using System; using System.Collections.Generic; using M17N.Core; namespace M17N.Core { public sealed class MSymbol { private static Dictionary pool = new Dictionary (); public readonly string Name; private MPlist Plist; internal MProperty.Flags? flags; 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"); private MSymbol (string name) { Name = name; } public static implicit operator MSymbol (string name) { return Of (name); } public static explicit operator string (MSymbol sym) { return sym.Name; } public static MSymbol Of (string name) { lock (pool) { MSymbol sym; if (! pool.TryGetValue (name, out sym)) { sym = new MSymbol (name); pool[name] = sym; } return sym; } } public static MSymbol PropertyKey (string name) { MSymbol sym = MSymbol.Of (name); if (sym.flags == null) sym.flags = MProperty.Flags.None;; return sym; } public static MSymbol PropertyKey (string name, MProperty.Flags flags) { 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 override string ToString () { 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 (Plist == null ? null : Plist.Find (key)); } public object Get (MSymbol key) { return (Plist == null ? null : Plist.Get (key)); } public object Put (MSymbol key, object val) { if (Plist == null) Plist = new MPlist (); return Plist.Put (key, val); } } }