From: handa Date: Mon, 28 Sep 2009 00:11:52 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=995e782899740644d2237ce1339925fe3f52a0f3;p=m17n%2Fm17n-lib-cs.git *** empty log message *** --- diff --git a/MInputMethod.cs b/MInputMethod.cs index 87777f6..e75f5bc 100644 --- a/MInputMethod.cs +++ b/MInputMethod.cs @@ -49,6 +49,7 @@ namespace M17N.Input private static MSymbol Mmove = "move"; private static MSymbol Mmark = "mark"; private static MSymbol Mmarker = "marker"; + private static MSymbol Mset = "set"; private static MSymbol Madd = "add"; private static MSymbol Msub = "sub"; private static MSymbol Mmul = "mul"; @@ -60,10 +61,14 @@ namespace M17N.Input private static MSymbol Mpushback = "pushback"; private static MSymbol Mkeyseq = "keyseq"; + private static Xex.Symbol Nprogn = "progn"; + private static Xex.Term Tnil = new Xex.Term ((Xex.Symbol) "nil"); + private static Xex.Term Tcatch_tag = new Xex.Term ((Xex.Symbol) "@mimtag"); + private static Dictionary im_table = new Dictionary (); - internal static MInputMethod im_global; + internal static MInputMethod im_global = null; // Sub classes private class Exception : System.Exception @@ -310,7 +315,14 @@ namespace M17N.Input public class KeySeq : Xex.TermValue { - List keyseq = new List (); + public List keyseq = new List (); + + public override Xex.TermValue Clone () + { + KeySeq ks = new KeySeq (); + ks.keyseq.InsertRange (0, keyseq); + return ks; + } public KeySeq () { } @@ -387,8 +399,8 @@ namespace M17N.Input { foreach (Xex.Term term in args) { - if (term.IsName) - keyseq.Add (new Key ((MSymbol) term.Nameval.name)); + if (term.IsSymbol) + keyseq.Add (new Key ((MSymbol) ((string) term.Symval))); else keyseq.Add (new Key (term.Strval)); } @@ -398,16 +410,16 @@ namespace M17N.Input { string str; - foreach (Key key in this) + foreach (Key key in keyseq) if (key.HasModifier) { str = "(keyseq"; - foreach (Key k in this) + foreach (Key k in keyseq) str += " " + k.ToString (); return str + ")"; } str = "\""; - foreach (Key key in this) + foreach (Key key in keyseq) str += key.ToString (); return str + "\""; } @@ -552,50 +564,45 @@ namespace M17N.Input internal class Plugin { - public string name; - public Assembly assembly; - public MPlist methods; + private string name; + private Assembly assembly; + private Type plugin_type; - public override string ToString () + public Plugin (string name) { - string str = "(" + name; - for (MPlist p = methods; ! p.IsEmpty; p = p.next) - str += " " + p.key; - return str + ")"; + this.name = name; } - public Xex.Term Call (MSymbol method, MInputContext ic, Xex.Term[] args) + public MethodInfo GetMethod (Xex.Symbol name) { if (assembly == null) { - try { - assembly = Assembly.LoadFrom (name + ".dll"); - } catch { - return Xex.Zero; - } - Type t = assembly.GetType ("Plugin"); - for (MPlist p = plugin.methods; ! p.IsEmpty; p = p.next) - p.Set (p.key, t.GetMethod (p.key.Name)); + assembly = Assembly.LoadFrom (name + ".dll"); + plugin_type = assembly.GetType ("M17n.MInputMethod.Plugin"); } - MethodInfo method_info = (MethodInfo) methods.Get (method); - if (method_info == null) - return Xex.Zero; - Xex.Term result = (Xex.Term) method_info.Invoke (null, args); - return result.Eval (); + MethodInfo info = plugin_type.GetMethod ((string) name); + if (info == null) + throw new Exception ("Invalid plugin method: " + name); + return info; + } + + public override string ToString () + { + return String.Format ("(module {0}", name); } } internal class PluginMethod : Xex.Function { - public Plugin plugin; - public MSymbol method; + private Plugin plugin; + private MethodInfo method_info; + object[] parameters = new object[2]; - public PluginMethod (Plugin plugin, MSymbol name) - : base ((Name) name.name, 0, -1) + public PluginMethod (Plugin plugin, string name) + : base ((Xex.Symbol) name, 0, -1) { this.plugin = plugin; - method = name.name.Substring (plugin.name.Length + 1); } public override Xex.Term Call (Xex.Domain domain, Xex.Variable vari, @@ -608,31 +615,14 @@ namespace M17N.Input if (domain.Thrown) return args[i]; } - return plugin.Call (method, (MIntutContext) domain.context, args); + if (method_info == null) + method_info = plugin.GetMethod (name); + parameters[0] = domain.context; + parameters[1] = args; + return (Xex.Term) method_info.Invoke (null, parameters); } } - internal class PluginCall : Xex.TermValue - { - PluginMethod method; - Xex.Term[] args; - - public PluginCall (Plugin plugin, MSymbol entry, Xex.Term[] args) - { - this.plugin = plugin; - this.entry = entry; - this.args = args; - } - - public override Xex.Term Eval (Xex.Domain domain) - { - Xex.Term[] args = new Xex.Term[this.args.Length]; - for (int i = 0; i < args.Length; i++) - args[i] = this.args[i].Eval (domain); - return plugin.Call (entry, args); - } - } - internal abstract class Marker : Xex.TermValue { MSymbol name; @@ -649,11 +639,18 @@ namespace M17N.Input { int pos; - public Named (MSymbol name) : base (name) { } + public Named (MSymbol name) : this (name, 0) { } + + private Named (MSymbol name, int p) : base (name) { pos = p; } public override int Position (MInputContext ic) { return pos; } public override void Mark (MInputContext ic) { pos = ic.cursor_pos; } + + public override Xex.TermValue Clone () + { + return new Named (name, pos); + } } public class Predefined : Marker @@ -670,7 +667,7 @@ namespace M17N.Input case '[': if (ic.cursor_pos > 0) { - int pos = ic.cursor_os; + int pos = ic.cursor_pos; int to; ic.preedit.FindProp (MInputMethod.Mcandidates, pos - 1, out pos, out to); @@ -696,6 +693,11 @@ namespace M17N.Input { throw new Exception ("Can't set predefined marker: " + name); } + + public override Xex.TermValue Clone () + { + return new Predefined (name); + } } static internal Dictionary predefined_markers; @@ -703,26 +705,27 @@ namespace M17N.Input static Marker () { predefined_markers = new Dictionary (); - MSymbol[] symlist = new MSYmbol[] {"@<", "@>", "@-", "@+", "@[", "@]", + MSymbol[] symlist = new MSymbol[] {"@<", "@>", "@-", "@+", "@[", "@]", "@0", "@1", "@2", "@3", "@4", "@5", "@6", "@7", "@8", "@9" }; - foreach (MSymbol s in strline) + foreach (MSymbol s in symlist) predefined_markers[s] = new Predefined (s); } public static Marker Get (MInputContext ic, MSymbol name) { + Predefined pred; Marker m; - if (predefined_markers.TryGetValue (name, out m)) - return m; + if (predefined_markers.TryGetValue (name, out pred)) + return pred; if (name.Name[0] == '@') throw new Exception ("Invalid marker name: " + name); - m = (Marker) ic->markers.Get (name); + m = (Marker) ic.markers.Get (name); if (m == null) { m = new Named (name); - ic->markers.Put (name, m); + ic.markers.Put (name, m); } return m; } @@ -732,53 +735,52 @@ namespace M17N.Input { public MSymbol name; public Dictionary submaps; - public Xex actions; + public Xex.Term actions; - public void Add (KeySeq keys, int index, Xex actions) + public void Add (KeySeq keys, int index, Xex.Term actions) { Map sub = null; if (submaps == null) submaps = new Dictionary (); else - submaps.TryGetValue (keys[index], out sub); + submaps.TryGetValue (keys.keyseq[index], out sub); if (sub == null) { - Key key = keys[index]; + Key key = keys.keyseq[index]; submaps[key] = sub = new Map (); } - if (index + 1 < keys.Count) + if (index + 1 < keys.keyseq.Count) sub.Add (keys, index + 1, actions); else this.actions = actions; } - public Xex Lookup (KeySeq keys, int index) + public Xex.Term Lookup (KeySeq keys, int index) { Map sub; - if (index + 1 == keys.Count) + if (index + 1 == keys.keyseq.Count) return actions; - if (submaps.TryGetValue (keys[index], out sub)) + if (submaps.TryGetValue (keys.keyseq[index], out sub)) return sub.Lookup (keys, index + 1); - return null; + return Tnil; } private void describe (MText mt, KeySeq keyseq) { - if (keyseq.Count > 0) + if (keyseq.keyseq.Count > 0) { mt.Cat (" (").Cat (keyseq.ToString ()); - if (actions != null) - mt.Cat (' ').Cat (actions.ToString ()); + mt.Cat (' ').Cat (actions.ToString ()); mt.Cat (')'); } if (submaps != null) foreach (KeyValuePair kv in submaps) { - keyseq.Add (kv.Key); + keyseq.keyseq.Add (kv.Key); kv.Value.describe (mt, keyseq); - keyseq.RemoveAt (keyseq.Count - 1); + keyseq.keyseq.RemoveAt (keyseq.keyseq.Count - 1); } } @@ -826,7 +828,7 @@ namespace M17N.Input private MText description; internal MText title; internal Command[] commands; - internal Xex.Name[] var_names; + internal Xex.Symbol[] var_names; internal Dictionary plugins; internal Dictionary maps; internal MPlist states; @@ -855,7 +857,9 @@ namespace M17N.Input List list = MDatabase.List (tag); M17n.DebugPrint ("Found {0} input methods\n", list.Count); foreach (MDatabase mdb in list) - im_table[mdb.tag] = new MInputMethod (mdb.tag); + { + im_table[mdb.tag] = new MInputMethod (mdb.tag); + } tag = new MDatabase.Tag (Minput_method, MSymbol.t, MSymbol.nil, "global"); im_global = im_table[tag]; } @@ -887,10 +891,15 @@ namespace M17N.Input } description = this.description; title = this.title; - variables = new Xex.Variable[var_names.Length]; - int i = 0; - foreach (Xex.Name name in var_names) - variables[i++] = domain.GetVar (name, false); + if (var_names == null) + variables = null; + else + { + variables = new Xex.Variable[var_names.Length]; + int i = 0; + foreach (Xex.Symbol name in var_names) + variables[i++] = domain.GetVar (name, false); + } commands = this.commands; return true; } @@ -951,7 +960,7 @@ namespace M17N.Input private bool load_body () { - domain = new Xex.Domain (domain, null); + domain = new Xex.Domain (im_domain, null); mdb = MDatabase.Find (tag); if (mdb == null) return false; @@ -985,11 +994,7 @@ namespace M17N.Input pl = pl.next; if (sym == Mdescription) - { - description = parse_description (pl); - if (description == null) - description = new MText ("No description"); - } + description = parse_description (pl); else if (sym == Mtitle) { if (pl.IsMText) @@ -1233,7 +1238,7 @@ namespace M17N.Input return node.InnerText; } - private void new_variable (Xex.Name name, string desc, int val, + private void new_variable (Xex.Symbol name, string desc, int val, MPlist pl, Xex.Variable vari) { int[] range; @@ -1271,7 +1276,7 @@ namespace M17N.Input } } - private void new_variable (Xex.Name name, string desc, MText val, + private void new_variable (Xex.Symbol name, string desc, MText val, MPlist pl, Xex.Variable vari) { string[] range; @@ -1300,17 +1305,17 @@ namespace M17N.Input } } - private void new_variable (Xex.Name name, string desc, MSymbol val, + private void new_variable (Xex.Symbol name, string desc, MSymbol val, MPlist pl, Xex.Variable vari) { - Xex.Name[] range; - Xex.Name sym = val.Name; + Xex.Symbol[] range; + Xex.Symbol sym = val.Name; if (pl.IsEmpty) range = null; else { - range = new Xex.Name[pl.Count * 2]; + range = new Xex.Symbol[pl.Count * 2]; for (int i = 0; i < range.Length; i++) { if (pl.IsSymbol) @@ -1332,7 +1337,7 @@ namespace M17N.Input private void parse_variables (MPlist plist) { - var_names = new Xex.Name[plist.Count]; + var_names = new Xex.Symbol[plist.Count]; for (int i = 0; ! plist.IsEmpty; i++, plist = plist.next) { @@ -1340,12 +1345,12 @@ namespace M17N.Input throw new Exception ("Invalid variable: " + plist); MPlist p = plist.Plist; - Xex.Name name = (Xex.Name) p.Symbol.Name; + Xex.Symbol name = (Xex.Symbol) p.Symbol.Name; var_names[i] = name; p = p.next; string desc = (string) parse_description (p); - Xex.Variable vari = im_global.domain.GetVar (name, false); - + Xex.Variable vari + = im_global != null ? im_global.domain.GetVar (name, false) : null; if (vari != null) domain.Defvar (vari); if (desc != null) @@ -1368,10 +1373,10 @@ namespace M17N.Input { XmlNodeList node_list = node.ChildNodes; - var_names = new Xex.Name[node_list.Count]; + var_names = new Xex.Symbol[node_list.Count]; for (int i = 0; i < node_list.Count; i++) { - Xex.Name name = node_list[i].Attributes[0].Value; + Xex.Symbol name = node_list[i].Attributes[0].Value; Xex.Variable vari = im_global.domain.GetVar (name, false); if (vari != null) @@ -1412,13 +1417,13 @@ namespace M17N.Input { MPlist p = plist.Plist; MSymbol sym = p.Symbol; - Plugin plugin = new Plugin (); + Plugin plugin = new Plugin (sym.Name); - plugin.name = sym.Name; - plugin.methods = new MPlist (); for (p = p.next; ! p.IsEmpty; p = p.next) - plugin.methods.Add (p.Symbol, null); - plugins.Add (sym, plugin); + { + Xex.Function func = new PluginMethod (plugin, p.Symbol.Name); + domain.Defun (func); + } } } @@ -1428,13 +1433,13 @@ namespace M17N.Input foreach (XmlNode n in node.ChildNodes) { - Plugin plugin = new Plugin (); - plugin.name = n.Attributes["id"].Value; - plugin.methods = new MPlist (); + Plugin plugin = new Plugin (n.Attributes[0].Value); foreach (XmlNode nn in n.ChildNodes) - plugin.methods.Add ((MSymbol) nn.Attributes["id"].Value, - null); - plugins.Add (plugin.name, plugin); + { + Xex.Function func = new PluginMethod (plugin, + nn.Attributes[0].Value); + domain.Defun (func); + } } } @@ -1442,11 +1447,10 @@ namespace M17N.Input { for (XmlNode nn = node.FirstChild; nn != null; nn = nn.NextSibling) if (nn.NodeType == XmlNodeType.Element) - domain.Defun ((MSymbol) node.GetAttribute ("id")); + domain.Defun (nn, true); for (XmlNode nn = node.FirstChild; nn != null; nn = nn.NextSibling) if (nn.NodeType == XmlNodeType.Element) - domain.Defun ((MSymbol) node.GetAttribute ("id"), null, - nn.FirstChild); + domain.Defun (nn, false); } private void parse_maps (XmlNode node) @@ -1495,7 +1499,7 @@ namespace M17N.Input if (target_name == MSymbol.nil) im.domain.CopyFunc (domain); else - im.domain.CopyFunc (domain, target_name); + im.domain.CopyFunc (domain, (Xex.Symbol) target_name.Name); } else if (target_type == Mmap) { @@ -1527,6 +1531,62 @@ namespace M17N.Input } } + private Xex.Term parse_cond (MPlist plist) + { + Xex.Term[] args = new Xex.Term[plist.Count]; + + for (int i = 0; ! plist.IsEmpty; i++, plist = plist.next) + { + if (! plist.IsPlist) + throw new Exception ("Invalid cond args: " + plist); + MPlist p = plist.Plist; + List arg = new List (parse_action (p)); + args[i] = new Xex.Term (arg); + } + return new Xex.Term (domain, (Xex.Symbol) Mcond.Name, args); + } + + private Xex.Term[] parse_action (MPlist plist) + { + Xex.Term[] terms = new Xex.Term[plist.Count]; + + for (int i = 0; ! plist.IsEmpty; i++, plist = plist.next) + { + if (plist.IsSymbol) + terms[i] = new Xex.Term ((Xex.Symbol) plist.Symbol.Name); + else if (plist.IsMText) + terms[i] = new Xex.Term ((string) plist.Text); + else if (plist.IsInteger) + terms[i] = new Xex.Term (plist.Integer); + else if (plist.IsPlist) + { + MPlist p = plist.Plist; + if (! p.IsSymbol) + throw new Exception ("Invalid action: " + p); + MSymbol name = p.Symbol; + p = p.next; + if (name == Mcond) + terms[i] = parse_cond (p); + else if (name == Mset || name == Madd || name == Msub + || name == Mmul || name == Mdiv) + { + if (! p.IsSymbol) + throw new Exception ("Invalid action: " + p); + Xex.Symbol varname = p.Symbol.Name; + terms[i] = new Xex.Term (domain, (Xex.Symbol) name.Name, + varname, parse_action (p.next)); + } + else + terms[i] = new Xex.Term (domain, (Xex.Symbol) name.Name, + parse_action (p)); + } + else + throw new Exception ("Invalid action: " + plist); + } + return terms; + } + + private void parse_macros (MPlist plist) { for (MPlist pl = plist; ! pl.IsEmpty; pl = pl.next) @@ -1536,7 +1596,7 @@ namespace M17N.Input if (! p.IsSymbol) continue; - domain.Defun (p.Symbol, null, null); + domain.Defun ((Xex.Symbol) p.Symbol.Name, false, null, null, true); } for (MPlist pl = plist; ! pl.IsEmpty; pl = pl.next) if (pl.IsPlist) @@ -1546,7 +1606,8 @@ namespace M17N.Input if (! p.IsSymbol) continue; transform (p.next); - domain.Defun (p.Symbol, null, p.next); + domain.Defun ((Xex.Symbol) p.Symbol.Name, false, null, + parse_action (p.next), false); } } @@ -1577,9 +1638,8 @@ namespace M17N.Input p = p.next; if (p.IsEmpty) continue; - transform (p); - MXex expr = new MXex (p, domain); - map.Add (keys, 0, expr); + map.Add (keys, 0, + new Xex.Term (domain, Nprogn, parse_action (p))); } } } @@ -1614,9 +1674,8 @@ namespace M17N.Input continue; MSymbol map_name = p.Symbol; p = p.next; - transform (p); - state.branches.Add (map_name, - new MXex (p, domain)); + Xex.Term term = new Xex.Term (domain, Nprogn, parse_action (p)); + state.branches.Add (map_name, term); } } } @@ -1639,21 +1698,22 @@ namespace M17N.Input private static Xex.Term Fmarker (Xex.Domain domain, Xex.Variable vari, Xex.Term[] args) { - MSymbol name = (string) args[0].Nameval; - return Marker.Get (name); + MSymbol name = (string) args[0].Symval; + return new Xex.Term (Marker.Get ((MInputContext) domain.context, name)); } private static Xex.Term Fchar_at (Xex.Domain domain, Xex.Variable vari, Xex.Term[] args) { - return ((MInputContext) domain.context).char_at (args[0].Intval); + int c = ((MInputContext) domain.context).char_at (args[0].Intval); + return new Xex.Term (c); } private static Xex.Term Fdelete (Xex.Domain domain, Xex.Variable vari, Xex.Term[] args) { ((MInputContext) domain.context).delete ((int) args[0].Intval); - return true; + return args[0]; } private static Xex.Term Fselect (Xex.Domain domain, Xex.Variable vari, @@ -1664,7 +1724,7 @@ namespace M17N.Input if (args[0].IsInt) ic.select (args[0].Intval); else - ic.select ((MSYmbol) ((string) args[0].Nameval)); + ic.select ((MSymbol) ((string) args[0].Symval)); return args[0]; } @@ -1672,14 +1732,14 @@ namespace M17N.Input Xex.Term[] args) { ((MInputContext) domain.context).show (); - return Xex.Zero; + return Tnil; } private static Xex.Term Fhide (Xex.Domain domain, Xex.Variable vari, Xex.Term[] args) { ((MInputContext) domain.context).hide (); - return Xex.Zero; + return Tnil; } private static Xex.Term Fmove (Xex.Domain domain, Xex.Variable vari, @@ -1707,7 +1767,7 @@ namespace M17N.Input private static Xex.Term Fkeyseq (Xex.Domain domain, Xex.Variable vari, Xex.Term[] args) { - return new KeySeq (args); + return new Xex.Term (new KeySeq (args)); } private static Xex.Term Fpushback (Xex.Domain domain, Xex.Variable vari, @@ -1728,7 +1788,7 @@ namespace M17N.Input Xex.Term[] args) { ((MInputContext) domain.context).pop (); - return Xex.Zero; + return Tnil; } private static Xex.Term Fundo (Xex.Domain domain, Xex.Variable vari, @@ -1736,14 +1796,14 @@ namespace M17N.Input { int n = args.Length == 0 ? -2 : args[0].Intval; ((MInputContext) domain.context).undo (n); - return Xex.Zero; + return Tnil; } private static Xex.Term Fcommit (Xex.Domain domain, Xex.Variable vari, Xex.Term[] args) { ((MInputContext) domain.context).commit (); - return Xex.Zero; + return Tnil; } private static Xex.Term Funhandle (Xex.Domain domain, Xex.Variable vari, @@ -1751,7 +1811,7 @@ namespace M17N.Input { ((MInputContext) domain.context).commit (); args = new Xex.Term[2]; - args[0] = args[1] = catch_tag; + args[0] = args[1] = Tcatch_tag; return Xex.Fthrow (domain, vari, args); } @@ -1772,10 +1832,10 @@ namespace M17N.Input str += " " + cmd; str += ")"; } - if (variables != null) + if (var_names != null) { str += " (variables"; - foreach (Variable var in variables) + foreach (Xex.Symbol var in var_names) str += " " + var; str += ")"; } @@ -1798,7 +1858,7 @@ namespace M17N.Input public class MInputContext { - internal static MSymbol Mcandidates_group_size = "candidates-group-size"; + internal static Xex.Symbol Ncandidates_group_size = "candidates-group-size"; private static MSymbol Mat_less_than = "@<"; private static MSymbol Mat_greater_than = "@>"; private static MSymbol Mat_minus = "@-"; @@ -1811,9 +1871,9 @@ namespace M17N.Input private bool active; private MText status; private bool status_changed; - private MText preedit; + internal MText preedit; private bool preedit_changed; - private int cursor_pos; + internal int cursor_pos; private bool cursor_pos_changed; private Candidates candidates; private MPlist candidate_group; @@ -1826,13 +1886,11 @@ namespace M17N.Input internal MInputMethod.KeySeq keys; private int key_head; private int state_key_head; - private MPlist state_boundary; + private object state_var_values; private int commit_key_head; private MText state_preedit; private int state_pos; internal MPlist markers = new MPlist (); - private MPlist vars; - private MPlist vars_saved; internal MText preceding_text = new MText (); internal MText following_text = new MText (); private bool key_unhandled; @@ -1902,13 +1960,30 @@ namespace M17N.Input public int Index; public object Data; + public Block (int index, Xex.Term term) + { + Index = index; + if (term.IsStr) + Data = (MText) term.Strval; + else + { + MPlist plist = new MPlist (); + MPlist p = plist; + foreach (Xex.Term t in term.Listval) + p = p.Add (MSymbol.mtext, (MText) t.Strval); + Data = plist; + } + } + public Block (int index, MPlist plist) { Index = index; if (plist.IsMText) Data = plist.Text; - else + else if (plist.IsPlist) Data = plist.Plist; + else + throw new Exception ("Invalid candidate: " + plist); } public int Count @@ -2158,13 +2233,10 @@ namespace M17N.Input internal void insert_candidates (Xex.Term arg) { int column = 0; + Xex.Variable v = domain.GetVar (Ncandidates_group_size, false); - if (domain.IsBound (Mcandidates_group_size)) - { - object val = domain.GetValue (Mcandidates_group_size); - if (val is int) - column = (int) val; - } + if (v != null) + column = v.Value.Intval; candidates = new Candidates (arg.Listval, column); candidate_from = candidate_to = cursor_pos; update_candidate (); @@ -2348,8 +2420,8 @@ namespace M17N.Input else { key_head = - n; - if (key_head > keys.Count) - key_head = keys.Count; + if (key_head > keys.keyseq.Count) + key_head = keys.keyseq.Count; } } @@ -2357,24 +2429,24 @@ namespace M17N.Input { if (key_head > 0) key_head--; - if (key_head < keys.Count) - keys.RemoveRange (key_head, keys.Count - key_head); - for (int i = 0; i < keyseq.Count; i++) - keys.Add (keyseq[i]); + if (key_head < keys.keyseq.Count) + keys.keyseq.RemoveRange (key_head, keys.keyseq.Count - key_head); + for (int i = 0; i < keyseq.keyseq.Count; i++) + keys.keyseq.Add (keyseq.keyseq[i]); } internal void pop () { - if (key_head < keys.Count) - keys.RemoveRange (key_head, 1); + if (key_head < keys.keyseq.Count) + keys.keyseq.RemoveRange (key_head, 1); } internal void undo (int n) { if (n < 0) - keys.RemoveRange (keys.Count + n, - n); + keys.keyseq.RemoveRange (keys.keyseq.Count + n, - n); else - keys.RemoveRange (n, keys.Count - n); + keys.keyseq.RemoveRange (n, keys.keyseq.Count - n); reset (); } @@ -2417,7 +2489,7 @@ namespace M17N.Input if (state != states.Peek ()) { states.Push (state); - state_boundary = domain.SetBoundary (); + state_var_values = domain.SaveValues (); status = state.title; if (status == null) status = im.title; @@ -2430,39 +2502,6 @@ namespace M17N.Input } } - internal bool call (MSymbol module, MSymbol method, MPlist arglist) - { - MInputMethod.Plugin plugin; - - if (! im.plugins.TryGetValue (module, out plugin)) - return false; - if (plugin.assembly == null) - { - Assembly assembly; - - try { - assembly = Assembly.LoadFrom (module.Name + ".dll"); - } catch { - return false; - } - Type t = assembly.GetType ("Plugin"); - for (MPlist p = plugin.methods; ! p.IsEmpty; p = p.next) - p.Set (p.key, t.GetMethod (p.key.Name)); - } - - MethodInfo method_info = (MethodInfo) plugin.methods.Get (method); - if (method_info == null) - return false; - object[] method_arg = new object[1]; - method_arg[0] = arglist; - bool result = (bool) method_info.Invoke (null, method_arg); - if (! result) - return false; - if (! arglist.IsEmpty) - (new Xex (arglist, domain)).Eval (domain); - return true; - } - internal void reset () { preedit.Del (); diff --git a/Makefile b/Makefile index 3837632..353493b 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ M17NIM.dll: ${INPUT_SRC} M17N.dll M17NCore.dll XmlExpr.dll XmlExpr.dll: ${XEX_SRC} $(RUNCS) -out:$@ -t:library ${XEX_SRC} -input.exe: input.cs M17NIM.dll +input.exe: input.cs M17NIM.dll XmlExpr.dll $(RUNCS) -r:M17N.dll -r:M17NCore -r:XmlExpr -r:M17NIM.dll $< expr.exe: expr.cs diff --git a/XmlExpr.cs b/XmlExpr.cs index ae56091..1dbff0f 100644 --- a/XmlExpr.cs +++ b/XmlExpr.cs @@ -10,58 +10,58 @@ namespace System.Xml.Expression { public static int debug_level = 0; - public struct Name : IEquatable + public struct Symbol : IEquatable { private static NameTable nt = new NameTable (); internal string name; - public Name (string str) + public Symbol (string str) { name = nt.Add (str); } - public static implicit operator Name (string str) + public static implicit operator Symbol (string str) { - return new Name (str); + return new Symbol (str); } - public static implicit operator string (Name name) + public static implicit operator string (Symbol name) { return name.name; } - public static bool operator== (Name n1, Name n2) + public static bool operator== (Symbol n1, Symbol n2) { return (object) n1.name == (object) n2.name; } - public static bool operator!= (Name n1, Name n2) + public static bool operator!= (Symbol n1, Symbol n2) { return (object) n1.name != (object) n2.name; } - public static bool operator== (Name n1, string n2) + public static bool operator== (Symbol n1, string n2) { return (object) n1.name == (object) n2; } - public static bool operator!= (Name n1, string n2) + public static bool operator!= (Symbol n1, string n2) { return (object) n1.name != (object) n2; } - public static bool operator== (string n1, Name n2) + public static bool operator== (string n1, Symbol n2) { return (object) n1 == (object) n2.name; } - public static bool operator!= (string n1, Name n2) + public static bool operator!= (string n1, Symbol n2) { return (object) n1 != (object) n2.name; } - public bool Equals (Name name) + public bool Equals (Symbol name) { return Object.ReferenceEquals (this.name, name.name); } @@ -81,36 +81,36 @@ namespace System.Xml.Expression public override string ToString () { return name; } } - private static Name Nexpr = "expr"; + private static Symbol Nexpr = "expr"; - private static Name Nfuncall = "funcall"; - private static Name Nvarref = "varref"; - private static Name Ninteger = "integer"; - private static Name Nstring = "string"; - private static Name Nsymbol = "symbol"; - private static Name Nlist = "list"; + private static Symbol Nfuncall = "funcall"; + private static Symbol Nvarref = "varref"; + private static Symbol Ninteger = "integer"; + private static Symbol Nstring = "string"; + private static Symbol Nsymbol = "symbol"; + private static Symbol Nlist = "list"; - private static Name Ndefun = "defun"; - private static Name Nfname = "fname"; - private static Name Nargs = "args"; - private static Name Nargs_unevalled = "args-unevalled"; - private static Name Nfixed = "fixed"; - private static Name Noptional = "optional"; - private static Name Nrest = "rest"; + private static Symbol Ndefun = "defun"; + private static Symbol Nfname = "fname"; + private static Symbol Nargs = "args"; + private static Symbol Nargs_unevalled = "args-unevalled"; + private static Symbol Nfixed = "fixed"; + private static Symbol Noptional = "optional"; + private static Symbol Nrest = "rest"; - private static Name Ndefvar = "defvar"; - private static Name Nvname = "vname"; - private static Name Ndescription = "description"; - private static Name Nrange = "range"; + private static Symbol Ndefvar = "defvar"; + private static Symbol Nvname = "vname"; + private static Symbol Ndescription = "description"; + private static Symbol Nrange = "range"; public abstract class Function { - public Name name; + public Symbol name; public int min_arg, max_arg; public Function () { } - public Function (Name name, int min_arg, int max_arg) + public Function (Symbol name, int min_arg, int max_arg) { this.name = name; this.min_arg = min_arg; @@ -129,7 +129,7 @@ namespace System.Xml.Expression public Builtin builtin; public bool setvar; - public Subroutine (Builtin builtin, Name name, bool setvar, + public Subroutine (Builtin builtin, Symbol name, bool setvar, int min_arg, int max_arg) : base (name, min_arg, max_arg) { @@ -153,7 +153,7 @@ namespace System.Xml.Expression { public Builtin builtin; - public SpecialForm (Builtin builtin, Name name, + public SpecialForm (Builtin builtin, Symbol name, int min_arg, int max_arg) : base (name, min_arg, max_arg) { @@ -172,46 +172,85 @@ namespace System.Xml.Expression internal Variable[] args; internal Term[] body; - public Lambda (XmlNode node, Domain domain) - { - int nfixed = 0; - int noptional = 0; - int nrest = 0; - name = node.Attributes[Nfname].Value; + public Lambda (Domain domain, XmlNode node) + { + int nfixed = 0; + int noptional = 0; + int nrest = 0; + name = node.Attributes[Nfname].Value; - node = node.FirstChild; - if (node != null - && (node.Name == Nargs || node.Name == Nargs_unevalled)) - { - XmlNode n; - args_evalled = node.Name == Nargs; - for (n = node.FirstChild; n != null; n = n.NextSibling) - { - if (n.Name == Nfixed) - nfixed++; - else if (n.Name == Noptional) - noptional++; - else if (n.Name == Nrest) - nrest++; - else - throw new Exception ("Invalid argument type: " + n); - } - min_arg = nfixed; - max_arg = nfixed + noptional + nrest; - args = new Variable[max_arg]; - n = node.FirstChild; - for (int i = 0; i < max_arg; n = n.NextSibling) - args[i++] = domain.Defvar ((Name) n.Attributes[0].Value); - if (nrest == 1) - max_arg = - max_arg; - } - else - { - min_arg = max_arg = 0; - } - } + node = node.FirstChild; + if (node != null + && (node.Name == Nargs || node.Name == Nargs_unevalled)) + { + XmlNode n; + args_evalled = node.Name == Nargs; + for (n = node.FirstChild; n != null; n = n.NextSibling) + { + if (n.Name == Nfixed) + nfixed++; + else if (n.Name == Noptional) + noptional++; + else if (n.Name == Nrest) + nrest++; + else + throw new Exception ("Invalid argument type: " + n); + } + min_arg = nfixed; + max_arg = nfixed + noptional + nrest; + args = new Variable[max_arg]; + n = node.FirstChild; + for (int i = 0; i < max_arg; n = n.NextSibling) + args[i++] = domain.Defvar ((Symbol) n.Attributes[0].Value); + if (nrest == 1) + max_arg = - max_arg; + } + else + { + min_arg = max_arg = 0; + } + } + + public Lambda (Domain domain, Symbol name, bool args_evalled, Symbol[] args) + { + int nfixed = 0; + int noptional = 0; + int nrest = 0; - public void SetBody (XmlNode node, Domain domain) + this.name = name; + this.args_evalled = args_evalled; + if (args != null) + { + int i = 0; + for (i = 0; i < args.Length; i++, nfixed++) + if (args[i] == Noptional || args[i] == Nrest) + break; + if (i < args.Length) + { + if (args[i] == Noptional) + { + for (i++; i < args.Length; i++, noptional++) + if (args[i] == Nrest) + break; + if (i < args.Length) + nrest = 1; + } + } + min_arg = nfixed; + max_arg = nfixed + noptional + nrest; + this.args = new Variable[max_arg]; + int j; + for (i = j = 0; j < this.args.Length; i++) + if (args[i] != Noptional || args[i] != Nrest) + this.args[j++] = domain.Defvar (args[i]); + } + else + { + min_arg = max_arg = 0; + } + } + + public void SetBody (Domain domain, XmlNode node) { for (node = node.FirstChild; node != null; node = node.NextSibling) if (node.Name != Ndescription @@ -229,6 +268,11 @@ namespace System.Xml.Expression } } + public void SetBody (Term[] body) + { + this.body = body; + } + public override Term Call (Domain domain, Variable vari, Term[] args) { Bindings current = domain.bindings; @@ -271,13 +315,13 @@ namespace System.Xml.Expression public class Variable : TermValue { - public readonly Name name; + public readonly Symbol name; public string desc; internal Term default_val; internal Term val; object range; - public Variable (Name name, Term value) + public Variable (Symbol name, Term value) { this.name = name; val = value; @@ -286,7 +330,7 @@ namespace System.Xml.Expression public virtual bool ValueP (Term val) { return true; } - public Variable Clone () + public override TermValue Clone () { Variable v = new Variable (name, val); v.desc = desc; @@ -355,7 +399,7 @@ namespace System.Xml.Expression return false; } - public Int (Name name, string description, int value, int[] range) + public Int (Symbol name, string description, int value, int[] range) : base (name, new Term (value)) { if (! SubsetP (value, range)) @@ -405,7 +449,7 @@ namespace System.Xml.Expression return false; } - public Str (Name name, string description, string value, string[] range) + public Str (Symbol name, string description, string value, string[] range) : base (name, new Term (value)) { if (! SubsetP (value, range)) @@ -437,25 +481,25 @@ namespace System.Xml.Expression public class Sym : Variable { - public Name[] range; + public Symbol[] range; - private static bool SubsetP (Name[] r1, Name[] r2) + private static bool SubsetP (Symbol[] r1, Symbol[] r2) { - foreach (Name n in r1) + foreach (Symbol n in r1) if (! SubsetP (n, r2)) return false; return true; } - private static bool SubsetP (Name name, Name[] r) + private static bool SubsetP (Symbol name, Symbol[] r) { - foreach (Name n in r) + foreach (Symbol n in r) if (name == n) return true; return false; } - public Sym (Name name, string description, Name value, Name[] range) + public Sym (Symbol name, string description, Symbol value, Symbol[] range) : base (name, new Term (value)) { if (! SubsetP (value, range)) @@ -467,18 +511,18 @@ namespace System.Xml.Expression public override bool ValueP (Term term) { - if (! (term.objval is Name)) + if (! (term.objval is Symbol)) return false; - return SubsetP (term.Nameval, range); + return SubsetP (term.Symval, range); } public override object Range { get { return range; } set { - Name[] r = (Name[]) value; + Symbol[] r = (Symbol[]) value; if (! SubsetP (r, range) - || ! SubsetP (val.Nameval, r) - || ! SubsetP (default_val.Nameval, r)) + || ! SubsetP (val.Symval, r) + || ! SubsetP (default_val.Symval, r)) throw new Exception ("Invalid range"); range = r; } @@ -526,10 +570,10 @@ namespace System.Xml.Expression #if false internal class ThrowException : Exception { - Name tag; + Symbol tag; public object value; - public ThrowException (Name tag, object value) : base () + public ThrowException (Symbol tag, object value) : base () { this.tag = tag; this.value = value; @@ -541,7 +585,7 @@ namespace System.Xml.Expression { private object val; - public CatchTag (Name name) { val = name.name; } + public CatchTag (Symbol name) { val = name.name; } private CatchTag (int i) { val = i; } public static CatchTag Return = new CatchTag (0); @@ -564,28 +608,22 @@ namespace System.Xml.Expression public object context; public int depth = 0; - internal Dictionary functions; - internal Dictionary> - modules = new Dictionary> (); - internal Dictionary variables; + internal Dictionary functions + = new Dictionary (); + internal Dictionary variables + = new Dictionary (); internal Bindings bindings; private Stack catch_stack = new Stack (); private int catch_count = 0; - internal Domain () - { - functions = new Dictionary (); - variables = new Dictionary (); - } + internal Domain () { } - public Domain (object context) : this (basic, context) - { - } + public Domain (object context) : this (basic, context) { } public Domain (Domain parent, object context) { - functions = new Dictionary (parent.functions); - variables = new Dictionary (parent.variables); + functions = new Dictionary (parent.functions); + variables = new Dictionary (parent.variables); this.context = context; } @@ -613,7 +651,7 @@ namespace System.Xml.Expression catch_count--; } - internal bool Thrown { + public bool Thrown { get { return catch_count < catch_stack.Count; } } @@ -647,57 +685,67 @@ namespace System.Xml.Expression public void DefSubr (Builtin builtin, string str, bool setvar, int min_arg, int max_arg, params string[] aliases) { - Name name = str; + Symbol name = str; Function func = new Function.Subroutine (builtin, name, setvar, min_arg, max_arg); functions[name] = func; foreach (string a in aliases) - functions[(Name) a] = func; + functions[(Symbol) a] = func; } public void DefSpecial (Builtin builtin, string str, int min_arg, int max_arg, params string[] aliases) { - Name name = str; + Symbol name = str; Function func = new Function.SpecialForm (builtin, name, min_arg, max_arg); functions[name] = func; foreach (string a in aliases) - functions[(Name) a] = func; + functions[(Symbol) a] = func; } public void DefAlias (string alias, string str) { - functions[(Name) alias] = functions[(Name) str]; + functions[(Symbol) alias] = functions[(Symbol) str]; } - internal Function.Lambda RegisterFunction (XmlNode node) + public void Defun (Symbol name, bool args_evalled, + Symbol[] args, Term[] body, bool prototype) { - Function.Lambda lambda = new Function.Lambda (node, this); + Function func; - functions[lambda.name] = lambda; - return lambda; + if (prototype || ! functions.TryGetValue (name, out func)) + { + func = new Function.Lambda (this, name, args_evalled, args); + functions[name] = func; + } + if (! prototype) + ((Function.Lambda) func).SetBody (body); } - public void Defun (Name name, Name[] args, bool args_evalled) + public void Defun (XmlNode node, bool prototype) { - Function func = new Function.Lambda (this, name, args, args_evalled) + Symbol name = node.Attributes[Nfname].Value; + Function func; + + if (prototype || ! functions.TryGetValue (name, out func)) + { + func = new Function.Lambda (this, node); + functions[name] = func; + } + if (! prototype) + ((Function.Lambda) func).SetBody (this, node); } - public void Defun (XmlNode node) + public void Defun (Function func) { - Name name = node.Attributes[Nfname].Value; - Function func; - - if (! functions.TryGetValue (name, out func)) - func = RegisterFunction (node); - ((Function.Lambda) func).SetBody (node, this); + functions[func.name] = func; } public Variable Defvar (XmlNode node) { - Name name = node.Attributes[0].Value; + Symbol name = node.Attributes[0].Value; String desc; Variable vari; @@ -711,7 +759,7 @@ namespace System.Xml.Expression desc = null; if (node != null) { - Name type = node.Name; + Symbol type = node.Name; XmlNodeList range_list = null; int nranges = 0; string val = node.InnerText; @@ -753,7 +801,7 @@ namespace System.Xml.Expression { if (! (vari is Variable.Int)) throw new Exception ("Inalid value"); - vari = vari.Clone (); + vari = (Variable) vari.Clone (); Term v = new Term (intval); vari.Value = v; vari.DefaultValue = v; @@ -777,7 +825,7 @@ namespace System.Xml.Expression { if (! (vari is Variable.Str)) throw new Exception ("Invalid value"); - vari = vari.Clone (); + vari = (Variable) vari.Clone (); Term v = new Term (val); vari.Value = v; vari.DefaultValue = v; @@ -789,10 +837,10 @@ namespace System.Xml.Expression } else if (type == Nsymbol) { - Name[] range = null; + Symbol[] range = null; if (range_list != null) { - range = new Name[nranges]; + range = new Symbol[nranges]; for (int i = 0; i < nranges; i++) range[i] = range_list[i].InnerText; } @@ -801,7 +849,7 @@ namespace System.Xml.Expression { if (! (vari is Variable.Sym)) throw new Exception ("Invalid value"); - vari = vari.Clone (); + vari = (Variable) vari.Clone (); Term v = new Term (val); vari.Value = v; vari.DefaultValue = v; @@ -817,7 +865,7 @@ namespace System.Xml.Expression else { if (variables.TryGetValue (name, out vari)) - vari = vari.Clone (); + vari = (Variable) vari.Clone (); else vari = new Variable (name, Zero); } @@ -831,14 +879,14 @@ namespace System.Xml.Expression return vari; } - internal Variable Defvar (Name name) + internal Variable Defvar (Symbol name) { Variable vari = new Variable (name, Zero); variables[name] = vari; return vari; } - internal Function GetFunc (Name name) + internal Function GetFunc (Symbol name) { Function func; @@ -847,7 +895,7 @@ namespace System.Xml.Expression return func; } - public bool CopyFunc (Domain domain, Name name) + public bool CopyFunc (Domain domain, Symbol name) { Function func = GetFunc (name); @@ -857,11 +905,11 @@ namespace System.Xml.Expression public void CopyFunc (Domain domain) { - foreach (KeyValuePair kv in functions) + foreach (KeyValuePair kv in functions) domain.functions[kv.Key] = kv.Value; } - public Variable GetVar (Name name, bool create) + public Variable GetVar (Symbol name, bool create) { Variable vari; @@ -877,10 +925,10 @@ namespace System.Xml.Expression public override string ToString () { string str = "<(functions"; - foreach (KeyValuePair kv in functions) + foreach (KeyValuePair kv in functions) str += " " + kv.Key; str += ") (variabls"; - foreach (KeyValuePair kv in variables) + foreach (KeyValuePair kv in variables) str += " " + kv.Key; str += ")"; if (bindings != null) @@ -904,6 +952,22 @@ namespace System.Xml.Expression Console.Write (fmt, arg); } } + + public object SaveValues () + { + Dictionary values = new Dictionary (); + + foreach (KeyValuePair kv in variables) + values[kv.Value] = kv.Value.val.Clone (); + return values; + } + + public void RestoreValues (object values) + { + foreach (KeyValuePair kv + in (Dictionary) values) + kv.Key.val = kv.Value; + } } public delegate Term Builtin (Domain domain, Variable vari, Term[] args); @@ -969,9 +1033,9 @@ namespace System.Xml.Expression int n = vari == null ? 0 : vari.val.Intval; foreach (Term arg in args) - n += (int) arg; + n += arg.Intval; if (vari == null) - return n; + return new Term (n); vari.val.intval = n; return vari.val; } @@ -980,9 +1044,9 @@ namespace System.Xml.Expression { int n = vari == null ? 1 : vari.val.Intval; foreach (Term arg in args) - n *= (int) arg; + n *= arg.Intval; if (vari == null) - return n; + return new Term (n); vari.val.intval = n; return vari.val; } @@ -1002,9 +1066,9 @@ namespace System.Xml.Expression i = 0; } while (i < args.Length) - n -= (int) args[i++]; + n -= args[i++].Intval; if (vari == null) - return n; + return new Term (n); vari.val.intval = n; return vari.val; } @@ -1026,7 +1090,7 @@ namespace System.Xml.Expression while (i < args.Length) n /= args[i++].Intval; if (vari == null) - return n; + return new Term (n); vari.val.intval = n; return vari.val; } @@ -1034,7 +1098,7 @@ namespace System.Xml.Expression private static Term Fmod (Domain domain, Variable vari, Term[] args) { if (vari == null) - return (args[0].Intval % args[1].Intval); + return new Term (args[0].Intval % args[1].Intval); vari.val.intval = vari.val.Intval % args[0].Intval; return vari.val; } @@ -1043,9 +1107,9 @@ namespace System.Xml.Expression { int n = vari == null ? 0 : vari.val.Intval; foreach (Term arg in args) - n |= (int) arg; + n |= arg.Intval; if (vari == null) - return n; + return new Term (n); vari.val.intval = n; return vari.val; } @@ -1065,9 +1129,9 @@ namespace System.Xml.Expression i = 0; } while (i < args.Length) - n &= (int) args[i++]; + n &= args[i++].Intval; if (vari == null) - return n; + return new Term (n); vari.val.intval = n; return vari.val; } @@ -1075,7 +1139,7 @@ namespace System.Xml.Expression private static Term Flsh (Domain domain, Variable vari, Term[] args) { if (vari == null) - return args[0].Intval << args[1].Intval; + return new Term (args[0].Intval << args[1].Intval); vari.val.intval = vari.val.Intval << args[0].Intval; return vari.val; } @@ -1083,7 +1147,7 @@ namespace System.Xml.Expression private static Term Frsh (Domain domain, Variable vari, Term[] args) { if (vari == null) - return args[0].Intval >> args[1].Intval; + return new Term (args[0].Intval >> args[1].Intval); vari.val.intval = vari.val.Intval >> args[0].Intval; return vari.val; } @@ -1114,11 +1178,11 @@ namespace System.Xml.Expression private static Term Flt (Domain domain, Variable vari, Term[] args) { - int n = (int) args[0]; + int n = args[0].Intval; for (int i = 1; i < args.Length; i++) { - int n1 = (int) args[i]; + int n1 = args[i].Intval; if (n >= n1) return Zero; n = n1; @@ -1128,10 +1192,10 @@ namespace System.Xml.Expression private static Term Fle (Domain domain, Variable vari, Term[] args) { - int n = (int) args[0]; + int n = args[0].Intval; for (int i = 1; i < args.Length; i++) { - int n1 = (int) args[i]; + int n1 = args[i].Intval; if (n > n1) return Zero; n = n1; @@ -1141,10 +1205,10 @@ namespace System.Xml.Expression private static Term Fgt (Domain domain, Variable vari, Term[] args) { - int n = (int) args[0]; + int n = args[0].Intval; for (int i = 1; i < args.Length; i++) { - int n1 = (int) args[i]; + int n1 = args[i].Intval; if (n <= n1) return Zero; n = n1; @@ -1154,10 +1218,10 @@ namespace System.Xml.Expression private static Term Fge (Domain domain, Variable vari, Term[] args) { - int n = (int) args[0]; + int n = args[0].Intval; for (int i = 1; i < args.Length; i++) { - int n1 = (int) args[i]; + int n1 = args[i].Intval; if (n < n1) return Zero; n = n1; @@ -1431,8 +1495,8 @@ namespace System.Xml.Expression return TermInt; if (args[0].IsStr) return TermStr; - if (args[0].IsName) - return TermName; + if (args[0].IsSymbol) + return TermSymbol; if (args[0].IsList) return TermList; return TermTerm; @@ -1442,7 +1506,7 @@ namespace System.Xml.Expression { Term result = Zero; try { - domain.Catch (new CatchTag (args[0].Nameval)); + domain.Catch (new CatchTag (args[0].Symval)); result = args[1].Eval (domain); } finally { domain.Uncatch (); @@ -1452,13 +1516,14 @@ namespace System.Xml.Expression public static Term Fthrow (Domain domain, Variable vari, Term[] args) { - domain.ThrowTag (new CatchTag (args[0].Nameval)); + domain.ThrowTag (new CatchTag (args[0].Symval)); return (args.Length == 1 ? Zero : args[1]); } - public class TermValue + public abstract class TermValue { public virtual Term Eval (Domain domain) { return new Term (this); } + public abstract TermValue Clone (); } private class Funcall : TermValue @@ -1467,10 +1532,17 @@ namespace System.Xml.Expression internal Variable vari; internal Term[] args; + private Funcall (Function func, Variable vari, Term[] args) + { + this.func = func; + this.vari = vari; + this.args = args; + } + public Funcall (XmlNode node, Domain domain) { vari = null; - Name name = node.Name; + Symbol name = node.Name; if (name == Nfuncall) name = node.Attributes[0].Value; @@ -1489,13 +1561,13 @@ namespace System.Xml.Expression args[i] = new Term (nlist[i], domain); } - public Funcall (Domain domain, Name fname, Term[] args) + public Funcall (Domain domain, Symbol fname, Term[] args) { func = domain.GetFunc (fname); this.args = args; } - public Funcall (Domain domain, Name fname, Name vname, Term[] args) + public Funcall (Domain domain, Symbol fname, Symbol vname, Term[] args) { func = domain.GetFunc (fname); vari = domain.GetVar (vname, true); @@ -1515,6 +1587,11 @@ namespace System.Xml.Expression return result; } + public override TermValue Clone () + { + return new Funcall (func, vari, args); + } + public override string ToString () { string str = " list) { intval = 0; objval = list; } public Term (Term term) { intval = term.intval; objval = term.objval; } @@ -1541,7 +1618,7 @@ namespace System.Xml.Expression public Term (XmlNode node, Domain domain) { - Name name = node.Name; + Symbol name = node.Name; if (name == Ninteger) { @@ -1552,11 +1629,11 @@ namespace System.Xml.Expression { intval = 0; if (name == Nsymbol) - objval = (Name) node.InnerText; + objval = (Symbol) node.InnerText; else if (name == Nstring) objval = node.InnerText.Clone (); else if (name == Nvarref) - objval = domain.GetVar ((Name) node.Attributes[0].Value, true); + objval = domain.GetVar ((Symbol) node.Attributes[0].Value, true); else if (name == Nlist) { List list = new List (); @@ -1570,6 +1647,18 @@ namespace System.Xml.Expression } } + public Term (Domain domain, Symbol fname, Term[] args) + { + intval = 0; + objval = new Funcall (domain, fname, args); + } + + public Term (Domain domain, Symbol fname, Symbol vname, Term[] args) + { + intval = 0; + objval = new Funcall (domain, fname, vname, args); + } + public object Objval { get { if (objval == null) @@ -1594,11 +1683,11 @@ namespace System.Xml.Expression } } - public string Nameval { + public string Symval { get { - if (! IsName) + if (! IsSymbol) throw new Exception ("term is not symbol: " + this); - return (Name) objval; + return (Symbol) objval; } } @@ -1621,7 +1710,7 @@ namespace System.Xml.Expression } public bool IsInt { get { return (objval == null); } } public bool IsStr { get { return (objval is string); } } - public bool IsName { get { return (objval is Name); } } + public bool IsSymbol { get { return (objval is Symbol); } } public bool IsList { get { return (objval is List); } } public bool IsType (Type type) @@ -1632,30 +1721,24 @@ namespace System.Xml.Expression public Term Eval (Domain domain) { - if (objval == null || objval is Name || objval is string) + if (objval == null || objval is Symbol || objval is string) return this; if (objval is List) return new Term ((List) objval); - if (objval is TermValue) - return ((TermValue) objval).Eval (domain); - throw new Exception ("invalid Term object: " + objval); + return ((TermValue) objval).Eval (domain); } - public static explicit operator int (Term term) + public Term Clone () { - if (term.objval != null) - throw new Exception ("Not an integer term: " + term); - return term.intval; - } - - public static explicit operator Name (Term term) - { - return (Name) term.objval; - } - - public static implicit operator Term (int i) - { - return new Term (i); + if (objval == null || objval is Symbol || objval is string) + return this; + if (objval is List) + { + List list = new List (); + list.InsertRange (0, ((List) objval)); + return new Term (list); + } + return new Term (((TermValue) objval).Clone ()); } public override string ToString () @@ -1664,7 +1747,7 @@ namespace System.Xml.Expression if (objval == null) str = "" + intval + ""; - else if (objval is Name) + else if (objval is Symbol) str = "" + objval + ""; else if (objval is string) str = "" + objval + ""; @@ -1691,9 +1774,9 @@ namespace System.Xml.Expression static private Term One = new Term (1); static private Term TermInt = new Term (Ninteger); static private Term TermStr = new Term (Nstring); - static private Term TermName = new Term (Nsymbol); + static private Term TermSymbol = new Term (Nsymbol); static private Term TermList = new Term (Nlist); - static private Term TermTerm = new Term ((Name) "term"); + static private Term TermTerm = new Term ((Symbol) "term"); internal static int parse_integer (string str) { @@ -1753,7 +1836,7 @@ namespace System.Xml.Expression if (n.NodeType == XmlNodeType.Element) { if (n.Name == Ndefun) - domain.RegisterFunction (n); + domain.Defun (n, true); else if (n.Name == Ndefvar) domain.Defvar (n); else @@ -1766,7 +1849,7 @@ namespace System.Xml.Expression if (n.NodeType == XmlNodeType.Element) { if (n.Name == Ndefun) - domain.Defun (n); + domain.Defun (n, false); else if (n.Name != Ndefvar) terms[i++]= new Term (n, domain); } @@ -1779,10 +1862,10 @@ namespace System.Xml.Expression public Xexpression (Domain domain, string url) { - XmlDocument doc = new XmlDocument (Name.Table); + XmlDocument doc = new XmlDocument (Symbol.Table); XmlNode node; - using (XmlTextReader reader = new XmlTextReader (url, Name.Table)) + using (XmlTextReader reader = new XmlTextReader (url, Symbol.Table)) { do { reader.Read (); diff --git a/input.cs b/input.cs index 4871598..465fe64 100644 --- a/input.cs +++ b/input.cs @@ -2,9 +2,11 @@ using System; using System.Collections.Generic; using System.IO; using System.Xml; +using System.Xml.Expression; using M17N; using M17N.Core; using M17N.Input; +using Xex = System.Xml.Expression.Xexpression; public class Test { @@ -13,7 +15,7 @@ public class Test //M17n.debug = true; MDatabase.ApplicationDir = "/usr/local/share/m17n-xml"; MText desc, title; - MInputMethod.Variable[] vars; + Xex.Variable[] vars; MInputMethod.Command[] cmds; #if false diff --git a/xex.xml b/xex.xml index 47115fa..476c1ed 100644 --- a/xex.xml +++ b/xex.xml @@ -68,4 +68,13 @@ ?a?b 1 + 0 + + k + a + 1 + 4 + broken + +