using System; using M17N.Core; namespace M17N.Core { public class MPlist { private MSymbol key; private object val; private MPlist next; public MPlist () { key = null; val = null; next = null; } public bool tailp { get { return (object) key == null; } } public new string ToString () { string str = ""; for (MPlist p = this; ! p.tailp; p = p.next) { str += (p == this ? "(" : " ") + p.key.ToString () + ":"; if (p.val is MSymbol) str += ((MSymbol) p.val).ToString (); else if (p.val is MPlist) str += ((MPlist) p.val).ToString (); } return str + ")"; } public object get (MSymbol key) { if ((object) key == null) return null; for (MPlist p = this; ! p.tailp; p = p.next) if (p.key == key) return p.val; return null; } public object put (MSymbol key, object val) { MPlist p; for (p = this; ! p.tailp; p = p.next) if (p.key == key) { if (val != null) p.val = val; else p.pop (); return val; } if (val != null) { p.key = key; p.val = val; p.next = new MPlist (); } return val; } public object push (MSymbol key, object val) { MPlist p = new MPlist (); p.key = this.key; p.val = this.val; p.next = this.next; this.key = key; this.val = val; this.next = p; return val; } public object pop () { if (tailp) return null; object val = this.val; this.key = this.next.key; this.val = this.next.val; this.next = this.next.next; return val; } public object add (MSymbol key, object val) { MPlist p; for (p = this; ! p.tailp; p = p.next); if (val != null) { p.key = key; p.val = val; p.next = new MPlist (); } return val; } } public class MSymbol { internal class MSymbolData { public string name; public MPlist plist; public MSymbolData next; public MSymbolData (string name, MSymbolData next) { this.name = name; this.next = next; } } static internal class MSymbolPool { const int MSYMBOL_POOL_SIZE = 1024; static MSymbolData[] pool = new MSymbolData[MSYMBOL_POOL_SIZE]; static int[] used = new int[MSYMBOL_POOL_SIZE]; static public MSymbolData get_data (string name) { MSymbolData data; if (used[0] > 0) { data = pool[0]; for (int i = 0; i < used[0]; i++, data = data.next) if (data.name == name) return data; } pool[0] = data = new MSymbolData (name, pool[0]); used[0]++; return data; } } static public MSymbol nil = new MSymbol ("nil"); static public MSymbol t = new MSymbol ("t"); private MSymbolData data; public MSymbol (string name) { data = MSymbolPool.get_data (name); } public new string ToString () { return data.name; } public new bool Equals (object sym) { return ((object) this == sym); } public new int GetHashCode () { return 0; } public static bool operator== (MSymbol sym1, MSymbol sym2) { return ((object) sym1.data == (object) sym2.data); } public static bool operator!= (MSymbol sym1, MSymbol sym2) { return ((object) sym1.data != (object) sym2.data); } public object get (MSymbol key) { return (data.plist == null ? null : data.plist.get (key)); } public object put (MSymbol key, object val) { if (data.plist == null) data.plist = new MPlist (); return data.plist.put (key, val); } } }