Skip to content

Instantly share code, notes, and snippets.

@jonpryor
Forked from imphasing/gist:1107415
Created July 26, 2011 18:27
Show Gist options
  • Save jonpryor/1107454 to your computer and use it in GitHub Desktop.
Save jonpryor/1107454 to your computer and use it in GitHub Desktop.
/* output:
# test2: (* 10 10 )
# test: (+ 10 ((* 10 10 )))
# test2: (* 10 10 )
*/
namespace Schemin.AST
{
public interface IScheminType
{
}
}
namespace Schemin.AST
{
public class ScheminInteger : IScheminType
{
public int Value;
public ScheminInteger(int value)
{
this.Value = value;
}
public override string ToString()
{
return Value.ToString();
}
}
}
namespace Schemin.AST
{
using System;
using System.Text;
using Cadenza.Collections;
public class ScheminList : IScheminType
{
public CachedSequence<IScheminType> List;
public bool Empty;
public ScheminList()
{
this.Empty = true;
this.List = null;
}
public ScheminList(IScheminType head)
{
this.List = new CachedSequence<IScheminType>(head);
this.Empty = false;
}
public ScheminList(IScheminType head, ScheminList rest)
{
this.List = new CachedSequence<IScheminType>(head, rest.List);
this.Empty = false;
}
public ScheminList(CachedSequence<IScheminType> list)
{
this.List = list;
this.Empty = false;
}
public IScheminType Car()
{
if (this.List == null)
{
return new ScheminList();
}
return this.List.Head;
}
public ScheminList Cdr()
{
if (this.List == null)
{
return new ScheminList();
}
return new ScheminList(this.List.Tail);
}
public ScheminList Append(IScheminType type)
{
if (this.List == null)
{
this.List = new CachedSequence<IScheminType>(type);
this.Empty = false;
}
else
{
this.List = this.List.Append(type);
}
return this;
}
public override string ToString()
{
return ToStringInternal(this);
}
private string ToStringInternal(ScheminList list)
{
StringBuilder builder = new StringBuilder();
builder.Append ("(");
foreach (var type in list.List)
{
if (type == null)
{
// return String.Empty;
builder.Append("[!EMPTY!] ");
}
if (type.GetType() == typeof(ScheminList))
{
builder.Append("(");
builder.Append(ToStringInternal((ScheminList) type));
builder.Append(")");
}
else
{
string value = String.Empty;
if (type.GetType() == typeof(ScheminPrimitive))
{
var p = (ScheminPrimitive) type;
value = p.Name;
}
else if (type.GetType() == typeof(ScheminInteger))
{
ScheminInteger num = (ScheminInteger) type;
value = num.Value.ToString();
}
builder.Append(value + " ");
}
}
builder.Append (")");
return builder.ToString();
}
}
}
namespace Schemin.AST
{
using System;
public class ScheminPrimitive : IScheminType
{
public Func<ScheminList, IScheminType> Definition;
public string Name;
public ScheminPrimitive(string name)
{
this.Name = name;
}
public ScheminPrimitive(Func<ScheminList, IScheminType> definition, string name)
{
this.Definition = definition;
this.Name = name;
}
public IScheminType Evaluate(ScheminList args)
{
return Definition(args);
}
public override string ToString()
{
if (Name != null)
{
return "<Primitive:" + Name + ">";
}
else
{
return "<Primitive:unbound>";
}
}
}
// Test usage, demonstrating the issue I'm having:
class Test {
public static void Main ()
{
ScheminList test = new ScheminList();
ScheminList test2 = new ScheminList();
test2.Append(new ScheminPrimitive("*"));
test2.Append(new ScheminInteger(10));
test2.Append(new ScheminInteger(10));
Console.WriteLine ("# test2: {0}", test2);
test.Append(new ScheminPrimitive("+"));
test.Append(new ScheminInteger(10));
// head of test2 is lost in this append, giving me a list like: (+, 10, (10, 10)) instead of (+, 10, (*, 10, 10))
test.Append(test2);
Console.WriteLine ("# test: {0}", test);
Console.WriteLine ("# test2: {0}", test2);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment