X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=MInputMethod.cs;h=8b2e7f828ed6746ea9fa173f709e70d308d46ec5;hb=093302f7036acd5f1782a4867b87ee8df1972479;hp=8bd03c43ed36973ea3b6133483f93a8f90951b9f;hpb=f5543e0aaf8f077fd584cbbdeaa7be8936269aa0;p=m17n%2Fm17n-lib-cs.git diff --git a/MInputMethod.cs b/MInputMethod.cs index 8bd03c4..8b2e7f8 100644 --- a/MInputMethod.cs +++ b/MInputMethod.cs @@ -352,6 +352,9 @@ namespace M17N.Input internal class KeySeq : Xex.TermValue { + private static Xex.Symbol name = "keyseq"; + public static Xex.Symbol Name { get { return name; } } + public List keyseq = new List (); public override Xex.TermValue Clone () @@ -393,7 +396,7 @@ namespace M17N.Input if (list[i].IsInt) keyseq.Add (new Key (list[i].Intval)); else if (list[i].IsStr) - keyseq.Add (new Key (list[i].Strval)); + keyseq.Add (new Key (list[i].Strval.ToString ())); else if (list[i].IsSymbol) keyseq.Add (new Key ((string) list[i].Symval)); else @@ -401,13 +404,33 @@ namespace M17N.Input } } - public static Xex.TermValue parser (Xex.Domain domain, XmlNode node) + public static Xex.TermValue Parser (Xex.Domain domain, XmlNode node) { - Xex.Term term = new Xex.Term (domain, node.FirstChild).Eval (domain); - return (term.IsStr ? new KeySeq ((MText) term.Strval) + Xex.Term term = Xex.Parse (domain, node.FirstChild); + term = Xex.Eval (domain, term); + return (term.IsStr ? new KeySeq ((MText) term.Strval.ToString ()) : new KeySeq (term.Listval)); } + public override bool Equals (object obj) + { + KeySeq ks = obj as KeySeq; + if (ks == null || ks.keyseq.Count != keyseq.Count) + return false; + for (int i = 0; i < keyseq.Count; i++) + if (keyseq[i] != ks.keyseq[i]) + return false; + return true; + } + + public override int GetHashCode () + { + int code = 0; + for (int i = 0; i < keyseq.Count; i++) + code ^= keyseq[i].GetHashCode (); + return code; + } + public override string ToString () { MText mt; @@ -468,7 +491,7 @@ namespace M17N.Input if (node.Name == "description") description = parse_description (node); else if (node.Name == "keyseq") - keys.Add ((KeySeq) KeySeq.parser (null, node)); + keys.Add ((KeySeq) KeySeq.Parser (null, node)); } } @@ -519,7 +542,7 @@ namespace M17N.Input object[] parameters = new object[2]; public PluginMethod (Plugin plugin, string name) - : base ((Xex.Symbol) name, 0, -1) + : base ((Xex.Symbol) name, false, 0, -1) { this.plugin = plugin; } @@ -530,8 +553,8 @@ namespace M17N.Input args = (Xex.Term[]) args.Clone (); for (int i = 0; i < args.Length; i++) { - args[i] = args[i].Eval (domain); - if (domain.Thrown) + args[i] = Xex.Eval (domain, args[i]); + if (domain.Thrown ()) return args[i]; } if (method_info == null) @@ -544,18 +567,21 @@ namespace M17N.Input internal abstract class Marker : Xex.TermValue { - private MSymbol name; + private static Xex.Symbol name = "marker"; + public static Xex.Symbol Name { get { return name; } } + + private MSymbol mname; - private Marker (MSymbol name) + private Marker (MSymbol mname) { - this.name = name; + this.mname = mname; } public abstract int Position (Context ic); public virtual void Mark (Context ic) { - throw new Exception ("Can't set predefined marker: " + name); + throw new Exception ("Can't set predefined marker: " + mname); } public virtual int CharAt (Context ic) { @@ -567,27 +593,36 @@ namespace M17N.Input public override string ToString () { - return "" + name.Name + ""; + return "" + mname + ""; } - public static Xex.TermValue parser (Xex.Domain domain, XmlNode node) + public static Xex.TermValue Parser (Xex.Domain domain, XmlNode node) { return Get ((MSymbol) node.InnerText); } + + public override bool Equals (object obj) + { + Marker m = obj as Marker; + return (m != null && m.mname == mname); + } + + public override int GetHashCode () { return mname.GetHashCode (); } + public class Named : Marker { - public Named (MSymbol name) : base (name) { } + public Named (MSymbol mname) : base (mname) { } public override int Position (Context ic) { - MPlist p = ic.marker_positions.Find (name); + MPlist p = ic.marker_positions.Find (mname); return (p == null ? 0 : p.Integer); } public override void Mark (Context ic) { - ic.marker_positions.Put (name, ic.cursor_pos); + ic.marker_positions.Put (mname, ic.cursor_pos); } } @@ -632,10 +667,10 @@ namespace M17N.Input { private int pos; - public PredefinedAbsolute (MSymbol name) : base (name) + public PredefinedAbsolute (MSymbol mname) : base (mname) { - if (! int.TryParse (((string) name).Substring (1), out pos)) - throw new Exception ("Invalid marker name: " + name); + if (! int.TryParse (((string) mname).Substring (1), out pos)) + throw new Exception ("Invalid marker name: " + mname); } public override int Position (Context ic) @@ -648,10 +683,10 @@ namespace M17N.Input { private int distance; - public PredefinedSurround (MSymbol name) : base (name) + public PredefinedSurround (MSymbol mname) : base (mname) { if (! int.TryParse (((string) name).Substring (1), out distance)) - throw new Exception ("Invalid marker name: " + name); + throw new Exception ("Invalid marker name: " + mname); if (distance > 0) distance--; } @@ -687,24 +722,24 @@ namespace M17N.Input = new Predefined (']'); } - public static Marker Get (MSymbol name) + public static Marker Get (MSymbol mname) { - string str = name.Name; + string str = mname.Name; if (str[0] == '@') { Predefined pred; - if (predefineds.TryGetValue (name, out pred)) + if (predefineds.TryGetValue (mname, out pred)) return pred; if (str.Length == 1) - throw new Exception ("Invalid marker name: " + name); + throw new Exception ("Invalid marker name: " + mname); if (Char.IsDigit (str[1])) - return new PredefinedAbsolute (name); - if (str.Length == 2 || name == Mat_minus_zero + return new PredefinedAbsolute (mname); + if (str.Length == 2 || mname == Mat_minus_zero || ! (str[1] == '-' || str[1] == '+')) - throw new Exception ("Invalid marker name: " + name); - return new PredefinedSurround (name); + throw new Exception ("Invalid marker name: " + mname); + return new PredefinedSurround (mname); } - return new Named (name); + return new Named (mname); } } @@ -719,13 +754,13 @@ namespace M17N.Input { Index = index; if (term.IsStr) - Data = (MText) term.Strval; + Data = (MText) term.Strval.ToString (); else { MPlist plist = new MPlist (); MPlist p = plist; foreach (Xex.Term t in term.Listval) - p = p.Add (MSymbol.mtext, (MText) t.Strval); + p = p.Add (MSymbol.mtext, (MText) t.Strval.ToString ()); Data = plist; } } @@ -992,6 +1027,9 @@ namespace M17N.Input internal class Selector : Xex.TermValue { + private static Xex.Symbol name = "selector"; + public static Xex.Symbol Name { get { return name; } } + static new Dictionary selectors; static Selector () @@ -1014,7 +1052,7 @@ namespace M17N.Input private Selector (char tag) { this.tag = tag; } - public static Xex.TermValue parser (Xex.Domain domain, XmlNode node) + public static Xex.TermValue Parser (Xex.Domain domain, XmlNode node) { return Get ((MSymbol) node.InnerText); } @@ -1026,6 +1064,19 @@ namespace M17N.Input throw new Exception ("Invalid selector name: " + name); return selector; } + + public override bool Equals (object obj) + { + Selector s = obj as Selector; + return (s != null && s.tag == tag); + } + + public override int GetHashCode () { return (int) tag; } + + public override string ToString () + { + return "@" + tag + ""; + } } internal class Map @@ -1056,6 +1107,31 @@ namespace M17N.Input } } + protected class Action + { + private Xex.Term action; + + public Action (Xex.Domain domain, Xex.Term[] terms) + { + Xex.Term[] args = new Xex.Term[terms.Length]; + args[0] = Tcatch_tag; + for (int i = 0; i < terms.Length; i++) + args[i + 1] = terms[i]; + action = new Xex.Term (domain, Qcatch, args); + } + + public bool Run (Xex.Domain domain) + { + Xex.Term result = Xex.Eval (domain, action); + if (result.IsError) + { + ((Context) domain.context).Error = result.ToString (); + return false; + } + return (result != Tcatch_tag); + } + } + internal class Keymap { public Dictionary submaps; @@ -1165,16 +1241,16 @@ namespace M17N.Input for (node = node.FirstChild; node != null; node = node.NextSibling) { if (node.Name == Qstate_hook) - enter_actions = Xex.ParseTerms (im.domain, node.FirstChild); + enter_actions = Xex.Parse (im.domain, node.FirstChild, null); else if (node.Name == Qcatch_all_branch) - fallback_actions = Xex.ParseTerms (im.domain, node.FirstChild); + fallback_actions = Xex.Parse (im.domain, node.FirstChild, null); else if (node.Name == Qbranch) { MSymbol mapname = node.Attributes[Qmname].Value; Map map; if (im.maps.TryGetValue (mapname, out map)) - keymap.AddMap (map, Xex.ParseTerms (im.domain, - node.FirstChild)); + keymap.AddMap (map, Xex.Parse (im.domain, node.FirstChild, + null)); else throw new Exception ("Unknown map: " + mapname); } @@ -1246,9 +1322,9 @@ namespace M17N.Input static MInputMethod () { - im_domain.DefTerm ("keyseq", KeySeq.parser); - im_domain.DefTerm ("marker", Marker.parser); - im_domain.DefTerm ("selector", Selector.parser); + im_domain.DefType (typeof (KeySeq)); + im_domain.DefType (typeof (Marker)); + im_domain.DefType (typeof (Selector)); im_domain.DefSubr (Finsert, "insert", false, 1, 1); im_domain.DefSubr (Finsert_candidates, "insert-candidates", false, 1, -1); @@ -1312,7 +1388,7 @@ namespace M17N.Input variables = new Xex.Variable[var_names.Length]; int i = 0; foreach (Xex.Symbol name in var_names) - variables[i++] = domain.GetVar (name, false); + variables[i++] = domain.GetVar (name); } commands = this.commands; return true; @@ -1543,7 +1619,7 @@ namespace M17N.Input if (! im_global.Open ()) throw new Exception ("Failed to load global"); } - return im_global.domain.GetVar (name, false); + return im_global.domain.GetVar (name); } private void parse_variables (MPlist plist) @@ -1651,7 +1727,7 @@ namespace M17N.Input Xex.Variable vari = get_global_var (name); if (vari != null) domain.Defvar (vari); - domain.Defvar (node_list[i]); + Xex.Parse (domain, node_list[i]); var_names[i] = name; } } @@ -1739,17 +1815,13 @@ namespace M17N.Input private void parse_macros (XmlNode node) { for (XmlNode nn = node.FirstChild; nn != null; nn = nn.NextSibling) - if (nn.NodeType == XmlNodeType.Element) - { - if (nn.Name == Xex.Qdefun) - domain.Defun (nn, true); - else if (nn.Name == Qxi_include) + if (nn.NodeType == XmlNodeType.Element && nn.Name == Qxi_include) + { parse_include (nn); - } - for (XmlNode nn = node.FirstChild; nn != null; nn = nn.NextSibling) - if (nn.NodeType == XmlNodeType.Element - && nn.Name == Xex.Qdefun) - domain.Defun (nn, false); + nn = nn.PreviousSibling; + node.RemoveChild (nn.NextSibling); + } + Xex.Parse (domain, node.FirstChild, null); } private void parse_maps (XmlNode node) @@ -1768,8 +1840,9 @@ namespace M17N.Input XmlNode n = nd.FirstChild; if (n.Name != Qkeyseq) continue; - KeySeq keyseq = (KeySeq) KeySeq.parser (domain, n); - Xex.Term[] actions = Xex.ParseTerms (domain, n.NextSibling); + KeySeq keyseq = (KeySeq) KeySeq.Parser (domain, n); + n = n.NextSibling; + Xex.Term[] actions = Xex.Parse (domain, n, null); map.entries.Add (new Map.Entry (domain, keyseq, actions)); } } @@ -2065,17 +2138,16 @@ namespace M17N.Input MPlist p = pl.Plist; if (! p.IsSymbol) continue; - domain.Defun ((Xex.Symbol) p.Symbol.Name, null, null, true); + domain.Defun ((Xex.Symbol) p.Symbol.Name, 0, 0, null, null); } for (MPlist pl = plist; ! pl.IsEmpty; pl = pl.next) if (pl.IsPlist) { MPlist p = pl.Plist; - if (! p.IsSymbol) continue; - domain.Defun ((Xex.Symbol) p.Symbol.Name, null, - parse_actions (p.next, false), false); + domain.Defun ((Xex.Symbol) p.Symbol.Name, 0, 0, null, + parse_actions (p.next, false)); } } @@ -2116,7 +2188,8 @@ namespace M17N.Input if (args[0].IsInt) ((Context) domain.context).insert (args[0].Intval, null); else - ((Context) domain.context).insert ((MText) args[0].Strval, null); + ((Context) domain.context).insert ((MText) args[0].Strval.ToString (), + null); return args[0]; } @@ -2125,8 +2198,8 @@ namespace M17N.Input Xex.Term[] args) { Context ic = (Context) domain.context; - Xex.Variable v = ic.domain.GetVar (Qcandidates_group_size, false); - int column = (v == null ? 0 : v.Value.Intval); + Xex.Variable v = ic.domain.GetVar (Qcandidates_group_size); + int column = v == null ? 0 : v.Value.Intval; Candidates candidates = new Candidates (args, column); object candidate = candidates.Current; @@ -2228,7 +2301,7 @@ namespace M17N.Input if (args[0].IsInt) ic.pushback (args[0].Intval); else if (args[0].IsStr) - ic.pushback (new KeySeq (args[0].Strval)); + ic.pushback (new KeySeq (args[0].Strval.ToString ())); else ic.pushback ((KeySeq) args[0].Objval); return args[0]; @@ -2260,9 +2333,7 @@ namespace M17N.Input Xex.Term[] args) { ((Context) domain.context).commit (); - args = new Xex.Term[2]; - args[0] = args[1] = Tcatch_tag; - return Xex.Fthrow (domain, vari, args); + return Xex.Fthrow (domain, vari, new Xex.Term[1] { Tcatch_tag }); } private static Xex.Term Fshift (Xex.Domain domain, Xex.Variable vari, @@ -2379,6 +2450,12 @@ namespace M17N.Input internal ChangedStatus changed; + private string error_message; + public string Error { + get { return error_message; } + set { error_message = value; } + } + private void set_cursor (string prefix, int pos) { cursor_pos = pos; @@ -2419,7 +2496,7 @@ namespace M17N.Input catch_args[0] = Tcatch_tag; catch_args[1]= new Xex.Term (domain, Qprogn, actions); Xex.Term term = new Xex.Term (domain, Qcatch, catch_args); - term = term.Eval (domain); + term = Xex.Eval (domain, term); return (! term.IsSymbol || term.Symval != Tcatch_tag.Symval); } @@ -2680,7 +2757,7 @@ namespace M17N.Input { if (im.load_status != LoadStatus.Full && ! im.Open ()) - throw new Exception ("Openging " + im.tag + " failed"); + throw new Exception ("Opening " + im.tag + " failed"); this.im = im; domain = new Xex.Domain ("context", im.domain, this); initial_state = (State) im.states.Val;