*** empty log message ***
authorhanda <handa>
Mon, 5 Oct 2009 00:01:56 +0000 (00:01 +0000)
committerhanda <handa>
Mon, 5 Oct 2009 00:01:56 +0000 (00:01 +0000)
MInputMethod.cs

index ecee0a1..3909bba 100644 (file)
@@ -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<Xex.Term> arg = new List<Xex.Term> (parse_action (p));
+         List<Xex.Term> arg = new List<Xex.Term> (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> state_stack;
+      private List<State> 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> ();
-       state_stack.Push ((State) im.states.val);
+       state_list = new List<State> ();
+       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);
+      }
     }
   }
 }