From: handa Date: Mon, 5 Oct 2009 00:01:56 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ddaf242f412b3aedd301517435f1f05f27df7182;p=m17n%2Fm17n-lib-cs.git *** empty log message *** --- diff --git a/MInputMethod.cs b/MInputMethod.cs index ecee0a1..3909bba 100644 --- a/MInputMethod.cs +++ b/MInputMethod.cs @@ -942,15 +942,19 @@ namespace M17N.Input this.actions = actions; } - public Xex.Term Lookup (KeySeq keys, int index) + public Xex.Term Lookup (KeySeq keys, ref index) { - Map sub; - - if (index + 1 == keys.keyseq.Count) - return actions; - if (submaps.TryGetValue (keys.keyseq[index], out sub)) - return sub.Lookup (keys, index + 1); - return Tnil; + if (index < keys.keyseq.Count) + { + Map sub; + if (submaps.TryGetValue (keys.keyseq[index], out sub)) + { + index++; + return sub.Lookup (keys, ref index); + } + return Tnil; + } + return actions; } private void describe (MText mt, KeySeq keyseq) @@ -1738,49 +1742,75 @@ namespace M17N.Input if (! plist.IsPlist) throw new Exception ("Invalid cond args: " + plist); MPlist p = plist.Plist; - List arg = new List (parse_action (p)); + List arg = new List (parse_actions (p)); args[i] = new Xex.Term (arg); } return new Xex.Term (domain, (Xex.Symbol) Mcond.Name, args); } - private Xex.Term[] parse_action (MPlist plist) + private Xex.Term parse_integer (MPlist plist) { - Xex.Term[] terms = new Xex.Term[plist.Count]; + if (plist.IsSymbol) + { + Xex.Variable vari = domain.GetVar (Xex.Name (plist.Symbol.Name), + true); + Xex.Term[] args = Xex.Term[1]; + args[0] = new Xex.Term (vari); + terms[i] = new Xex.Term (domain, Ninsert, args); + } + else if (plist.IsMText) + { + Xex.Term[] args = Xex.Term[1]; + args[0] = new Xex.Term ((string) plist.Text); + terms[i] = new Xex.Term (domain, Ninsert, args); + } + else if (plist.IsInteger) + { + Xex.Term[] args = Xex.Term[1]; + args[0] = new Xex.Term (plist.Integer); + terms[i] = new Xex.Term (domain, Ninsert, args); + } + } - for (int i = 0; ! plist.IsEmpty; i++, plist = plist.next) + private Xex.Term parse_action (MPlist plist) + { + if (plist.IsPlist) { - 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.IsMText || p.IsPlist) + return parse_integer (p); + if (! p.IsSymbol) + throw new Exception ("Invalid action: " + p); + MSymbol name = p.Symbol; + p = p.next; + if (name == Mcond) + return parse_cond (p); + else if (name == Mset || name == Madd || name == Msub + || name == Mmul || name == Mdiv) { - 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)); + Xex.Symbol varname = p.Symbol.Name; + return new Xex.Term (domain, (Xex.Symbol) name.Name, + varname, parse_actions (p.next)); } else - throw new Exception ("Invalid action: " + plist); + return new Xex.Term (domain, (Xex.Symbol) name.Name, + parse_actions (p)); } + else if (plist.MText || plist.Integer || plist.IsSymbol) + retunr parse_insert (plist); + else + throw new Exception ("Invalid action: " + plist); + } + + private Xex.Term[] parse_actions (MPlist plist) + { + Xex.Term[] terms = new Xex.Term[plist.Count]; + + for (int i = 0; ! plist.IsEmpty; i++, plist = plist.next) + terms[i] = parse_action (plist); return terms; } @@ -1805,7 +1835,7 @@ namespace M17N.Input continue; transform (p.next); domain.Defun ((Xex.Symbol) p.Symbol.Name, false, null, - parse_action (p.next), false); + parse_actions (p.next), false); } } @@ -1837,7 +1867,7 @@ namespace M17N.Input if (p.IsEmpty) continue; map.Add (keys, 0, - new Xex.Term (domain, Nprogn, parse_action (p))); + new Xex.Term (domain, Nprogn, parse_actions (p))); } } } @@ -1872,7 +1902,7 @@ namespace M17N.Input continue; MSymbol map_name = p.Symbol; p = p.next; - Xex.Term term = new Xex.Term (domain, Nprogn, parse_action (p)); + Xex.Term term = new Xex.Term (domain, Nprogn, parse_actions (p)); state.branches.Add (map_name, term); } } @@ -2074,9 +2104,15 @@ namespace M17N.Input private int candidate_from, candidate_to; private bool candidate_show; - private Stack state_stack; + private List state_list; + + // Sequence of input keys. internal KeySeq keys; + + // Index into KEYS specifying the next key to handle. internal int key_head; + + private int state_key_head; private object state_var_values; private int commit_key_head; @@ -2085,8 +2121,15 @@ namespace M17N.Input internal MPlist markers = new MPlist (); internal MText preceding_text = new MText (); internal MText following_text = new MText (); + + // Set to false before calling the method 'handle_key', and set + // to true when some key is unhandled. private bool key_unhandled; + // The unhandled key. It has the meaning only when + // 'key_unhandled' is true. + private Key unhandled_key; + internal Xex.Domain domain; internal ChangedStatus changed; @@ -2097,8 +2140,8 @@ namespace M17N.Input { this.im = im; domain = new Xex.Domain (im.domain, this); - state_stack = new Stack (); - state_stack.Push ((State) im.states.val); + state_list = new List (); + state_list.Add ((State) im.states.val); keys = new KeySeq (); } @@ -2382,10 +2425,9 @@ namespace M17N.Input if (sym == MSymbol.t) { - if (state_stack.Count > 1) - state = state_stack.Pop (); - else - state = state_stack.Peek (); + state = state_list.Last (); + if (state_list.Count > 1) + state_list.RemoveAt (state_list.Count - 1) } else { @@ -2394,7 +2436,10 @@ namespace M17N.Input throw new Exception ("Unknown state: " + state.name); } if (state == null) - state = state_stack.Pop (); + { + state = state_list.Last; + state_list.RemoveAt (state_list.Count -1); + } if (state == (State) im.states.val) { commit (); @@ -2405,9 +2450,9 @@ namespace M17N.Input state_key_head = key_head; state_pos = cursor_pos; state_preedit = preedit.Dup (); - if (state != state_stack.Peek ()) + if (state != state_list.Last ()) { - state_stack.Push (state); + state_list.Add (state); state_var_values = domain.SaveValues (); status = state.title; if (status == null) @@ -2429,8 +2474,8 @@ namespace M17N.Input markers.Clear (); cursor_pos = 0; key_head = commit_key_head = 0; - state_stack.Clear (); - state_stack.Push ((State) im.states.Val); + state_list.Clear (); + state_list.Add ((State) im.states.Val); state_key_head = 0; state_pos = 0; } @@ -2457,6 +2502,51 @@ namespace M17N.Input active = ! active; return active; } + + public bool UnhandledKey (out const Key key) + { + key = unhandled_key; + return key_unhandled; + } + + public bool Produced (out const MText mt) + { + mt = produced; + return (produced.Length > 0); + } + + + // Return value: + // true: All keys are handled and there's no text to commit. + // false: Some key is unhandled or there's a text to commit. + // The caller should use methods UnhandledKey and Produced. + + public bool Filter (Key key) + { + if (check_reload (key)) + return true; + changed = ChangedStatus.None; + produced.Del (); + preceding_text.Del (); + following_text.Del (); + + key_unhandled = false; + keys.Add (key); + int count = 0; + while (key_head < keys.Length) + { + if (! handle_key ()) + { + unhandled_key = keys[key_head++]; + key_unhandled = true; + break; + } + if (++count == 100) + break; + } + keys.RemoveRange (0, key_head); + return (! key_unhandled && produced.Length == 0); + } } } }