Skip to content

Instantly share code, notes, and snippets.

@imphasing
Created July 26, 2011 18:14
Show Gist options
  • Save imphasing/1107415 to your computer and use it in GitHub Desktop.
Save imphasing/1107415 to your computer and use it in GitHub Desktop.
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();
foreach (var type in list.List)
{
if (type == null)
{
return String.Empty;
}
if (type.GetType() == typeof(ScheminList))
{
builder.Append("(");
builder.Append(ToStringInternal((ScheminList) type));
builder.Append(")");
}
else
{
string value = String.Empty;
if (type.GetType() == typeof(ScheminAtom))
{
ScheminAtom atom = (ScheminAtom) type;
value = atom.Name;
}
else if (type.GetType() == typeof(ScheminString))
{
ScheminString str = (ScheminString) type;
value = str.Value;
}
else if (type.GetType() == typeof(ScheminInteger))
{
ScheminInteger num = (ScheminInteger) type;
value = num.Value.ToString();
}
builder.Append(value + " ");
}
}
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:
ScheminList test = new ScheminList();
ScheminList test2 = new ScheminList();
test2.Append(new ScheminPrimitive("*"));
test2.Append(new ScheminInteger(10));
test2.Append(new ScheminInteger(10));
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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment