*** empty log message ***
authorhanda <handa>
Thu, 24 Sep 2009 13:12:18 +0000 (13:12 +0000)
committerhanda <handa>
Thu, 24 Sep 2009 13:12:18 +0000 (13:12 +0000)
MInputMethod.cs
XmlExpr.cs

index 6c73951..fcc0973 100644 (file)
@@ -381,9 +381,9 @@ namespace M17N.Input
            }
        }
 
-      public KeySeq (List<Xex.Term> list)
+      public KeySeq (Xex.Term[] args)
        {
-         foreach (Xex.Term term in list)
+         foreach (Xex.Term term in args)
            {
              if (term.IsName)
                keyseq.Add (new Key ((MSymbol) term.Nameval.name));
@@ -561,8 +561,149 @@ namespace M17N.Input
          str += " " + p.key;
        return str + ")";
       }
+
+      public Xex.Term Call (MSymbol method, MInputContext ic, Xex.Term[] args)
+      {
+       if (assembly == null)
+         {
+           try {
+             assembly = Assembly.LoadFrom (name + ".dll");
+           } catch {
+             return Xex.Zero;
+           }
+           Type t = assembly.GetType ("Plugin");
+           for (MPlist p = plugin.methods; ! p.IsEmpty; p = p.next)
+             p.Set (p.key, t.GetMethod (p.key.Name));
+         }
+
+       MethodInfo method_info = (MethodInfo) methods.Get (method);
+       if (method_info == null)
+         return Xex.Zero;
+       Xex.Term result = (Xex.Term) method_info.Invoke (null, args);
+       return result.Eval ();
+      }
+    }
+
+    internal class PluginMethod : Function
+    {
+      public Plugin plugin;
+      public MSymbol method;
+
+      public PluginMethod (Plugin plugin, MSymbol name)
+       : base ((Name) name.name, 0, -1)
+       {
+         this.plugin = plugin;
+         method = name.name.Substring (plugin.name.Length + 1);
+       }
+
+      public override Term Call (Xex.Domain domain, Xex.Variable vari,
+                                Xex.Term[] args)
+      {
+       Xex.Term[] args = (Xex.Term[]) args.Clone ();
+       for (int i = 0; i < args.Length; i++)
+         {
+           args[i] = args[i].Eval (domain);
+           if (domain.Thrown)
+             return args[i];
+         }
+       return plugin.Call (method, (MIntutContext) domain.context, args);
+      }
     }
 
+    internal class PluginCall : Xex.TermValue
+    {
+      PluginMethod method;
+      Xex.Term[] args;
+
+      public PluginCall (Plugin plugin, MSymbol entry, Xex.Term[] args)
+       {
+         this.plugin = plugin;
+         this.entry = entry;
+         this.args = args;
+       }
+
+      public override Xex.Term Eval (Xex.Domain domain)
+       {
+         Xex.Term[] args = new Xex.Term[this.args.Length];
+         for (int i = 0; i < args.Length; i++)
+           args[i] = this.args[i].Eval (domain);
+         return plugin.Call (entry, args);
+       }
+    }
+
+    internal abstract class Marker : Xex.TermValue
+    {
+      MSymbol name;
+      MInputContext ic;
+
+      public Marker (MSymbol name, MInputContext ic)
+       {
+         this.name = name;
+         this.ic = ic;
+       }
+
+      public abstract int Position { get; set; }
+    }
+
+    internal class NamedMarker : Marker
+    {
+      int position;
+
+      public NamedMaker (MSymbol name, MInputContext ic) : base (name, ic)
+       {
+         ic.markers.Put (name, this);
+       }
+
+      public override int Position {
+       get { return position; }
+       set { position = value; }
+      }
+    }
+     
+    internal class SystemMarker : Marker
+    {
+      public SystemMarker (MSymbol name, MInputContext ic) : base (name, ic)
+       {
+       }
+       
+      public override int Position {
+       get {
+         switch (name.Name[1])
+           {
+           case '<': return 0;
+           case '>': return ic.preedit.Length;
+           case '-': return ic.cursor_pos - 1;
+           case '+': return ic.cursor_pos + 1;
+           case '[':
+             if (ic.cursor_pos > 0)
+               {
+                 int pos = ic.cursor_os;
+                 int to;
+                 ic.preedit.FindProp (MInputMethod.Mcandidates, pos - 1,
+                                      out pos, out to);
+                 return pos;
+               }
+             return 0;
+           case ']':
+             if (ic.cursor_pos < ic.preedit.Length - 1)
+               {
+                 int pos = ic.cursor_pos;
+                 int from;
+                 ic.preedit.FindProp (MInputMethod.Mcandidates, pos,
+                                      out from, out pos);
+                 return pos;
+               }
+             return ic.preedit.Length;
+           default:
+             return name.Name[1] - '0';
+           }
+       }
+       set {
+         throw new Exception ("Can't set predefined marker: " + name);
+       }
+      }
+    }
+      
     internal class Map
     {
       public MSymbol name;
@@ -682,7 +823,6 @@ namespace M17N.Input
       im_domain.DefSubr (Fcommit, "commit", true, 0, 0);
       im_domain.DefSubr (Funhandle, "unhandle", true, 0, 0);
       im_domain.DefSubr (Fshift, "shift", true, 1, 1);
-      im_domain.DefSubr (Fcall, "call", true, 2, -1);
       im_domain.DefSubr (Fmarker, "marker", true, 1, 1);
       im_domain.DefSubr (Fchar_at, "char-at", true, 1, 1);
       im_domain.DefSubr (Fkeyseq, "keyseq", true, 1, -1);
@@ -1543,16 +1683,16 @@ namespace M17N.Input
     }
 
     private static Xex.Term Fmark (Xex.Domain domain, Xex.Variable vari,
-                                Xex.Term[] args)
+                                  Xex.Term[] args)
     {
-      ((MInputContext) domain.context).mark (args[0]);
+      ((MInputContext) domain.context).mark ((Marker) args[0].Objval);
       return args[0];
     }
 
     private static Xex.Term Fkeyseq (Xex.Domain domain, Xex.Variable vari,
                                     Xex.Term[] args)
     {
-      return new KeySeq (args[0].Listval);
+      return new KeySeq (args);
     }
 
     private static Xex.Term Fpushback (Xex.Domain domain, Xex.Variable vari,
@@ -1595,7 +1735,9 @@ namespace M17N.Input
                                       Xex.Term[] args)
     {
       ((MInputContext) domain.context).commit ();
-      return Xex.Zero;
+      args = new Xex.Term[2];
+      args[0] = args[1] = catch_tag;
+      return Xex.Fthrow (domain, vari, args);
     }
 
     private static Xex.Term Fshift (Xex.Domain domain, Xex.Variable vari,
@@ -1605,31 +1747,6 @@ namespace M17N.Input
       return args[0];
     }
 
