*** empty log message ***
[m17n/m17n-lib-cs.git] / MInputMethod.cs
index 8bd03c4..ff6a974 100644 (file)
@@ -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<Key> keyseq = new List<Key> ();
 
        public override Xex.TermValue Clone ()
@@ -401,13 +404,32 @@ 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)
                   : 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 +490,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));
           }
        }
 
@@ -544,18 +566,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 +592,36 @@ namespace M17N.Input
 
        public override string ToString ()
        {
-        return "<marker>" + name.Name + "</marker>";
+        return "<marker>" + mname + "</marker>";
        }
 
-       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 +666,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 +682,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 +721,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);
        }
      }
 
@@ -992,6 +1026,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<MSymbol, Selector> selectors;
 
       static Selector ()
@@ -1014,7 +1051,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 +1063,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 "<selector>@" + tag + "</selector>";
+      }
     }
 
     internal class Map
@@ -1056,6 +1106,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 = action.Eval (domain);
+       if (result.IsError)
+         {
+           ((Context) domain.context).Error = result.ToString ();
+           return false;
+         }
+       return (result != Tcatch_tag);
+      }
+    }
+
     internal class Keymap
     {
       public Dictionary<Key, Keymap> submaps;
@@ -1246,9 +1321,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);
@@ -1768,7 +1843,7 @@ namespace M17N.Input
                    XmlNode n = nd.FirstChild;
                    if (n.Name != Qkeyseq)
                      continue;
-                   KeySeq keyseq = (KeySeq) KeySeq.parser (domain, n);
+                   KeySeq keyseq = (KeySeq) KeySeq.Parser (domain, n);
                    Xex.Term[] actions = Xex.ParseTerms (domain, n.NextSibling);
                    map.entries.Add (new Map.Entry (domain, keyseq, actions));
                  }
@@ -2260,9 +2335,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 +2452,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;