From 4aefe2227f419cc664c8a27eeb5babb382778162 Mon Sep 17 00:00:00 2001 From: handa Date: Wed, 7 Oct 2009 05:24:49 +0000 Subject: [PATCH] *** empty log message *** --- MInputMethod.cs | 329 ++++++++++++++++++++++++++++++++++--------------------- XmlExpr.cs | 120 ++++++++++---------- 2 files changed, 265 insertions(+), 184 deletions(-) diff --git a/MInputMethod.cs b/MInputMethod.cs index f92e302..717cccf 100644 --- a/MInputMethod.cs +++ b/MInputMethod.cs @@ -64,13 +64,21 @@ namespace M17N.Input private static MSymbol Mat_minus_zero = "@-0"; - private static Xex.Symbol Nmap = "map"; - private static Xex.Symbol Nrule = "rule"; - private static Xex.Symbol Nkeyseq = "keyseq"; - private static Xex.Symbol Nprogn = "progn"; - private static Xex.Symbol Ninsert = "insert"; - private static Xex.Symbol Ninsert_candidates = "insert-candidates"; - private static Xex.Symbol Nchar_at = "char-at"; + private static Xex.Symbol Qmap = "map"; + private static Xex.Symbol Qrule = "rule"; + private static Xex.Symbol Qkeyseq = "keyseq"; + private static Xex.Symbol Qprogn = "progn"; + private static Xex.Symbol Qinsert = "insert"; + private static Xex.Symbol Qinsert_candidates = "insert-candidates"; + private static Xex.Symbol Qchar_at = "char-at"; + private static Xex.Symbol Qsname = "sname"; + private static Xex.Symbol Qmname = "mname"; + private static Xex.Symbol Qstate_hook = "state-hook"; + private static Xex.Symbol Qcatch_all_branch = "catch-all-branch"; + private static Xex.Symbol Qbranch = "branch"; + private static Xex.Symbol Qstate = "state"; + private static Xex.Symbol Qtitle = "title"; + private static Xex.Term Tnil = new Xex.Term ((Xex.Symbol) "nil"); private static Xex.Term Tcatch_tag = new Xex.Term ((Xex.Symbol) "@mimtag"); @@ -307,6 +315,11 @@ namespace M17N.Input && ((m1 & KeyModifier.High) == (m2 & KeyModifier.High))); } + public int ToChar () + { + return key & 0x1FFFFF; + } + public override string ToString () { string str = Char.ToString ((char) key); @@ -936,8 +949,8 @@ namespace M17N.Input selectors["@last"] = new Selector ('>'); selectors["@previous"] = new Selector ('-'); selectors["@next"] = new Selector ('+'); - selectors["@previous-candidate-list"] = new Selector ('['); - selectors["@next-candidate-list"] = new Selector (']'); + selectors["@previous-candidate-change"] = new Selector ('['); + selectors["@next-candidate-change"] = new Selector (']'); } private char tag; @@ -996,74 +1009,73 @@ namespace M17N.Input } } - internal class Branch + internal class Keymap { - public MSymbol name; - public Keymap keymap; - public Xex.Term[] enter_actions, fallback_actions; - } + public Dictionary submaps; + public Xex.Term[] map_actions, branch_actions; - public class Keymap - { - public Dictionary keymaps; - public Xex.Term[] map_actions, branch_actions; + public Keymap () { } - public void Add (KeySeq keys, int index, - Xex.Term[] map_actions, Xex.Term[] branch_actions) - { - Map sub = null; + public void Add (KeySeq keys, int index, + Xex.Term[] map_actions, Xex.Term[] branch_actions) + { + if (index == keys.keyseq.Count) + { + this.map_actions = map_actions; + this.branch_actions = branch_actions; + } + else + { + Key key = keys.keyseq[index]; + Keymap sub = null; - if (submaps == null) - submaps = new Dictionary (); - else - submaps.TryGetValue (keys.keyseq[index], out sub); - if (sub == null) - { - Key key = keys.keyseq[index]; - submaps[key] = sub = new Map (); - } - if (index + 1 < keys.keyseq.Count) - sub.Add (keys, index + 1, actions); - else - this.actions = actions; - } + if (submaps == null) + submaps = new Dictionary (); + else + submaps.TryGetValue (key, out sub); + if (sub == null) + submaps[key] = sub = new Keymap (); + sub.Add (keys, index + 1, map_actions, branch_actions); + } } - public void AddMap (Map map, Xex.Term[] actions) + public void AddMap (Map map, Xex.Term[] branch_actions) { foreach (Map.Entry entry in map.entries) - { - Add (entry.keyseq, 0, entry.actions, actions) - } + Add (entry.keyseq, 0, entry.actions, branch_actions); } - public void Add (KeySeq keys, int index, - Xex.Term[] map_actions, Xex.Term[] branch_actions) - public Xex.Term Lookup (KeySeq keys, ref int index) + public Keymap Lookup (KeySeq keys, ref int index) { - if (index < keys.keyseq.Count) + Keymap sub; + + if (index < keys.keyseq.Count + && submaps != null + && submaps.TryGetValue (keys.keyseq[index], out sub)) { - Map sub; - if (submaps.TryGetValue (keys.keyseq[index], out sub)) - { - index++; - return sub.Lookup (keys, ref index); - } - return Tnil; + index++; + return sub.Lookup (keys, ref index); } - return actions; + return this; } private void describe (MText mt, KeySeq keyseq) { - if (keyseq.keyseq.Count > 0) + if (map_actions != null || branch_actions != null) { - mt.Cat (" (").Cat (keyseq.ToString ()); - mt.Cat (' ').Cat (actions.ToString ()); + if (mt.Length > 0) + mt.Cat (" "); + mt.Cat ('(').Cat (keyseq.ToString ()); + if (map_actions != null) + foreach (Xex.Term term in map_actions) + mt.Cat (' ').Cat (term.ToString ()); + if (branch_actions != null) + foreach (Xex.Term term in branch_actions) + mt.Cat (' ').Cat (term.ToString ()); mt.Cat (')'); } if (submaps != null) - foreach (KeyValuePair kv in submaps) + foreach (KeyValuePair kv in submaps) { keyseq.keyseq.Add (kv.Key); kv.Value.describe (mt, keyseq); @@ -1073,7 +1085,7 @@ namespace M17N.Input public override string ToString () { - MText mt = "(" + name.Name; + MText mt = ""; KeySeq keyseq = new KeySeq (); describe (mt, keyseq); @@ -1086,11 +1098,74 @@ namespace M17N.Input { public Xex.Symbol name; public MText title; - public MPlist branches = new MPlist (); + public Xex.Term[] enter_actions, fallback_actions; + public Keymap keymap; - public State (Xex.Symbol name) + public State (Xex.Symbol name, MText title) { this.name = name; + this.title = title; + } + + public State (MInputMethod im, XmlNode node) + { + this.name = node.Attributes[Qsname].Value; + XmlAttribute attr = node.Attributes[Qtitle]; + if (attr != null) + title = (MText) attr.Value; + keymap = new Keymap (); + for (node = node.FirstChild; node != null; node = node.NextSibling) + { + if (node.Name == Qstate_hook) + enter_actions = Xex.ParseTerms (im.domain, node.FirstChild); + else if (node.Name == Qcatch_all_branch) + fallback_actions = Xex.ParseTerms (im.domain, node.FirstChild); + 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)); + else + throw new Exception ("Unknown map: " + mapname); + } + } + } + + public State (MInputMethod im, MPlist plist) + { + if (! plist.IsSymbol) + throw new Exception ("Invalid state: " + plist); + this.name = plist.Symbol.Name; + plist = plist.next; + if (plist.IsMText) + { + this.title = plist.Text; + plist = plist.next; + } + keymap = new Keymap (); + for (; ! plist.IsEmpty; plist = plist.next) + { + if (! plist.IsPlist) + throw new Exception ("Invalid branch: " + plist); + MPlist p = plist.Plist; + if (! p.IsSymbol) + throw new Exception ("Invalid branch: " + p); + MSymbol mapname = p.Symbol; + if (mapname == MSymbol.t) + enter_actions = im.parse_actions (p.next); + else if (mapname == MSymbol.nil) + fallback_actions = im.parse_actions (p.next); + else + { + Map map; + if (im.maps.TryGetValue (mapname, out map)) + keymap.AddMap (map, im.parse_actions (p.next)); + else + throw new Exception ("Unknown map: " + mapname); + } + } } public override string ToString () @@ -1099,8 +1174,7 @@ namespace M17N.Input if (title != null) mt.Cat (" \"" + title + "\""); - for (MPlist p = branches; ! p.IsEmpty; p = p.next) - mt.Cat (" (" + p.Key + " " + (Xex) p.Val + ")"); + mt += keymap.ToString (); return (string) mt + ")"; } } @@ -1272,11 +1346,11 @@ namespace M17N.Input private void add_default_state () { - Xex.Symbol Ninit = "init"; - State state = new State (Ninit); + Xex.Symbol Qinit = "init"; + State state = new State (Qinit, null); foreach (KeyValuePairkv in maps) - state.branches.Add (kv.Key, null); - states[Ninit] = initial_state = state; + state.keymap.AddMap (kv.Value, null); + states[Qinit] = initial_state = state; } private void load (MPlist plist, bool full) @@ -1754,16 +1828,16 @@ namespace M17N.Input private void parse_maps (XmlNode node) { for (node = node.FirstChild; node != null; node = node.NextSibling) - if (node.Name == Nmap) + 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 == Nrule) + if (nd.Name == Qrule) { XmlNode n = nd.FirstChild; - if (n.Name != Nkeyseq) + if (n.Name != Qkeyseq) continue; KeySeq keyseq = (KeySeq) KeySeq.parser (domain, n); Xex.Term[] actions = Xex.ParseTerms (domain, n.NextSibling); @@ -1772,8 +1846,24 @@ namespace M17N.Input } } + private void parse_states (MPlist plist) + { + for (; ! plist.IsEmpty; plist = plist.next) + if (plist.IsPlist) + { + State state = new State (this, plist.Plist); + states[state.name] = state; + } + } + 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; + } } private void parse_include (MPlist plist) @@ -1895,13 +1985,13 @@ namespace M17N.Input else throw new Exception ("Invalid candidates: " + pl); } - return new Xex.Term (domain, Ninsert_candidates, args); + return new Xex.Term (domain, Qinsert_candidates, args); } else throw new Exception ("Invalid arg to insert: " + plist); args = new Xex.Term[1]; args[0] = arg; - return new Xex.Term (domain, Ninsert, args); + return new Xex.Term (domain, Qinsert, args); } private Xex.Term parse_select (MPlist plist) @@ -1934,7 +2024,7 @@ namespace M17N.Input { Xex.Term[] args = new Xex.Term[1]; args[0] = new Xex.Term (Marker.Get (name)); - return new Xex.Term (domain, Nchar_at, args); + return new Xex.Term (domain, Qchar_at, args); } private Xex.Term parse_action (MPlist plist) @@ -2043,43 +2133,6 @@ namespace M17N.Input } } - private void parse_states (MPlist plist) - { - for (; ! plist.IsEmpty; plist = plist.next) - if (plist.IsPlist) - { - MPlist pl = plist.Plist; - MText title = null; - - if (pl.IsMText) - { - title = pl.Text; - pl = pl.next; - } - if (! pl.IsSymbol) - continue; - - Xex.Symbol name = (Xex.Symbol) pl.Symbol.Name; - State state = new State (name); - state.title = title; - if (states.Count == 0) - initial_state = state; - states[name] = state; - for (pl = pl.next; ! pl.IsEmpty; pl = pl.next) - { - if (! pl.IsPlist) - continue; - MPlist p = pl.Plist; - if (! p.IsSymbol) - continue; - MSymbol map_name = p.Symbol; - p = p.next; - Xex.Term term = new Xex.Term (domain, Nprogn, parse_actions (p)); - state.branches.Add (map_name, term); - } - } - } - private static Xex.Term Finsert (Xex.Domain domain, Xex.Variable vari, Xex.Term[] args) { @@ -2264,7 +2317,7 @@ namespace M17N.Input public class Context { - internal static Xex.Symbol Ncandidates_group_size + internal static Xex.Symbol Qcandidates_group_size = "candidates-group-size"; private MInputMethod im; private Dictionary callbacks @@ -2280,10 +2333,11 @@ namespace M17N.Input private int candidate_from, candidate_to; private bool candidate_show; - private List state_list; + private List state_list = new List state_list (); + private Keymap keymap; // Sequence of input keys. - internal KeySeq keys; + internal KeySeq keys = new KeySeq (); // Index into KEYS specifying the next key to handle. internal int key_head; @@ -2421,7 +2475,7 @@ namespace M17N.Input internal void insert_candidates (Xex.Term arg) { int column = 0; - Xex.Variable v = domain.GetVar (Ncandidates_group_size, false); + Xex.Variable v = domain.GetVar (Qcandidates_group_size, false); if (v != null) column = v.Value.Intval; @@ -2635,9 +2689,7 @@ namespace M17N.Input if (status == null) status = im.title; this.changed |= ChangedStatus.StateTitle; - Xex on_entry - = (Xex) state.branches.Get (MSymbol.t); - if (on_entry != null) + if (state.enter_actions != null) on_entry.Eval (domain); } } @@ -2670,10 +2722,12 @@ namespace M17N.Input produced.Del (); markers.Clear (); cursor_pos = 0; + keys.keyseq.Clear (); key_head = commit_key_head = 0; state_list.Clear (); state_list.Add (im.initial_state); - state_key_head = 0; + keymap = im.initial_state.keymap; + key_head = state_key_head = 0; state_pos = 0; } @@ -2681,9 +2735,7 @@ namespace M17N.Input { this.im = im; domain = new Xex.Domain (im.domain, this); - state_list.Clear (); - state_list.Add (im.initial_state); - keys = new KeySeq (); + reset (); } public ChangedStatus Changed { get { return changed; } } @@ -2709,15 +2761,44 @@ namespace M17N.Input private bool handle_key () { State state = state_list[state_list.Count - 1]; - for (MPlist *p = state.branches; ! p.IsEmpty; p = p.next) + Keymap sub = keymap.Lookup (keys, ref key_head); + + if (sub != keymap) { - int n = state_key_head; - Xex.Term term = ((Map) p.Val).Lookup (keys, ref n); + keymap = sub; + if (keymap->map_actions) + { + restore_state (); + if (! take_action (keymap->map_actions)) + return false; + } + else if (keymap->submaps != null) + { + for (int i = state_key_head; i < n; i++) + preedit_replace (cursor_pos, cursor_pos, + keys.keyseq[i].ToChar ()); + } + if (keymap->submaps == null) + { + if (keymap->branch_actions != null) + { + if (! take_action (keymap->branch_actions)) + return false; + } + if (keymap != state->keymap) + shift (state->name); + } + } + else + { + if (keymap->branch_actions) + { + if (! take_action (keymap->branch_actions)) + return false; + } - } - } public bool Toggle () diff --git a/XmlExpr.cs b/XmlExpr.cs index c609e1a..5c588da 100644 --- a/XmlExpr.cs +++ b/XmlExpr.cs @@ -81,28 +81,28 @@ namespace System.Xml.Expression public override string ToString () { return name; } } - private static Symbol Nexpr = "expr"; - - private static Symbol Nnull = ""; - 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 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 Symbol Ndefvar = "defvar"; - private static Symbol Nvname = "vname"; - private static Symbol Ndescription = "description"; - private static Symbol Nrange = "range"; + private static Symbol Qexpr = "expr"; + + private static Symbol Qnull = ""; + private static Symbol Qfuncall = "funcall"; + private static Symbol Qvarref = "varref"; + private static Symbol Qinteger = "integer"; + private static Symbol Qstring = "string"; + private static Symbol Qsymbol = "symbol"; + private static Symbol Qlist = "list"; + + private static Symbol Qdefun = "defun"; + private static Symbol Qfname = "fname"; + private static Symbol Qargs = "args"; + private static Symbol Qargs_unevalled = "args-unevalled"; + private static Symbol Qfixed = "fixed"; + private static Symbol Qoptional = "optional"; + private static Symbol Qrest = "rest"; + + private static Symbol Qdefvar = "defvar"; + private static Symbol Qvname = "vname"; + private static Symbol Qdescription = "description"; + private static Symbol Qrange = "range"; public abstract class Function { @@ -178,21 +178,21 @@ namespace System.Xml.Expression int nfixed = 0; int noptional = 0; int nrest = 0; - name = node.Attributes[Nfname].Value; + name = node.Attributes[Qfname].Value; node = node.FirstChild; if (node != null - && (node.Name == Nargs || node.Name == Nargs_unevalled)) + && (node.Name == Qargs || node.Name == Qargs_unevalled)) { XmlNode n; - args_evalled = node.Name == Nargs; + args_evalled = node.Name == Qargs; for (n = node.FirstChild; n != null; n = n.NextSibling) { - if (n.Name == Nfixed) + if (n.Name == Qfixed) nfixed++; - else if (n.Name == Noptional) + else if (n.Name == Qoptional) noptional++; - else if (n.Name == Nrest) + else if (n.Name == Qrest) nrest++; else throw new Exception ("Invalid argument type: " + n); @@ -224,14 +224,14 @@ namespace System.Xml.Expression { int i = 0; for (i = 0; i < args.Length; i++, nfixed++) - if (args[i] == Noptional || args[i] == Nrest) + if (args[i] == Qoptional || args[i] == Qrest) break; if (i < args.Length) { - if (args[i] == Noptional) + if (args[i] == Qoptional) { for (i++; i < args.Length; i++, noptional++) - if (args[i] == Nrest) + if (args[i] == Qrest) break; if (i < args.Length) nrest = 1; @@ -242,7 +242,7 @@ namespace System.Xml.Expression this.args = new Variable[max_arg]; int j; for (i = j = 0; j < this.args.Length; i++) - if (args[i] != Noptional || args[i] != Nrest) + if (args[i] != Qoptional || args[i] != Qrest) this.args[j++] = domain.Defvar (args[i]); } else @@ -254,9 +254,9 @@ namespace System.Xml.Expression public void SetBody (Domain domain, XmlNode node) { for (node = node.FirstChild; node != null; node = node.NextSibling) - if (node.Name != Ndescription - && node.Name != Nargs - && node.Name != Nargs_unevalled) + if (node.Name != Qdescription + && node.Name != Qargs + && node.Name != Qargs_unevalled) break; int nterms = 0; for (XmlNode n = node; n != null; n = n.NextSibling) @@ -743,7 +743,7 @@ namespace System.Xml.Expression public void Defun (XmlNode node, bool prototype) { - Symbol name = node.Attributes[Nfname].Value; + Symbol name = node.Attributes[Qfname].Value; Function func; if (prototype || ! functions.TryGetValue (name, out func)) @@ -767,7 +767,7 @@ namespace System.Xml.Expression Variable vari; node = node.FirstChild; - if (node != null && node.Name == Ndescription) + if (node != null && node.Name == Qdescription) { desc = node.InnerText; node = node.NextSibling; @@ -788,7 +788,7 @@ namespace System.Xml.Expression nranges = range_list.Count; } - if (type == Ninteger) + if (type == Qinteger) { int intval = parse_integer (val); int[] range = null; @@ -798,7 +798,7 @@ namespace System.Xml.Expression for (int i = 0; i < nranges; i++) { XmlNode n = range_list[i]; - if (n.Name == Nrange) + if (n.Name == Qrange) { range[i * 2] = parse_integer (n.FirstChild.InnerText); @@ -828,7 +828,7 @@ namespace System.Xml.Expression else vari = new Variable.Int (name, desc, intval, range); } - else if (type == Nstring) + else if (type == Qstring) { string[] range = null; if (range_list != null) @@ -852,7 +852,7 @@ namespace System.Xml.Expression else vari = new Variable.Str (name, desc, val, range); } - else if (type == Nsymbol) + else if (type == Qsymbol) { Symbol[] range = null; if (range_list != null) @@ -1588,19 +1588,19 @@ namespace System.Xml.Expression throw new Exception ("Invalid number of arguments to: " + fname + " " + nargs); this.args = args; - if (vname != Nnull) + if (vname != Qnull) vari = domain.GetVar (vname, true); } internal static TermValue parser (Domain domain, XmlNode node) { Symbol fname = node.Name; - Symbol vname = Nnull; + Symbol vname = Qnull; XmlAttribute attr; - if (fname == Nfuncall) - fname = node.Attributes[Nfname].Value; - attr = node.Attributes[Nvname]; + if (fname == Qfuncall) + fname = node.Attributes[Qfname].Value; + attr = node.Attributes[Qvname]; if (attr != null) vname = attr.Value; @@ -1658,7 +1658,7 @@ namespace System.Xml.Expression { Symbol name = node.Name; - if (name == Ninteger) + if (name == Qinteger) { intval = parse_integer (node.InnerText); objval = null; @@ -1666,13 +1666,13 @@ namespace System.Xml.Expression else { intval = 0; - if (name == Nsymbol) + if (name == Qsymbol) objval = (Symbol) node.InnerText; - else if (name == Nstring) + else if (name == Qstring) objval = node.InnerText.Clone (); - else if (name == Nvarref) + else if (name == Qvarref) objval = domain.GetVar ((Symbol) node.Attributes[0].Value, true); - else if (name == Nlist) + else if (name == Qlist) { List list = new List (); for (node = node.FirstChild; node != null; @@ -1823,10 +1823,10 @@ namespace System.Xml.Expression static private Term Zero = new Term (0); static private Term One = new Term (1); - static private Term TermInt = new Term (Ninteger); - static private Term TermStr = new Term (Nstring); - static private Term TermSymbol = new Term (Nsymbol); - static private Term TermList = new Term (Nlist); + static private Term TermInt = new Term (Qinteger); + static private Term TermStr = new Term (Qstring); + static private Term TermSymbol = new Term (Qsymbol); + static private Term TermList = new Term (Qlist); static private Term TermTerm = new Term ((Symbol) "term"); internal static int parse_integer (string str) @@ -1886,9 +1886,9 @@ namespace System.Xml.Expression for (XmlNode n = node; n != null; n = n.NextSibling) if (n.NodeType == XmlNodeType.Element) { - if (n.Name == Ndefun) + if (n.Name == Qdefun) domain.Defun (n, true); - else if (n.Name == Ndefvar) + else if (n.Name == Qdefvar) domain.Defvar (n); else nterms++; @@ -1898,9 +1898,9 @@ namespace System.Xml.Expression for (XmlNode n = node; n != null; n = n.NextSibling) if (n.NodeType == XmlNodeType.Element) { - if (n.Name == Ndefun) + if (n.Name == Qdefun) domain.Defun (n, false); - else if (n.Name != Ndefvar) + else if (n.Name != Qdefvar) terms[i++]= new Term (domain, n); } return terms; @@ -1922,7 +1922,7 @@ namespace System.Xml.Expression reader.Read (); } while (reader.NodeType != XmlNodeType.None && (reader.NodeType != XmlNodeType.Element - || reader.Name != Nexpr)); + || reader.Name != Qexpr)); if (reader.NodeType == XmlNodeType.None) throw new Exception ("Node not found"); node = doc.ReadNode (reader); -- 1.7.10.4