X-Git-Url: http://git.chise.org/gitweb/?p=m17n%2Fm17n-lib-cs.git;a=blobdiff_plain;f=MSymbol.cs;h=c687a0ff80fab8986725d5b21327fb4c58e48153;hp=b92bcbf9859032dd7596cab8cec0913070e1c25a;hb=1d437136777ceed08a6a1835feb6864219ebef86;hpb=a583a94ebfd8bbd3fa3353afa204059e1c90c941 diff --git a/MSymbol.cs b/MSymbol.cs index b92bcbf..c687a0f 100644 --- a/MSymbol.cs +++ b/MSymbol.cs @@ -1,95 +1,108 @@ using System; -using System.Collections; +using System.Collections.Generic; using M17N.Core; namespace M17N.Core { - public class MSymbol + public sealed class MSymbol { - static private Hashtable pool = new Hashtable (); + private static Dictionary pool + = new Dictionary (); - private class MSymbolData - { - public string name; - public object value; - public MPlist plist; - - public MSymbolData (string name) - { - this.name = name; - } - } + public readonly string Name; + private MPlist Plist; + internal MProperty.Flags? flags; - private MSymbolData data; + 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 static MSymbol nil = new MSymbol ("nil"); - public static MSymbol t = new MSymbol ("t"); - public static MSymbol symbol = new MSymbol ("symbol"); - public static MSymbol mtext = new MSymbol ("mtext"); - public static MSymbol plist = new MSymbol ("plist"); - public static MSymbol integer = new MSymbol ("integer"); + private MSymbol (string name) + { + Name = name; + } - public MSymbol (string name) + public static implicit operator MSymbol (string name) { - if (! pool.ContainsKey (name)) - { - data = new MSymbolData (name); - pool.Add (name, data); - } - else - data = (MSymbolData) pool[name]; + return Of (name); } - public override string ToString () + public static explicit operator string (MSymbol sym) { - string str = ""; + return sym.Name; + } - foreach (char c in data.name) + public static MSymbol Of (string name) + { + lock (pool) { - if (c == '\\' || c == ' ' || c == '\'' || c == '\"' || c == ':') - str += "\\"; - str += c; + MSymbol sym; + + if (! pool.TryGetValue (name, out sym)) + { + sym = new MSymbol (name); + pool[name] = sym; + } + return sym; } - return str; } - public override bool Equals (object sym) + public static MSymbol PropertyKey (string name) { - if (sym == null) - return false; - return (this.data == ((MSymbol) sym).data); - } + MSymbol sym = MSymbol.Of (name); - public override int GetHashCode () - { - return (data.name.GetHashCode ()); + if (sym.flags == null) + sym.flags = MProperty.Flags.None;; + return sym; } - public static bool operator== (MSymbol sym1, MSymbol sym2) + public static MSymbol PropertyKey (string name, MProperty.Flags flags) { - return (sym1.data == sym2.data); + MSymbol sym = MSymbol.Of (name); + + 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; } - public static bool operator!= (MSymbol sym1, MSymbol sym2) + public override string ToString () { - return (sym1.data != sym2.data); + string str = ""; + + foreach (char c in Name) + { + if (c == '\\' || c == ' ' || c == '\'' || c == '\"' + || c == '(' || c == ')') + str += "\\"; + str += c; + } + return str; } public MPlist Find (MSymbol key) { - return (data.plist == null ? null : data.plist.Find (key)); + return (Plist == null ? null : Plist.Find (key)); } public object Get (MSymbol key) { - return (data.plist == null ? null : data.plist.Get (key)); + return (Plist == null ? null : Plist.Get (key)); } public object Put (MSymbol key, object val) { - if (data.plist == null) - data.plist = new MPlist (); - return data.plist.Put (key, val); + if (Plist == null) + Plist = new MPlist (); + return Plist.Put (key, val); } } }