using System;
-using M17N;
+using System.Collections.Generic;
+using M17N.Core;
-namespace M17N
+namespace M17N.Core
{
- public class MPlist
+ public sealed class MSymbol
{
- private MSymbol key;
- private object val;
- private MPlist next;
+ private static Dictionary<string, MSymbol> pool
+ = new Dictionary<string, MSymbol> ();
- public MPlist ()
- {
- key = null;
- val = null;
- next = null;
- }
+ public readonly string Name;
+ private MPlist Plist;
+ internal MProperty.Flags? flags;
- public bool tailp { get { return (object) key == null; } }
+ public static MSymbol nil = MSymbol.Of ("nil");
+ public static MSymbol t = MSymbol.Of ("t");
+ public static MSymbol symbol = MSymbol.Of ("symbol");
+ public static MSymbol mtext = MSymbol.Of ("mtext");
+ public static MSymbol mstring = MSymbol.Of ("string");
+ public static MSymbol plist = MSymbol.Of ("plist");
+ public static MSymbol integer = MSymbol.Of ("integer");
- public new string ToString ()
+ private MSymbol (string name)
{
- 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;
+ Name = name;
}
- public object push (MSymbol key, object val)
+ public static implicit operator MSymbol (string name)
{
- 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;
+ return Of (name);
}
- public object pop ()
+ public static explicit operator string (MSymbol sym)
{
- 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;
+ return sym.Name;
}
- public object add (MSymbol key, object val)
+ public static MSymbol Of (string name)
{
- MPlist p;
-
- for (p = this; ! p.tailp; p = p.next);
- if (val != null)
+ lock (pool)
{
- p.key = key;
- p.val = val;
- p.next = new MPlist ();
+ MSymbol sym;
+
+ if (! pool.TryGetValue (name, out sym))
+ {
+ sym = new MSymbol (name);
+ pool[name] = sym;
+ }
+ return sym;
}
- return val;
}
- }
- public class MSymbol
- {
- internal class MSymbolData
+ public static MSymbol PropertyKey (string name)
{
- public string name;
- public MPlist plist;
- public MSymbolData next;
+ MSymbol sym = MSymbol.Of (name);
- public MSymbolData (string name, MSymbolData next)
- {
- this.name = name;
- this.next = next;
- }
+ if (sym.flags == null)
+ sym.flags = MProperty.Flags.None;;
+ return sym;
}
- static internal class MSymbolPool
+ public static MSymbol PropertyKey (string name, MProperty.Flags flags)
{
- 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;
+ MSymbol sym = MSymbol.Of (name);
- 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;
- }
+ if ((flags & MProperty.Flags.BothSticky) != MProperty.Flags.None
+ && (flags & MProperty.Flags.Sensitive) != MProperty.Flags.None)
+ throw new Exception ("A property can't be both sticky and sensitve");
+ if (sym.flags == null)
+ sym.flags = flags;
+ else if (sym.flags != flags)
+ throw new Exception ("Flags of PropertyKey mismatch");
+ return sym;
}
- 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)
+ public override string ToString ()
{
- return ((object) sym1.data == (object) sym2.data);
- }
+ string str = "";
- public static bool operator!= (MSymbol sym1, MSymbol sym2)
- {
- return ((object) sym1.data != (object) sym2.data);
+ foreach (char c in Name)
+ {
+ if (c == '\\' || c == ' ' || c == '\'' || c == '\"'
+ || c == '(' || c == ')')
+ str += "\\";
+ str += c;
+ }
+ return str;
}
- public object get (MSymbol key)
+ public MPlist Find (MSymbol key)
{
- return (data.plist == null ? null : data.plist.get (key));
+ return (Plist == null ? null : Plist.Find (key));
}
- public object put (MSymbol key, object val)
+ public object Get (MSymbol key)
{
- if (data.plist == null)
- data.plist = new MPlist ();
- return data.plist.put (key, val);
+ return (Plist == null ? null : Plist.Get (key));
}
- }
- public class MTextProperty
- {
- }
-
- public enum MTextFormat
- {
- MTEXT_FORMAT_US_ASCII,
- MTEXT_FORMAT_UTF_8,
- MTEXT_FORMAT_UTF_16BE,
- MTEXT_FORMAT_UTF_16LE,
- MTEXT_FORMAT_UTF_32BE,
- MTEXT_FORMAT_UTF_32LE,
- }
-
- public class MText
- {
- private class MTextPlist : MPlist
+ public object Put (MSymbol key, object val)
{
- public class MInterval
- {
- public MPlist stack;
- public int nprops;
- public int start, end;
- public MInterval prev, next;
- }
-
- MInterval head, tail;
-
- public MTextPlist (MText mt)
- {
- head = tail = new MInterval ();
- head.start = 0;
- head.end = mt.nchars;
- }
- }
-
- private string str;
- private int nchars;
- private int nunits;
- private int cache_pos;
- private int cache_idx;
- private MTextPlist plist;
-
- public MText (byte str, MTextFormat format)
- {
-
- }
- }
-
-
- public class Test
- {
- public static void Main()
- {
- MSymbol sym1, sym2;
-
- sym1 = new MSymbol ("abc");
- Console.WriteLine (sym1.ToString ());
- sym2 = new MSymbol ("abc");
- Console.WriteLine (sym2.ToString ());
- Console.WriteLine (sym1 == sym2 ? "OK" : "NO");
- sym1.put (MSymbol.nil, MSymbol.t);
-
- MPlist p = new MPlist ();
-
- p.put (MSymbol.t, sym1);
- p.push (MSymbol.t, sym2);
-
- MPlist pp = new MPlist ();
- pp.put (MSymbol.t, p);
- Console.WriteLine (pp.ToString ());
- Console.WriteLine (p.get (MSymbol.t));
+ if (Plist == null)
+ Plist = new MPlist ();
+ return Plist.Put (key, val);
}
}
}