-    private static Xex.Term Fcall (Xex.Domain domain, Xex.Variable vari, Xex.Term[] args)
-    {
-      MSymbol module = (MSymbol) args[0].Args[0].Val;
-      MSymbol method = (MSymbol) args[1].Args[0].Val;
-      MPlist arglist = new MPlist ();
-
-      for (int i = 2; i < args.Length; i++)
-       {
-         object val = args[i].Eval (domain);
-
-         if (val is int)
-           arglist.Add (MSymbol.integer, val);
-         else if (val is MSymbol)
-           arglist.Add (MSymbol.symbol, val);
-         else if (val is MText)
-           arglist.Add (MSymbol.mtext, val);
-         else if (val is MPlist)
-           arglist.Add (MSymbol.plist, val);
-         else
-           throw new Exception ("Invalid argument to {0}/{1}: {2}",
-                                module, method, val);
-       }
-      return ((MInputContext) domain.context).call (module, method, arglist);
-    }
-
     public override string ToString ()
     {
       string str = (String.Format ("({0} (title \"{1}\")", tag, title));
index f88d2e7..84d808e 100644 (file)
@@ -138,15 +138,14 @@ namespace System.Xml.Expression
 
        public override Term Call (Domain domain, Variable vari, Term[] args)
        {
-         Term[] newargs = new Term[args.Length];
-
+         args = (Term[]) args.Clone ();
          for (int i = 0; i < args.Length; i++)
            {
-             newargs[i] = args[i].Eval (domain);
+             args[i] = args[i].Eval (domain);
              if (domain.Thrown)
-               return newargs[i];
+               return args[i];
            }
-         return builtin (domain, vari, newargs);
+         return builtin (domain, vari, args);
        }
       }
 
@@ -270,7 +269,7 @@ namespace System.Xml.Expression
       }
     }
 
-    public class Variable : Object
+    public class Variable : TermValue
     {
       public readonly Name name;
       public string desc;
@@ -1178,7 +1177,6 @@ namespace System.Xml.Expression
          result.objval = list;
          return result;
        }
-      vari.val.objval = list;
       return vari.val;
     }
 
@@ -1429,7 +1427,7 @@ namespace System.Xml.Expression
       return TermTerm;
     }
 
-    private static Term Fcatch (Domain domain, Variable vari, Term[] args)
+    public static Term Fcatch (Domain domain, Variable vari, Term[] args)
     {
       Term result = Zero;
       try {
@@ -1441,18 +1439,18 @@ namespace System.Xml.Expression
       return result;
     }
 
-    private static Term Fthrow (Domain domain, Variable vari, Term[] args)
+    public static Term Fthrow (Domain domain, Variable vari, Term[] args)
     {
       domain.ThrowTag (new CatchTag (args[0].Nameval));
       return (args.Length == 1 ? Zero : args[1]);
     }
 
-    public class Object
+    public class TermValue
     {
       public virtual Term Eval (Domain domain) { return new Term (this); }
     }
 
-    private class Funcall : Object
+    private class Funcall : TermValue
     {
       internal Function func;
       internal Variable vari;
@@ -1522,7 +1520,7 @@ namespace System.Xml.Expression
       public Term (string str) { intval = 0; objval = str; }
       public Term (List<Term> list) { intval = 0; objval = list; }
       public Term (Term term) { intval = term.intval; objval = term.objval; }
-      public Term (Object obj) { intval = 0; objval = obj; }
+      public Term (TermValue obj) { intval = 0; objval = obj; }
 
       public Term (XmlNode node, Domain domain)
        {
@@ -1555,7 +1553,7 @@ namespace System.Xml.Expression
            }
        }
 
-      public int Objval {
+      public object Objval {
        get {
          if (objval == null)
            throw new Exception ("term is an integer: " + this);
@@ -1621,8 +1619,8 @@ namespace System.Xml.Expression
          return this;
        if (objval is List<Term>)
          return new Term ((List<Term>) objval);
-       if (objval is Object)
-         return ((Object) objval).Eval (domain);
+       if (objval is TermValue)
+         return ((TermValue) objval).Eval (domain);
        throw new Exception ("invalid Term object: " + objval);
       }