From: handa Date: Mon, 19 Oct 2009 14:05:53 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60e0de6dffdb5258ac0749a9588c51ec363edef5;p=m17n%2Fm17n-lib-cs.git *** empty log message *** --- diff --git a/MDatabase.cs b/MDatabase.cs index 6ac8291..01d5755 100644 --- a/MDatabase.cs +++ b/MDatabase.cs @@ -968,12 +968,6 @@ namespace M17N.Core private FileStream get_stream () { - if (loader != null - || (Info.Format != MSymbol.plist && Info.Format != Mxml)) - { - LastLoadStatus = LoadStatus.InvalidLoadMethod; - return null; - } if (DBStatus != MDBStatus.READY) { LastLoadStatus = LoadStatus.NotAvailable; @@ -989,8 +983,6 @@ namespace M17N.Core return stream; } - private NameTable name_table = new NameTable (); - public MPlist Load () { if (loader != null) @@ -1013,138 +1005,163 @@ namespace M17N.Core return plist; } - public void Load (XmlDocument doc) + public MPlist Load (MSymbol key, MSymbol stop) { - if (Info.Format == Mxml) - throw new Exception ("Not an XML database"); - try { - XmlTextReader reader - = new XmlTextReader (FileInfo.FullName, doc.NameTable); - doc.Load (reader); - LastLoaded = DateTime.Now; - } catch (Exception e) { - Console.WriteLine (e); - LastLoadStatus = LoadStatus.InvalidContents; - } - } + if (loader != null) + throw new Exception ("Partial load is impossible"); + if (Info.Format != MSymbol.plist) + throw new Exception ("Not a plist database"); - public object Load (MSymbol key, MSymbol stop) - { FileStream stream = get_stream (); - if (stream == null) return null; - if (Info.Format == Mxml) - { - XmlDocument doc = new XmlDocument (name_table); - XmlTextReader reader = new XmlTextReader (stream, name_table); - - reader.WhitespaceHandling = WhitespaceHandling.None; - try { - reader.Read (); - while (reader.NodeType != XmlNodeType.Element) - reader.Read (); - doc.LoadXml ("<" + reader.Name + ">"); - reader.Read (); - XmlNode node = doc.DocumentElement; - while (reader.NodeType == XmlNodeType.Element - ? reader.Name != stop.Name - : reader.NodeType != XmlNodeType.EndElement) - if (reader.NodeType == XmlNodeType.Element - && reader.Name == key.Name) - node = doc.DocumentElement.InsertAfter (doc.ReadNode (reader), - node); - } finally { - reader.Close (); - stream.Dispose (); - } - return doc; - } - - MPlist plist = null; try { - plist = new MPlist (stream, key, stop); + MPlist plist = new MPlist (stream, key, stop); LastLoaded = DateTime.Now; + return plist; } catch { LastLoadStatus = LoadStatus.InvalidContents; + return null; } finally { stream.Dispose (); } - return plist; } - public object Load (MSymbol stop) + public MPlist Load (MSymbol stop) { - FileStream stream = get_stream (); + if (loader != null) + throw new Exception ("Partial load is impossible"); + if (Info.Format != MSymbol.plist) + throw new Exception ("Not a plist database"); + FileStream stream = get_stream (); if (stream == null) return null; - if (Info.Format == Mxml) - { - XmlDocument doc = new XmlDocument (name_table); - XmlTextReader reader = new XmlTextReader (stream, name_table); - - reader.WhitespaceHandling = WhitespaceHandling.None; - try { - reader.Read (); - while (reader.NodeType != XmlNodeType.Element) - reader.Read (); - doc.LoadXml ("<" + reader.Name + ">"); - reader.Read (); - XmlNode node = null; - while (reader.NodeType == XmlNodeType.Element - ? reader.Name != stop.Name - : reader.NodeType != XmlNodeType.EndElement) - if (reader.NodeType == XmlNodeType.Element) - node = doc.DocumentElement.InsertAfter (doc.ReadNode (reader), - node); - } catch (Exception e) { - Console.WriteLine (e); - } finally { - reader.Close (); - stream.Dispose (); - } - return doc; - } - - MPlist plist = null; try { - plist = new MPlist (stream, stop); + MPlist plist = new MPlist (stream, stop); LastLoaded = DateTime.Now; + return plist; } catch (Exception e) { Console.WriteLine (e); LastLoadStatus = LoadStatus.InvalidContents; + return null; } finally { stream.Dispose (); } - return plist; } - public XmlNode Load (string id, params string[] nodes) + private XmlTextReader get_reader (XmlDocument doc) + { + XmlTextReader reader; + + try { + if (doc.NameTable != null) + reader = new XmlTextReader (FileInfo.FullName, doc.NameTable); + else + reader = new XmlTextReader (FileInfo.FullName); + reader.WhitespaceHandling = WhitespaceHandling.None; + } catch { + LastLoadStatus = LoadStatus.NotReadable; + reader = null; + } + return reader; + } + + public bool Load (XmlDocument doc) { - FileStream stream = get_stream (); - if (stream == null) - return null; if (Info.Format != Mxml) - throw new Exception ("Not an XML format"); + throw new Exception ("Not an XML database"); + XmlTextReader reader = get_reader (doc); + if (reader == null) + return false; + try { + doc.Load (reader); + LastLoaded = DateTime.Now; + return true; + } catch (Exception e) { + Console.WriteLine (e); + LastLoadStatus = LoadStatus.InvalidContents; + return false; + } finally { + reader.Close (); + } + } - XmlDocument doc = new XmlDocument (name_table); - XmlTextReader reader = new XmlTextReader (stream, name_table); - int len = nodes.Length; + public bool Load (XmlDocument doc, MSymbol key, MSymbol stop) + { + if (Info.Format != Mxml) + throw new Exception ("Not an XML database"); + XmlTextReader reader = get_reader (doc); + if (reader == null) + return false; + try { + reader.Read (); + while (reader.NodeType != XmlNodeType.Element) + reader.Read (); + doc.LoadXml ("<" + reader.Name + ">"); + reader.Read (); + XmlNode node = doc.DocumentElement; + while (reader.NodeType == XmlNodeType.Element + ? reader.Name != stop.Name + : reader.NodeType != XmlNodeType.EndElement) + if (reader.NodeType == XmlNodeType.Element + && reader.Name == key.Name) + node = doc.DocumentElement.InsertAfter (doc.ReadNode (reader), + node); + return true; + } catch (Exception e) { + Console.WriteLine (e); + return false; + } finally { + reader.Close (); + } + } - reader.WhitespaceHandling = WhitespaceHandling.None; - do { + public bool Load (XmlDocument doc, MSymbol stop) + { + if (Info.Format != Mxml) + throw new Exception ("Not an XML database"); + XmlTextReader reader = get_reader (doc); + if (reader == null) + return false; + try { reader.Read (); - } while (reader.NodeType != XmlNodeType.Element); + while (reader.NodeType != XmlNodeType.Element) + reader.Read (); + doc.LoadXml ("<" + reader.Name + ">"); + reader.Read (); + XmlNode node = doc.DocumentElement; + while (reader.NodeType == XmlNodeType.Element + ? reader.Name != stop.Name + : reader.NodeType != XmlNodeType.EndElement) + node = doc.DocumentElement.InsertAfter (doc.ReadNode (reader), node); + return true; + } catch (Exception e) { + Console.WriteLine (e); + return false; + } finally { + reader.Close (); + } + } - if (reader.Name != nodes[0]) + public XmlNode Load (XmlDocument doc, string id, params string[] nodes) + { + if (Info.Format != Mxml) + throw new Exception ("Not an XML database"); + XmlTextReader reader = get_reader (doc); + if (reader == null) return null; - - string ns = reader.GetAttribute ("xmlns"); - XmlNode top = doc.CreateNode (XmlNodeType.Element, nodes[0], ns); - XmlNode node = top; - try { + int len = nodes.Length; + do { + reader.Read (); + } while (reader.NodeType != XmlNodeType.Element); + if (reader.Name != nodes[0]) + return null; + + string ns = reader.GetAttribute ("xmlns"); + XmlNode top = doc.CreateNode (XmlNodeType.Element, nodes[0], ns); + XmlNode node = top; int i; for (i = 1; i + 1 < len; i++) @@ -1170,14 +1187,13 @@ namespace M17N.Core else reader.Read (); } - + return top; } catch (Exception e) { Console.WriteLine (e); + return null; } finally { reader.Close (); - stream.Dispose (); } - return top; } /// Return a list of currently available database diff --git a/MInputMethod.cs b/MInputMethod.cs index 60e48d0..c535112 100644 --- a/MInputMethod.cs +++ b/MInputMethod.cs @@ -41,6 +41,7 @@ namespace M17N.Input internal static MSymbol Mcandidates = "candidates"; private static MSymbol Mat_minus_zero = "@-0"; + private static Xex.Symbol Qxi_include = "xi:include"; private static Xex.Symbol Qmap = "map"; private static Xex.Symbol Qrule = "rule"; private static Xex.Symbol Qkeyseq = "keyseq"; @@ -591,10 +592,7 @@ namespace M17N.Input { char tag; - public Predefined (MSymbol name) : base (name) - { - tag = ((string) name)[1]; - } + public Predefined (char tag) : base ("@" + tag) { this.tag = tag; } public override int Position (Context ic) { @@ -671,15 +669,20 @@ namespace M17N.Input } } - static internal Dictionary predefined_markers; + static internal Dictionary predefineds; static Marker () - { - predefined_markers = new Dictionary (); - MSymbol[] symlist = new MSymbol[] {"@<", "@>", "@-", "@+", "@[", "@]" }; - foreach (MSymbol s in symlist) - predefined_markers[s] = new Predefined (s); - } + { + predefineds = new Dictionary (); + predefineds ["@<"] = predefineds["@first"] = new Predefined ('<'); + predefineds ["@>"] = predefineds["@last"] = new Predefined ('>'); + predefineds ["@-"] = predefineds["@previous"] = new Predefined ('-'); + predefineds ["@+"] = predefineds["@next"] = new Predefined ('+'); + predefineds ["@["] = predefineds["@previous-candidate-change"] + = new Predefined ('['); + predefineds ["@]"] = predefineds["@next-candidate-change"] + = new Predefined (']'); + } public static Marker Get (MSymbol name) { @@ -687,7 +690,7 @@ namespace M17N.Input if (str[0] == '@') { Predefined pred; - if (predefined_markers.TryGetValue (name, out pred)) + if (predefineds.TryGetValue (name, out pred)) return pred; if (str.Length == 1) throw new Exception ("Invalid marker name: " + name); @@ -1342,15 +1345,14 @@ namespace M17N.Input mdb = MDatabase.Find (tag); if (mdb == null) return false; - mdb.name_table = Xex.Symbol.Table; try { - MSymbol format = mdb.Format; - - if (format == MSymbol.plist) - load ((MPlist) mdb.Load (Mmap), false); + if (mdb.Format == MSymbol.plist) + load (mdb.Load (Mmap), false); else { - XmlDocument doc = (XmlDocument) mdb.Load (Mmap_list); + XmlDocument doc = new XmlDocument (Xex.Symbol.NameTable); + if (! mdb.Load (doc, Mmap_list)) + throw new Exception ("Load error" + mdb.tag); load (doc.DocumentElement, false); } } catch (Exception e) { @@ -1367,13 +1369,16 @@ namespace M17N.Input mdb = MDatabase.Find (tag); if (mdb == null) return false; - mdb.name_table = Xex.Symbol.Table; try { - object obj = mdb.Load (); - if (obj is MPlist) - load ((MPlist) obj, true); + if (mdb.Format == MSymbol.plist) + load (mdb.Load (), true); else - load ((XmlDocument) obj, true); + { + XmlDocument doc = new XmlDocument (Xex.Symbol.NameTable); + if (! mdb.Load (doc)) + throw new Exception ("Load error" + mdb.tag); + load (doc.DocumentElement, true); + } } catch (Exception e) { Console.WriteLine (e); load_status = LoadStatus.Error; @@ -1457,6 +1462,7 @@ namespace M17N.Input node = node.NextSibling; for (node = node.FirstChild; node != null; node = node.NextSibling) { + Console.WriteLine (this.tag + node.Name); if (node.NodeType != XmlNodeType.Element) continue; if (! skip_header) @@ -1470,7 +1476,7 @@ namespace M17N.Input else if (node.Name == "command-list") parse_commands (node); } - else if (full) + if (full) { if (node.Name == "module-list") parse_plugins (node); @@ -1520,110 +1526,12 @@ namespace M17N.Input return node.InnerText; } - private void new_variable (Xex.Symbol name, string desc, int val, - MPlist pl, Xex.Variable vari) - { - int[] range; - - if (pl.IsEmpty) - range = null; - else - { - int nrange = pl.Count; - range = new int[nrange * 2]; - for (int i = 0; i < nrange; i++) - { - if (pl.IsPlist) - { - MPlist p = pl.Plist; - - if (! p.IsInteger || ! p.next.IsInteger) - throw new Exception ("Invalid range: " + p); - range[i * 2] = p.Integer; - range[i * 2 + 1] = p.next.Integer; - } - else if (pl.IsInteger) - range[i * 2] = range[i * 2 + 1] = pl.Integer; - else - throw new Exception ("Invalid range: " + pl); - } - } - if (vari == null) - domain.Defvar (new Xex.Variable.Int (domain, name, desc, val, range)); - else - { - Xex.Term term = new Xex.Term (val); - vari.Value = term; - vari.DefaultValue = term; - vari.Range = range; - } - } - - private void new_variable (Xex.Symbol name, string desc, MText val, - MPlist pl, Xex.Variable vari) - { - string[] range; - - if (pl.IsEmpty) - range = null; - else - { - range = new string[pl.Count * 2]; - for (int i = 0; i < range.Length; i++) - { - if (pl.IsMText) - range[i] = (string) pl.Text; - else - throw new Exception ("Invalid range: " + pl); - } - } - if (vari == null) - domain.Defvar (new Xex.Variable.Str (domain, name, desc, (string) val, range)); - else - { - Xex.Term term = new Xex.Term ((string) val); - vari.Value = term; - vari.DefaultValue = term; - vari.Range = range; - } - } - - private void new_variable (Xex.Symbol name, string desc, MSymbol val, - MPlist pl, Xex.Variable vari) - { - Xex.Symbol[] range; - Xex.Symbol sym = val.Name; - - if (pl.IsEmpty) - range = null; - else - { - range = new Xex.Symbol[pl.Count * 2]; - for (int i = 0; i < range.Length; i++) - { - if (pl.IsSymbol) - range[i] = pl.Symbol.Name; - else - throw new Exception ("Invalid range: " + pl); - } - } - if (vari == null) - domain.Defvar (new Xex.Variable.Sym (domain, name, desc, sym, range)); - else - { - Xex.Term term = new Xex.Term (sym); - vari.Value = term; - vari.DefaultValue = term; - vari.Range = range; - } - } - private Xex.Variable get_global_var (Xex.Symbol name) { if (im_global == null || this != im_global) { - tag = new MDatabase.Tag (Minput_method, MSymbol.t, MSymbol.nil, - "global"); + MDatabase.Tag tag = + new MDatabase.Tag (Minput_method, MSymbol.t, MSymbol.nil, "global"); im_global = im_table[tag]; if (! im_global.Open ()) throw new Exception ("Failed to load global"); @@ -1645,22 +1553,82 @@ namespace M17N.Input var_names[i] = name; p = p.next; string desc = (string) parse_description (p); + if (desc != null) + p = p.next; Xex.Variable vari = get_global_var (name); if (vari != null) domain.Defvar (vari); - if (desc != null) - p = p.next; - if (! p.IsEmpty) + if (p.IsInteger) + { + int n = p.Integer; + int[] range = null; + + p = p.Next; + if (! p.IsEmpty) + { + int nrange = p.Count; + range = new int[nrange * 2]; + for (int j = 0; j < nrange; j++) + { + if (p.IsPlist) + { + MPlist p0 = p.Plist; + + if (! p0.IsInteger || ! p0.next.IsInteger) + throw new Exception ("Invalid range: " + p0); + range[j * 2] = p0.Integer; + range[j * 2 + 1] = p0.next.Integer; + } + else if (p.IsInteger) + range[j * 2] = range[j * 2 + 1] = p.Integer; + else + throw new Exception ("Invalid range: " + p); + } + } + domain.DefvarInt (name, n, desc, range); + } + else if (p.IsMText) { - if (p.IsInteger) - new_variable (name, desc, p.Integer, p.next, vari); - else if (p.IsMText) - new_variable (name, desc, p.Text, p.next, vari); - else if (p.IsSymbol) - new_variable (name, desc, p.Symbol, p.next, vari); + string str = (string) p.Text; + string[] range = null; + + p = p.next; + if (! p.IsEmpty) + { + range = new string[p.Count]; + for (int j = 0; j < range.Length; j++) + { + if (p.IsMText) + range[j] = (string) p.Text; + else + throw new Exception ("Invalid range: " + p); + } + } + domain.DefvarStr (name, str, desc, range); + } + else if (p.IsSymbol) + { + Xex.Symbol sym = p.Symbol.Name; + Xex.Symbol[] range; + + p = p.next; + if (p.IsEmpty) + range = null; else - throw new Exception ("Invalid variable type: " + p.val); + { + range = new Xex.Symbol[p.Count]; + for (int j = 0; j < range.Length; j++) + { + if (p.IsSymbol) + range[j] = p.Symbol.Name; + else + throw new Exception ("Invalid range: " + p); + } + } + domain.DefvarSym (name, sym, desc, range); } + else if (! p.IsEmpty) + throw new Exception ("Invalid variable type: " + p.val); } } @@ -1735,35 +1703,71 @@ namespace M17N.Input } } + private void parse_include (XmlNode node) + { + XmlNode n; + MSymbol language, name, subname; + MSymbol part, section; + node = node.FirstChild; + n = node.FirstChild; + language = n.InnerText; + n = n.NextSibling; + name = n.InnerText; + n = n.NextSibling; + if (n != null) + subname = n.InnerText; + else + subname = MSymbol.nil; + node = node.NextSibling; + part = node.InnerText; + node = node.NextSibling; + if (node != null) + section = node.InnerText; + else + section = MSymbol.nil; + include_part (language, name, subname, part, section); + } + private void parse_macros (XmlNode node) { for (XmlNode nn = node.FirstChild; nn != null; nn = nn.NextSibling) if (nn.NodeType == XmlNodeType.Element) - domain.Defun (nn, true); + { + if (nn.Name == Xex.Qdefun) + domain.Defun (nn, true); + else if (nn.Name == Qxi_include) + parse_include (nn); + } for (XmlNode nn = node.FirstChild; nn != null; nn = nn.NextSibling) - if (nn.NodeType == XmlNodeType.Element) + if (nn.NodeType == XmlNodeType.Element + && nn.Name == Xex.Qdefun) domain.Defun (nn, false); } private void parse_maps (XmlNode node) { for (node = node.FirstChild; node != null; node = node.NextSibling) - if (node.Name == Qmap) - { - MSymbol name = node.Attributes[0].Value; - Map map = new Map (name); - maps[name] = map; - for (XmlNode nd = node.FirstChild; nd != null; nd = nd.NextSibling) - if (nd.Name == Qrule) - { - XmlNode n = nd.FirstChild; - if (n.Name != Qkeyseq) - continue; - KeySeq keyseq = (KeySeq) KeySeq.parser (domain, n); - Xex.Term[] actions = Xex.ParseTerms (domain, n.NextSibling); - map.entries.Add (new Map.Entry (domain, keyseq, actions)); - } - } + { + if (node.Name == Qmap) + { + MSymbol name = node.Attributes[0].Value; + Map map = new Map (name); + maps[name] = map; + for (XmlNode nd = node.FirstChild; nd != null; + nd = nd.NextSibling) + if (nd.Name == Qrule) + { + XmlNode n = nd.FirstChild; + if (n.Name != Qkeyseq) + continue; + KeySeq keyseq = (KeySeq) KeySeq.parser (domain, n); + Xex.Term[] actions = Xex.ParseTerms (domain, n.NextSibling); + map.entries.Add (new Map.Entry (domain, keyseq, actions)); + } + } + else if (node.Name == Qxi_include) + parse_include (node); + } } private void parse_states (MPlist plist) @@ -1781,58 +1785,40 @@ namespace M17N.Input private void parse_states (XmlNode node) { for (node = node.FirstChild; node != null; node = node.NextSibling) - if (node.Name == Qstate) - { - State state = new State (this, node); - states[state.name] = state; - if (initial_state == null) - initial_state = state; - } + { + if (node.Name == Qstate) + { + State state = new State (this, node); + states[state.name] = state; + if (initial_state == null) + initial_state = state; + } + else if (node.Name == Qxi_include) + parse_include (node); + } } - private void parse_include (MPlist plist) + private void include_part (MSymbol language, MSymbol name, MSymbol subname, + MSymbol part, MSymbol section) { - if (! plist.IsPlist) - return; - MPlist p = plist.Plist; - MSymbol language, name, subname; - language = p.Symbol; - p = p.next; - if (! p.IsSymbol) - name = subname = MSymbol.nil; - else - { - name = p.Symbol; - p = p.next; - if (! p.IsSymbol) - subname = MSymbol.nil; - else - subname = p.Symbol; - } + Console.WriteLine ("including {0}:{1}:{2}:{3}:{4}", + language, name, subname, part, section); MInputMethod im = MInputMethod.Find (language, name, subname); if (im == null) return; if (! im.Open ()) return; - plist = plist.next; - if (! plist.IsSymbol) - return; - MSymbol target_type = plist.Symbol; - plist = plist.next; - MSymbol target_name = MSymbol.nil; - if (plist.IsSymbol) - target_name = plist.Symbol; - if (target_type == Mmacro) + if (part == Mmacro) { - if (target_name == MSymbol.nil) + if (section == MSymbol.nil) im.domain.CopyFunc (domain); else - im.domain.CopyFunc (domain, (Xex.Symbol) target_name.Name); + im.domain.CopyFunc (domain, (Xex.Symbol) section.Name); } - else if (target_type == Mmap) + else if (part == Mmap) { - if (target_name == MSymbol.nil) + if (section == MSymbol.nil) { foreach (KeyValuePair kv in im.maps) maps[kv.Key] = kv.Value; @@ -1840,20 +1826,20 @@ namespace M17N.Input else { Map map; - if (im.maps.TryGetValue (target_name, out map)) - maps[target_name] = map; + if (im.maps.TryGetValue (section, out map)) + maps[section] = map; } } - else if (target_type == Mstate) + else if (part == Mstate) { - if (target_name == MSymbol.nil) + if (section == MSymbol.nil) { foreach (KeyValuePair kv in im.states) states[kv.Key] = kv.Value; } else { - Xex.Symbol state_name = target_name.Name; + Xex.Symbol state_name = section.Name; State state; if (im.states.TryGetValue (state_name, out state)) states[state_name] = state; @@ -1861,6 +1847,36 @@ namespace M17N.Input } } + private void parse_include (MPlist plist) + { + if (! plist.IsPlist) + return; + MPlist p = plist.Plist; + MSymbol language, name, subname; + language = p.Symbol; + p = p.next; + if (! p.IsSymbol) + name = subname = MSymbol.nil; + else + { + name = p.Symbol; + p = p.next; + if (! p.IsSymbol) + subname = MSymbol.nil; + else + subname = p.Symbol; + } + plist = plist.next; + if (! plist.IsSymbol) + return; + MSymbol part = plist.Symbol; + plist = plist.next; + MSymbol section = MSymbol.nil; + if (plist.IsSymbol) + section = plist.Symbol; + include_part (language, name, subname, part, section); + } + private Xex.Term parse_cond (MPlist plist) { Xex.Term[] args = new Xex.Term[plist.Count]; @@ -2040,7 +2056,6 @@ namespace M17N.Input if (pl.IsPlist) { MPlist p = pl.Plist; - if (! p.IsSymbol) continue; domain.Defun ((Xex.Symbol) p.Symbol.Name, null, null, true); diff --git a/XmlExpr.cs b/XmlExpr.cs index bcd05c9..23ffd80 100644 --- a/XmlExpr.cs +++ b/XmlExpr.cs @@ -14,22 +14,16 @@ namespace System.Xml.Expression { private static NameTable nt = new NameTable (); - internal string name; + private string name; - public Symbol (string str) - { - name = nt.Add (str); - } + public Symbol (string str) { name = nt.Add (str); } public static implicit operator Symbol (string str) { return new Symbol (str); } - public static implicit operator string (Symbol name) - { - return name.name; - } + public static implicit operator string (Symbol sym) { return sym.name; } public static bool operator== (Symbol n1, Symbol n2) { @@ -76,7 +70,7 @@ namespace System.Xml.Expression return name.GetHashCode (); } - public static NameTable Table { get { return nt; } } + public static NameTable NameTable { get { return nt; } } public override string ToString () { return name; } } @@ -90,15 +84,15 @@ namespace System.Xml.Expression private static Symbol Qsymbol = "symbol"; private static Symbol Qlist = "list"; - private static Symbol Qdefun = "defun"; - private static Symbol Qdefmacro = "defmacro"; + public static Symbol Qdefun = "defun"; + public static Symbol Qdefmacro = "defmacro"; private static Symbol Qfname = "fname"; private static Symbol Qargs = "args"; private static Symbol Qfixed = "fixed"; private static Symbol Qoptional = "optional"; private static Symbol Qrest = "rest"; - private static Symbol Qdefvar = "defvar"; + public static Symbol Qdefvar = "defvar"; private static Symbol Qvname = "vname"; private static Symbol Qdescription = "description"; private static Symbol Qrange = "range"; @@ -377,30 +371,26 @@ namespace System.Xml.Expression { public Domain domain; public readonly Symbol name; - public string desc; - protected Term default_val; protected Term val; - object range; public Variable (Domain domain, Symbol name, Term val) { this.domain = domain; this.name = name; this.val = val; - default_val = Zero; } public virtual bool ValueP (Term val) { return true; } - public Variable Clone (Domain domain) + public virtual Variable Clone (Domain domain) { - Variable v = new Variable (domain, name, val); - v.desc = desc; - v.default_val = default_val; - v.range = range; - return v; + return new Variable (domain, name, val); } + public virtual void Reset () { val = Zero; } + + public virtual string Description { get { return null; } } + public Term Value { get { return val; } @@ -424,193 +414,174 @@ namespace System.Xml.Expression return val; } - public Term DefaultValue - { - get { return default_val; } - set { - if (! ValueP (value)) - throw new Exception ("Invalid value: " + value); - default_val = value; - } - } + public override string ToString () { return name + "(" + val + ")"; } - public virtual object Range + public abstract class Typed : Variable { - get { return range; } - set { range = value; } - } + protected string desc; + private Term default_val; - public override string ToString () { return name + "(" + val + ")"; } + protected Typed (Domain domain, Symbol name, Term val, string desc) + : base (domain, name, val) + { + this.desc = desc; + default_val = val; + } + + public override void Reset () { val = default_val; } + + public override string Description { get { return desc; } } + } - public class Int : Variable + public class Int : Typed { - public int[] range; + private int[] range; - private static bool SubsetP (int[] r1, int[] r2) + public bool IsSubrange (int[] r) { - if (r2 == null) + if (range == null) return true; - for (int i = 0; i < r1.Length; i += 2) + for (int i = 0; i < r.Length; i += 2) { int j; - for (j = 0; j < r2.Length; j += 2) - if (r2[j] <= r1[i] && r2[j + 1] >= r1[i + 1]) + for (j = 0; j < range.Length; j += 2) + if (range[j] <= r[i] && range[j + 1] >= r[i + 1]) break; - if (j >= r2.Length) + if (j >= range.Length) return false; } return true; } - private static bool SubsetP (int val, int[] r) + public Int (Domain domain, Symbol name, int n, string desc, int[] range) + : base (domain, name, new Term (n), desc) { - if (r == null) - return true; - for (int i = 0; i < r.Length; i += 2) - if (r[i] <= val && r[i + 1] >= val) - return true; - return false; - } - - public Int (Domain domain, Symbol name, string description, - int value, int[] range) - : base (domain, name, new Term (value)) - { - if (! SubsetP (value, range)) - throw new Exception ("Invalid value: " + value); - desc = description; - default_val = val; + if (range != null && range.Length % 2 == 1) + throw new Exception ("Invalid range length: " + range.Length); this.range = range; + if (! ValueP (val)) + throw new Exception ("Invalid integer value: " + val); } public override bool ValueP (Term term) { if (! term.IsInt) return false; - return SubsetP (term.Intval, range); + if (range == null) + return true; + int n = term.Intval; + for (int i = 0; i < range.Length; i += 2) + if (range[i] <= n && range[i + 1] >= n) + return true; + return false; } - public override object Range { - get { return range; } - set { - int[] r = (int[]) value; - if (! SubsetP (r, range) - || ! SubsetP (val.Intval, r) - || ! SubsetP (default_val.Intval, r)) - throw new Exception ("Invalid range"); - range = r; - } + public override Variable Clone (Domain domain) + { + return new Int (domain, name, val.Intval, desc, range); } + + public int[] Range { get { return range; } set { range = value; } } } - public class Str : Variable + public class Str : Typed { - public string[] range; + private string[] range; - private static bool SubsetP (string[] r1, string[] r2) + public bool IsSubrange (string[] r) { - if (r2 == null) + if (range == null) return true; - foreach (string s in r1) - if (! SubsetP (s, r2)) - return false; + for (int i = 0; i < r.Length; i++) + { + int j; + for (j = 0; j < range.Length; j++) + if (range[j] == r[i]) + break; + if (j >= range.Length) + return false; + } return true; } - private static bool SubsetP (string str, string[] r) - { - if (r == null) - return true; - foreach (string s in r) - if (str == s) - return true; - return false; - } - - public Str (Domain domain, Symbol name, string description, - string value, string[] range) - : base (domain, name, new Term (value)) + public Str (Domain domain, Symbol name, string str, string desc, + string[] range) + : base (domain, name, new Term (str), desc) { - if (! SubsetP (value, range)) - throw new Exception ("Invalid value: " + value); - desc = description; - default_val = val; this.range = range; + if (! ValueP (val)) + throw new Exception ("Invalid string value: " + val); } public override bool ValueP (Term term) { - if (! (term.objval is string)) + if (! term.IsStr) return false; - return SubsetP (term.Strval, range); + if (range == null) + return true; + string str = term.Strval; + foreach (string s in range) + if (str == s) + return true; + return false; } - public override object Range { - get { return range; } - set { - string[] r = (string[]) value; - if (! SubsetP (r, range) - || ! SubsetP (val.Strval, r) - || ! SubsetP (default_val.Strval, r)) - throw new Exception ("Invalid range"); - range = r; - } + public override Variable Clone (Domain domain) + { + return new Str (domain, name, val.Strval, desc, range); } + + public string[] Range { get { return range; } set { range = value; } } } - public class Sym : Variable + public class Sym : Typed { public Symbol[] range; - private static bool SubsetP (Symbol[] r1, Symbol[] r2) + public bool IsSubrange (Symbol[] r) { - if (r2 == null) + if (range == null) return true; - foreach (Symbol n in r1) - if (! SubsetP (n, r2)) - return false; + for (int i = 0; i < r.Length; i++) + { + int j; + for (j = 0; j < range.Length; j++) + if (range[j] == r[i]) + break; + if (j >= range.Length) + return false; + } return true; } - private static bool SubsetP (Symbol name, Symbol[] r) - { - if (r == null) - return true; - foreach (Symbol n in r) - if (name == n) - return true; - return false; - } - - public Sym (Domain domain, Symbol name, string description, - Symbol value, Symbol[] range) - : base (domain, name, new Term (value)) + public Sym (Domain domain, Symbol name, Symbol sym, string desc, + Symbol[] range) + : base (domain, name, new Term (sym), desc) { - if (! SubsetP (value, range)) - throw new Exception ("Invalid value: " + value); - desc = description; - default_val = val; this.range = range; + if (! ValueP (val)) + throw new Exception ("Invalid symbol value: " + val); } public override bool ValueP (Term term) { - if (! (term.objval is Symbol)) + if (! term.IsSymbol) return false; - return SubsetP (term.Symval, range); + if (range == null) + return true; + Symbol name = term.Symval; + foreach (Symbol n in range) + if (name == n) + return true; + return false; } - public override object Range { - get { return range; } - set { - Symbol[] r = (Symbol[]) value; - if (! SubsetP (r, range) - || ! SubsetP (val.Symval, r) - || ! SubsetP (default_val.Symval, r)) - throw new Exception ("Invalid range"); - range = r; - } + public override Variable Clone (Domain domain) + { + return new Sym (domain, name, val.Symval, desc, range); } + + public Symbol[] Range { get { return range; } set { range = value; } } } } @@ -669,7 +640,7 @@ namespace System.Xml.Expression { private object val; - public CatchTag (Symbol name) { val = name.name; } + public CatchTag (Symbol sym) { val = (string) sym; } private CatchTag (int i) { val = i; } public static CatchTag Return = new CatchTag (0); @@ -894,43 +865,30 @@ namespace System.Xml.Expression if (type == Qinteger) { - int intval = parse_integer (val); + int n = parse_integer (val); int[] range = null; if (range_list != null) { range = new int[nranges * 2]; for (int i = 0; i < nranges; i++) { - XmlNode n = range_list[i]; - if (n.Name == Qrange) + XmlNode nd = range_list[i]; + if (nd.Name == Qrange) { range[i * 2] - = parse_integer (n.FirstChild.InnerText); + = parse_integer (nd.FirstChild.InnerText); range[i * 2 + 1] - = parse_integer (n.LastChild.InnerText); + = parse_integer (nd.LastChild.InnerText); } else { range[i * 2] = range[i * 2 + 1] - = parse_integer (n.FirstChild.InnerText); + = parse_integer (nd.FirstChild.InnerText); } } } - - if (variables.TryGetValue (name, out vari)) - { - if (! (vari is Variable.Int)) - throw new Exception ("Inalid value"); - vari = (Variable) vari.Clone (this); - Term v = new Term (intval); - vari.Value = v; - vari.DefaultValue = v; - if (range != null) - vari.Range = range; - } - else - vari = new Variable.Int (this, name, desc, intval, range); + vari = DefvarInt (name, n, desc, range); } else if (type == Qstring) { @@ -941,20 +899,7 @@ namespace System.Xml.Expression for (int i = 0; i < nranges; i++) range[i] = range_list[i].FirstChild.InnerText; } - - if (variables.TryGetValue (name, out vari)) - { - if (! (vari is Variable.Str)) - throw new Exception ("Invalid value"); - vari = (Variable) vari.Clone (this); - Term v = new Term (val); - vari.Value = v; - vari.DefaultValue = v; - if (range != null) - vari.Range = range; - } - else - vari = new Variable.Str (this, name, desc, val, range); + vari = DefvarStr (name, val, desc, range); } else if (type == Qsymbol) { @@ -965,20 +910,7 @@ namespace System.Xml.Expression for (int i = 0; i < nranges; i++) range[i] = range_list[i].FirstChild.InnerText; } - - if (variables.TryGetValue (name, out vari)) - { - if (! (vari is Variable.Sym)) - throw new Exception ("Invalid value"); - vari = (Variable) vari.Clone (this); - Term v = new Term (val); - vari.Value = v; - vari.DefaultValue = v; - if (range != null) - vari.Range = range; - } - else - vari = new Variable.Sym (this, name, desc, val, range); + vari = DefvarSym (name, (Symbol) val, desc, range); } else throw new Exception ("Unknown type: " + type); @@ -986,11 +918,12 @@ namespace System.Xml.Expression else { if (variables.TryGetValue (name, out vari)) - vari = (Variable) vari.Clone (this); + vari = vari.Clone (this); else vari = new Variable (this, name, Zero); + variables[name] = vari; } - variables[name] = vari; + Console.WriteLine (vari); return vari; } @@ -1008,6 +941,71 @@ namespace System.Xml.Expression return vari; } + public Variable DefvarInt (Symbol name, int n, string desc, int[] range) + { + Variable vari; + + if (variables.TryGetValue (name, out vari)) + { + Variable.Int intvari = vari as Variable.Int; + if (intvari == null) + throw new Exception ("Variable type mismatch"); + if (range == null) + range = intvari.Range; + else if (! intvari.IsSubrange (range)) + throw new Exception ("Variable range mismatch"); + if (desc == null) + desc = vari.Description; + } + vari = new Variable.Int (this, name, n, desc, range); + variables[name] = vari; + return vari; + } + + public Variable DefvarStr (Symbol name, string str, string desc, + string[] range) + { + Variable vari; + + if (variables.TryGetValue (name, out vari)) + { + Variable.Str strvari = vari as Variable.Str; + if (strvari == null) + throw new Exception ("Variable type mismatch"); + if (range == null) + range = strvari.Range; + else if (! strvari.IsSubrange (range)) + throw new Exception ("Variable range mismatch"); + if (desc == null) + desc = vari.Description; + } + vari = new Variable.Str (this, name, str, desc, range); + variables[name] = vari; + return vari; + } + + public Variable DefvarSym (Symbol name, Symbol sym, string desc, + Symbol[] range) + { + Variable vari; + + if (variables.TryGetValue (name, out vari)) + { + Variable.Sym symvari = vari as Variable.Sym; + if (symvari == null) + throw new Exception ("Variable type mismatch"); + if (range == null) + range = symvari.Range; + else if (! symvari.IsSubrange (range)) + throw new Exception ("Variable range mismatch"); + if (desc == null) + desc = vari.Description; + } + vari = new Variable.Sym (this, name, sym, desc, range); + variables[name] = vari; + return vari; + } + internal Function GetFunc (Symbol name) { Function func; @@ -2056,10 +2054,10 @@ namespace System.Xml.Expression public Xexpression (Domain domain, string url) { - XmlDocument doc = new XmlDocument (Symbol.Table); + XmlDocument doc = new XmlDocument (Symbol.NameTable); XmlNode node; - using (XmlTextReader reader = new XmlTextReader (url, Symbol.Table)) + using (XmlTextReader reader = new XmlTextReader (url, doc.NameTable)) { do { reader.Read (); diff --git a/input.cs b/input.cs index 735febc..e888cca 100644 --- a/input.cs +++ b/input.cs @@ -15,8 +15,7 @@ public class Test //M17n.debug = true; Xex.debug_level = 10; MDatabase.ApplicationDir = "/usr/local/share/m17n-xml"; - MInputMethod im = MInputMethod.Find ("vi", "telex"); - Console.WriteLine (im); + MInputMethod im = MInputMethod.Find ("zh", "py-b5"); MInputMethod.Context ic = new MInputMethod.Context (im); MText str = args[0]; for (int i = 0; i < str.Length; i++)