*** empty log message ***
authorhanda <handa>
Wed, 5 Aug 2009 14:32:33 +0000 (14:32 +0000)
committerhanda <handa>
Wed, 5 Aug 2009 14:32:33 +0000 (14:32 +0000)
MExpression.cs
MInputMethod.cs
Makefile
expr.cs

index 560a6b1..f482088 100644 (file)
@@ -9,7 +9,8 @@ namespace M17N.Core
 {
   public class MExpression
   {
-    public delegate object Evaluator (object[] args, MPlist bindings);
+    public delegate object Evaluator (object[] args, MPlist bindings,
+                                     object context);
 
     internal delegate void PrettyPrinter (Function func,
                                          string indent, object[] args);
@@ -114,20 +115,21 @@ namespace M17N.Core
        return slot;
       }
 
-      public object Call (object[] args, MPlist bindings)
+      public object Call (object[] args, MPlist bindings, object context)
       {
        if (name == MSymbol.nil)
          return args[0];
        if (eval != null)
-         return eval (args, bindings);
+         return eval (args, bindings, context);
 
        MPlist arg_symbols = (MPlist) data[0];
        for (int i = 0; i < args.Length; i++, arg_symbols = arg_symbols.next)
          bindings = bindings.Cons (arg_symbols.Symbol,
-                                   ((MExpression) args[i]).Eval (bindings));
+                                   ((MExpression) args[i]).Eval (bindings,
+                                                                 context));
        object result = 0;
        for (int i = 1; i < data.Length; i++)
-         result = ((MExpression) data[i]).Eval (bindings);
+         result = ((MExpression) data[i]).Eval (bindings, context);
        return result;
       }
 
@@ -156,96 +158,106 @@ namespace M17N.Core
        Console.Write (")");
       }
 
-      private static object get_value (object[] args, MPlist bindings)
+      private static object get_value (object[] args, MPlist bindings,
+                                      object context)
       {
        return find_binding (args, bindings).val;
       }
 
-      private static object set_value (object[] args, MPlist bindings)
+      private static object set_value (object[] args, MPlist bindings,
+                                      object context)
       {
        MSymbol var = (MSymbol) args[0];
        MPlist slot = bindings.Find (var);
 
        if (slot == null)
          slot = bindings.Push (var, null);
-       slot.val = ((MExpression) args[1]).Eval (bindings);
+       slot.val = ((MExpression) args[1]).Eval (bindings, context);
        if (slot.val is MText)
          slot.val = ((MText) slot.val).Dup ();
        return slot.val;
       }
 
-      private static object plus (object[] args, MPlist bindings)
+      private static object plus (object[] args, MPlist bindings,
+                                 object context)
       {
-       object val = ((MExpression) args[0]).Eval (bindings);
+       object val = ((MExpression) args[0]).Eval (bindings, context);
 
        if (val is int)
          {
            int n = 0;
            foreach (MExpression e in args)
-             n += (int) e.Eval (bindings);
+             n += (int) e.Eval (bindings, context);
            val = n;
          }
        else if (val is MText)
          {
            MText mt = new MText ();
            foreach (MExpression e in args)
-             mt += (MText) e.Eval (bindings);
+             mt += (MText) e.Eval (bindings, context);
            val = mt;
          }
        return val;
       }
 
-      private static object multi (object[] args, MPlist bindings)
+      private static object multi (object[] args, MPlist bindings,
+                                  object context)
       {
        int n = 1;
        foreach (MExpression e in args)
-         n *= (int) e.Eval (bindings);
+         n *= (int) e.Eval (bindings, context);
        return n;
       }
 
-      private static object minus (object[] args, MPlist bindings)
+      private static object minus (object[] args, MPlist bindings,
+                                  object context)
       {
-       int n = (int) ((MExpression) args[0]).Eval (bindings);
+       int n = (int) ((MExpression) args[0]).Eval (bindings, context);
        if (args.Length == 1)
          return - n;
        for (int i = 1; i < args.Length; i++)
-         n -= (int) ((MExpression) args[i]).Eval (bindings);
+         n -= (int) ((MExpression) args[i]).Eval (bindings, context);
        return n;
       }
 
-      private static object divide (object[] args, MPlist bindings)
+      private static object divide (object[] args, MPlist bindings,
+                                   object context)
       {
-       int n = (int) ((MExpression) args[0]).Eval (bindings);
+       int n = (int) ((MExpression) args[0]).Eval (bindings, context);
        for (int i = 1; i < args.Length; i++)
-         n /= (int) ((MExpression) args[i]).Eval (bindings);
+         n /= (int) ((MExpression) args[i]).Eval (bindings, context);
        return n;
       }
 
-      private static object percent (object[] args, MPlist bindings)
+      private static object percent (object[] args, MPlist bindings,
+                                    object context)
       {
-       int n = (int) ((MExpression) args[0]).Eval (bindings);
+       int n = (int) ((MExpression) args[0]).Eval (bindings, context);
        for (int i = 1; i < args.Length; i++)
-         n %= (int) ((MExpression) args[i]).Eval (bindings);
+         n %= (int) ((MExpression) args[i]).Eval (bindings, context);
        return n;
       }
 
-      private static object logior (object[] args, MPlist bindings)
+      private static object logior (object[] args, MPlist bindings,
+                                   object context)
       {
-       int n = (int) ((MExpression) args[0]).Eval (bindings);
+       int n = (int) ((MExpression) args[0]).Eval (bindings, context);
        for (int i = 1; i < args.Length; i++)
-         n |= (int) ((MExpression) args[i]).Eval (bindings);
+         n |= (int) ((MExpression) args[i]).Eval (bindings, context);
        return n;
       }
 
-      private static object logand (object[] args, MPlist bindings)
+      private static object logand (object[] args, MPlist bindings,
+                                   object context)
       {
-       int n = (int) ((MExpression) args[0]).Eval (bindings);
+       int n = (int) ((MExpression) args[0]).Eval (bindings, context);
        for (int i = 1; i < args.Length; i++)
-         n &= (int) ((MExpression) args[i]).Eval (bindings);
+         n &= (int) ((MExpression) args[i]).Eval (bindings, context);
        return n;
       }
 
-      private static object pluseq (object[] args, MPlist bindings)
+      private static object pluseq (object[] args, MPlist bindings,
+                                   object context)
       {
        MPlist slot = find_binding (args, bindings);
        object val = slot.val;
@@ -254,124 +266,137 @@ namespace M17N.Core
          {
            int n = (int) val;
            for (int i = 1; i < args.Length; i++)
-             n += (int) ((MExpression) args[i]).Eval (bindings);
+             n += (int) ((MExpression) args[i]).Eval (bindings, context);
            slot.val = n;
          }
        else if (val is MText)
          {
            MText mt = (MText) val;
            for (int i = 1; i < args.Length; i++)
-             mt.Cat ((MText) ((MExpression) args[i]).Eval (bindings));
+             mt.Cat ((MText) ((MExpression) args[i]).Eval (bindings, context));
          }
        return slot.val;
       }
 
-      private static object multieq (object[] args, MPlist bindings)
+      private static object multieq (object[] args, MPlist bindings,
+                                    object context)
       {
        MPlist slot = find_binding (args, bindings);
        int n = (int) slot.val;
        for (int i = 1; i < args.Length; i++)
-         n *= (int) ((MExpression) args[i]).Eval (bindings);
+         n *= (int) ((MExpression) args[i]).Eval (bindings, context);
        return (slot.val = n);
       }
 
-      private static object minuseq (object[] args, MPlist bindings)
+      private static object minuseq (object[] args, MPlist bindings,
+                                    object context)
       {
        MPlist slot = find_binding (args, bindings);
        int n = (int) slot.val;
        for (int i = 1; i < args.Length; i++)
-         n -= (int) ((MExpression) args[i]).Eval (bindings);
+         n -= (int) ((MExpression) args[i]).Eval (bindings, context);
        return (slot.val = n);
       }
 
-      private static object divideeq (object[] args, MPlist bindings)
+      private static object divideeq (object[] args, MPlist bindings,
+                                     object context)
       {
        MPlist slot = find_binding (args, bindings);
        int n = (int) slot.val;
        for (int i = 1; i < args.Length; i++)
-         n /= (int) ((MExpression) args[i]).Eval (bindings);
+         n /= (int) ((MExpression) args[i]).Eval (bindings, context);
        return (slot.val = n);
       }
 
-      private static object percenteq (object[] args, MPlist bindings)
+      private static object percenteq (object[] args, MPlist bindings,
+                                      object context)
       {
        MPlist slot = find_binding (args, bindings);
        int n = (int) slot.val;
        for (int i = 1; i < args.Length; i++)
-         n %= (int) ((MExpression) args[i]).Eval (bindings);
+         n %= (int) ((MExpression) args[i]).Eval (bindings, context);
        return (slot.val = n);
       }
 
-      private static object logioreq (object[] args, MPlist bindings)
+      private static object logioreq (object[] args, MPlist bindings,
+                                     object context)
       {
        MPlist slot = find_binding (args, bindings);
        int n = (int) slot.val;
        for (int i = 1; i < args.Length; i++)
-         n |= (int) ((MExpression) args[i]).Eval (bindings);
+         n |= (int) ((MExpression) args[i]).Eval (bindings, context);
        return (slot.val = n);
       }
 
-      private static object logandeq (object[] args, MPlist bindings)
+      private static object logandeq (object[] args, MPlist bindings,
+                                     object context)
       {
        MPlist slot = find_binding (args, bindings);
        int n = (int) slot.val;
        for (int i = 1; i < args.Length; i++)
-         n &= (int) ((MExpression) args[i]).Eval (bindings);
+         n &= (int) ((MExpression) args[i]).Eval (bindings, context);
        return (slot.val = n);
       }
 
-      private static object lshift (object[] args, MPlist bindings)
+      private static object lshift (object[] args, MPlist bindings,
+                                   object context)
       {
-       int n1 = (int) ((MExpression) args[0]).Eval (bindings);
-       int n2 = (int) ((MExpression) args[1]).Eval (bindings);
+       int n1 = (int) ((MExpression) args[0]).Eval (bindings, context);
+       int n2 = (int) ((MExpression) args[1]).Eval (bindings, context);
        return n1 << n2;
       }
 
-      private static object lshifteq (object[] args, MPlist bindings)
+      private static object lshifteq (object[] args, MPlist bindings,
+                                     object context)
       {
        MPlist slot = find_binding (args, bindings);
        int n1 = (int) slot.val;
-       int n2 = (int) ((MExpression) args[1]).Eval (bindings);
+       int n2 = (int) ((MExpression) args[1]).Eval (bindings, context);
        return (slot.val = (n1 << n2));
       }
 
-      private static object rshift (object[] args, MPlist bindings)
+      private static object rshift (object[] args, MPlist bindings,
+                                   object context)
       {
-       int n1 = (int) ((MExpression) args[0]).Eval (bindings);
-       int n2 = (int) ((MExpression) args[1]).Eval (bindings);
+       int n1 = (int) ((MExpression) args[0]).Eval (bindings, context);
+       int n2 = (int) ((MExpression) args[1]).Eval (bindings, context);
        return n1 >> n2;
       }
 
-      private static object rshifteq (object[] args, MPlist bindings)
+      private static object rshifteq (object[] args, MPlist bindings,
+                                     object context)
       {
        MPlist slot = find_binding (args, bindings);
        int n1 = (int) slot.val;
-       int n2 = (int) ((MExpression) args[1]).Eval (bindings);
+       int n2 = (int) ((MExpression) args[1]).Eval (bindings, context);
        return (slot.val = (n1 >> n2));
       }
 
-      private static object eq (object[] args, MPlist bindings)
+      private static object eq (object[] args, MPlist bindings,
+                               object context)
       {
-       int n = (int) ((MExpression) args[0]).Eval (bindings);
+       int n = (int) ((MExpression) args[0]).Eval (bindings, context);
        for (int i = 1; i < args.Length; i++)
-         if (n != (int) ((MExpression) args[i]).Eval (bindings))
+         if (n != (int) ((MExpression) args[i]).Eval (bindings, context))
            return 0;
        return 1;
       }
 
-      private static object noteq (object[] args, MPlist bindings)
+      private static object noteq (object[] args, MPlist bindings,
+                                  object context)
       {
-       int n1 = (int) ((MExpression) args[0]).Eval (bindings);
-       int n2 = (int) ((MExpression) args[1]).Eval (bindings);
+       int n1 = (int) ((MExpression) args[0]).Eval (bindings, context);
+       int n2 = (int) ((MExpression) args[1]).Eval (bindings, context);
        return (n1 != n2);
       }
 
-      private static object less (object[] args, MPlist bindings)
+      private static object less (object[] args, MPlist bindings,
+                                 object context)
       {
-       int n = (int) ((MExpression) args[0]).Eval (bindings);
+       int n = (int) ((MExpression) args[0]).Eval (bindings, context);
        for (int i = 1; i < args.Length; i++)
          {
-           int n1 = (int) ((MExpression) args[i]).Eval (bindings);
+           int n1 = (int) ((MExpression) args[i]).Eval (bindings, context);
            if (n >= n1)
              return 0;
            n = n1;
@@ -379,12 +404,13 @@ namespace M17N.Core
        return 1;
       }
 
-      private static object lesseq (object[] args, MPlist bindings)
+      private static object lesseq (object[] args, MPlist bindings,
+                                   object context)
       {
-       int n = (int) ((MExpression) args[0]).Eval (bindings);
+       int n = (int) ((MExpression) args[0]).Eval (bindings, context);
        for (int i = 1; i < args.Length; i++)
          {
-           int n1 = (int) ((MExpression) args[i]).Eval (bindings);
+           int n1 = (int) ((MExpression) args[i]).Eval (bindings, context);
            if (n > n1)
              return 0;
            n = n1;
@@ -392,12 +418,13 @@ namespace M17N.Core
        return 1;
       }
 
-      private static object more (object[] args, MPlist bindings)
+      private static object more (object[] args, MPlist bindings,
+                                 object context)
       {
-       int n = (int) ((MExpression) args[0]).Eval (bindings);
+       int n = (int) ((MExpression) args[0]).Eval (bindings, context);
        for (int i = 1; i < args.Length; i++)
          {
-           int n1 = (int) ((MExpression) args[i]).Eval (bindings);
+           int n1 = (int) ((MExpression) args[i]).Eval (bindings, context);
            if (n <= n1)
              return 0;
            n = n1;
@@ -405,12 +432,13 @@ namespace M17N.Core
        return 1;
       }
 
-      private static object moreeq (object[] args, MPlist bindings)
+      private static object moreeq (object[] args, MPlist bindings,
+                                   object context)
       {
-       int n = (int) ((MExpression) args[0]).Eval (bindings);
+       int n = (int) ((MExpression) args[0]).Eval (bindings, context);
        for (int i = 1; i < args.Length; i++)
          {
-           int n1 = (int) ((MExpression) args[i]).Eval (bindings);
+           int n1 = (int) ((MExpression) args[i]).Eval (bindings, context);
            if (n < n1)
              return 0;
            n = n1;
@@ -418,12 +446,13 @@ namespace M17N.Core
        return 1;
       }
 
-      private static object progn (object[] args, MPlist bindings)
+      private static object progn (object[] args, MPlist bindings,
+                                  object context)
       {
        object result = null;
 
        foreach (MExpression e in args)
-         result = e.Eval (bindings);
+         result = e.Eval (bindings, context);
        return result;
       }
 
@@ -445,20 +474,22 @@ namespace M17N.Core
        Console.Write (")");
       }
 
-      private static bool check_condition (MExpression e, MPlist bindings)
+      private static bool check_condition (MExpression e, MPlist bindings,
+                                          object context)
       {
-       object result = e.Eval (bindings);
+       object result = e.Eval (bindings, context);
        return (! (result is int) || (int) result != 0);
       }
 
-      private static object cond (object[] args, MPlist bindings)
+      private static object cond (object[] args, MPlist bindings,
+                                 object context)
       {
        foreach (MExpression[] elist in args)
-         if (check_condition (elist[0], bindings))
+         if (check_condition (elist[0], bindings, context))
            {
              object result = 0;
              for (int i = 1; i < elist.Length; i++)
-               result = elist[i].Eval (bindings);
+               result = elist[i].Eval (bindings, context);
              return result;
            }
        return 0;
@@ -486,15 +517,16 @@ namespace M17N.Core
        Console.Write (")");
       }
 
-      private static object ifclause (object[] args, MPlist bindings)
+      private static object ifclause (object[] args, MPlist bindings,
+                                     object context)
       {
        object result = 0;
 
-       if (check_condition ((MExpression) args[0], bindings))
-         result = ((MExpression) args[1]).Eval (bindings);
+       if (check_condition ((MExpression) args[0], bindings, context))
+         result = ((MExpression) args[1]).Eval (bindings, context);
        else
          for (int i = 2; i < args.Length; i++)
-           result = ((MExpression) args[i]).Eval (bindings);
+           result = ((MExpression) args[i]).Eval (bindings, context);
        return result;
       }
 
@@ -514,13 +546,14 @@ namespace M17N.Core
        Console.Write (")");
       }
 
-      private static object whileclause (object[] args, MPlist bindings)
+      private static object whileclause (object[] args, MPlist bindings,
+                                        object context)
       {
        object result = 0;
 
-       while (check_condition ((MExpression) args[0], bindings))
+       while (check_condition ((MExpression) args[0], bindings, context))
          for (int i = 1; i < args.Length; i++)
-           result = ((MExpression) args[i]).Eval (bindings);
+           result = ((MExpression) args[i]).Eval (bindings, context);
        return result;
       }
 
@@ -545,7 +578,8 @@ namespace M17N.Core
        Console.Write (")");
       }
 
-      public static object define_function (object[] args, MPlist bindings)
+      public static object define_function (object[] args, MPlist bindings,
+                                           object context)
       {
        FunctionTable table = (FunctionTable) args[0];
        MSymbol sym = (MSymbol) args[1];
@@ -631,7 +665,7 @@ namespace M17N.Core
       args[1] = name;
       args[2] = new MPlist ();
       args[3] = expr;
-      Function.define_function (args, null);
+      Function.define_function (args, null, null);
     }
 
     private static Function Defun (string name, Evaluator evaluator,
@@ -794,7 +828,7 @@ namespace M17N.Core
            args[i++] = p.val;
        }
       if (function == Function.defun)
-       function.Call (args, null);
+       function.Call (args, null, null);
     }
 
     public MExpression (MSymbol sym)
@@ -811,9 +845,9 @@ namespace M17N.Core
       args[0] = obj;
     }
 
-    public object Eval (MPlist bindings)
+    public object Eval (MPlist bindings, object context)
     {
-      return function.Call (args, bindings);
+      return function.Call (args, bindings, context);
     }
 
     private void pp (string indent)
index ee0bfae..78f91ff 100644 (file)
@@ -27,7 +27,7 @@ namespace M17N.Input
     private static MSymbol Mat_plus = MSymbol.Of ("@+");
     private static MSymbol Mat_open_square_bracket = MSymbol.Of ("@[");
     private static MSymbol Mat_close_square_bracket = MSymbol.Of ("@]");
-
+    private static MSymbol Minsert = MSymbol.Of ("insert");
 
     internal class Variable
     {
@@ -51,7 +51,7 @@ namespace M17N.Input
 
       private static MSymbol char_to_symbol (int c)
       {
-       return MSymbol.Of (String.Format ("#%X", c));
+       return MSymbol.Of (String.Format ("#{0:X}", c));
       }
 
       public KeySeq (MPlist plist)
@@ -96,7 +96,10 @@ namespace M17N.Input
        else
          submaps.TryGetValue (keys[index], out sub);
        if (sub == null)
-         submaps[keys[index]] = sub = new Map ();
+         {
+           MSymbol sym = keys[index];
+           submaps[sym] = sub = new Map ();
+         }
        if (index + 1 < keys.Length)
          sub.Add (keys, index + 1, actions);
        else
@@ -123,7 +126,8 @@ namespace M17N.Input
        = new Dictionary<MSymbol, MExpression> ();
     }
 
-    private static Dictionary<MDatabase.Tag, MInputMethod> im_table;
+    private static Dictionary<MDatabase.Tag, MInputMethod> im_table
+      = new Dictionary<MDatabase.Tag, MInputMethod> ();
 
     private static MExpression.FunctionTable global_table
       = new MExpression.FunctionTable ();
@@ -151,50 +155,50 @@ namespace M17N.Input
     {
       MExpression.Defun (global_table, "insert",
                         new MExpression.Evaluator (insert),
-                        2, 2, typeof (MInputContext), typeof (MExpression));
+                        1, 1, typeof (MExpression));
       MExpression.Defun (global_table, "candidates",
                         new MExpression.Evaluator (insert_candidates),
-                        2, 2, typeof (MInputContext), typeof (object));
+                        1, 1, typeof (object));
       MExpression.Defun (global_table, "delete",
                         new MExpression.Evaluator (delete),
-                        2, 2, typeof (MInputContext), typeof (object));
+                        1, 1, typeof (object));
       MExpression.Defun (global_table, "select",
                         new MExpression.Evaluator (select),
-                        2, 2, typeof (MInputContext), typeof (object));
+                        1, 1, typeof (object));
       MExpression.Defun (global_table, "show",
                         new MExpression.Evaluator (show),
-                        1, 1, typeof (MInputContext));
+                        0, 0);
       MExpression.Defun (global_table, "hide",
                         new MExpression.Evaluator (hide),
-                        1, 1, typeof (MInputContext));
+                        0, 0);
       MExpression.Defun (global_table, "move",
                         new MExpression.Evaluator (move),
-                        2, 2, typeof (MInputContext), typeof (object));
+                        1, 1, typeof (object));
       MExpression.Defun (global_table, "mark",
                         new MExpression.Evaluator (mark),
-                        2, 2, typeof (MInputContext), typeof (MSymbol));
+                        1, 1, typeof (MSymbol));
       MExpression.Defun (global_table, "pushback",
                         new MExpression.Evaluator (pushback),
-                        2, 2, typeof (MInputContext), typeof (object));
+                        1, 1, typeof (object));
       MExpression.Defun (global_table, "pop",
                         new MExpression.Evaluator (pop),
-                        1, 1, typeof (MInputContext));
+                        0, 0);
       MExpression.Defun (global_table, "undo",
                         new MExpression.Evaluator (undo),
-                        2, 2, typeof (MInputContext), typeof (object));
+                        0, 1, typeof (object));
       MExpression.Defun (global_table, "commit",
                         new MExpression.Evaluator (commit),
-                        1, 1, typeof (MInputContext));
+                        0, 0);
       MExpression.Defun (global_table, "unhandle",
                         new MExpression.Evaluator (unhandle),
-                        1, 1, typeof (MInputContext));
+                        0, 0);
       MExpression.Defun (global_table, "shift",
                         new MExpression.Evaluator (shift),
-                        2, 2, typeof (MInputContext), typeof (MSymbol));
+                        1, 1, typeof (MSymbol));
       MExpression.Defun (global_table, "call",
                         new MExpression.Evaluator (call),
-                        3, -1, typeof (MInputContext), typeof (MSymbol),
-                        typeof (MSymbol), typeof (object));
+                        2, -1, typeof (MSymbol), typeof (MSymbol),
+                        typeof (object));
     }
 
     private MInputMethod (MDatabase.Tag tag)
@@ -311,14 +315,25 @@ namespace M17N.Input
     {
       if (! plist.IsPlist)
        return;
-      MPlist p = plist.Plist.Cons (MSymbol.symbol, Minput_method);
-      MDatabase.Tag tag = new MDatabase.Tag (ref p);
-      MInputMethod im;
-      try {
-       im_table.TryGetValue (tag, out im);
-      } catch {
+      MPlist p = plist.Plist;
+      MSymbol language, name, extra;
+      language = p.Symbol;
+      p = p.next;
+      if (! p.IsSymbol)
+       name = extra = MSymbol.nil;
+      else
+       {
+         name = p.Symbol;
+         p = p.next;
+         if (! p.IsSymbol)
+           extra = MSymbol.nil;
+         else
+           extra = p.Symbol;
+       }
+
+      MInputMethod im = MInputMethod.Get (language, name, extra);
+      if (im == null)
        return;
-      }
       plist = plist.next;
       if (! plist.IsSymbol)
        return;
@@ -379,6 +394,47 @@ namespace M17N.Input
          }
     }
 
+    private static void regulalize_command (MPlist plist)
+    {
+      if (plist.IsSymbol)
+       {
+         MSymbol sym = plist.Symbol;
+
+         if (sym == MSymbol.Of ("add"))
+           plist.val = MSymbol.Of ("+=");
+         regulalize_actions (plist.next);
+       }
+    }
+
+    private static void regulalize_actions (MPlist plist)
+    {
+      for (; ! plist.IsEmpty; plist = plist.next)
+       {
+         if (plist.IsMText)
+           {
+             MText mt = plist.Text;
+             MPlist p = new MPlist ();
+             p.Add (MSymbol.symbol, Minsert);
+             p.Add (MSymbol.mtext, mt);
+             plist.key = MSymbol.plist;
+             plist.val = p;
+           }
+         else if (plist.IsInteger)
+           {
+             int c = plist.Integer;
+             MPlist p = new MPlist ();
+             p.Add (MSymbol.symbol, Minsert);
+             p.Add (MSymbol.integer, c);
+             plist.key = MSymbol.plist;
+             plist.val = p;
+           }
+         else if (plist.IsPlist)
+           {
+             
+           }
+       }
+    }
+
     private void parse_maps (MPlist plist)
     {
       for (; ! plist.IsEmpty; plist = plist.next)
@@ -395,20 +451,22 @@ namespace M17N.Input
              {
                if (! pl.IsPlist)
                  continue;
+               MPlist p = pl.Plist;
                KeySeq keys;
-               if (pl.IsMText)
-                 keys = new KeySeq (pl.Text);
-               else if (pl.IsPlist)
-                 keys = new KeySeq (pl.Plist);
+               if (p.IsMText)
+                 keys = new KeySeq (p.Text);
+               else if (p.IsPlist)
+                 keys = new KeySeq (p.Plist);
                else
                  continue;
                if (keys.keys.Length == 0
                    && keys.keys[0] == null)
                  continue;
-               pl = pl.next;
-               if (pl.IsEmpty)
+               p = p.next;
+               if (p.IsEmpty)
                  continue;
-               MExpression expr = new MExpression (pl, local_table);
+               regulalize_actions (p);
+               MExpression expr = new MExpression (p, local_table);
                map.Add (keys, 0, expr);
              }
          }
@@ -443,13 +501,18 @@ namespace M17N.Input
                MPlist p = pl.Plist;
                if (! p.IsSymbol)
                  continue;
-               state.branches[p.Symbol]
-                 = new MExpression (p.next, local_table);
+               MSymbol map_name = p.Symbol;
+               p = p.next;
+               if (! p.IsEmpty)
+                 regulalize_actions (p);
+               state.branches[map_name]
+                 = new MExpression (p, local_table);
              }
          }
     }
 
-    public MInputMethod Get (MSymbol language, MSymbol name, MSymbol extra)
+    public static MInputMethod Get (MSymbol language, MSymbol name,
+                                   MSymbol extra)
     {
       MDatabase.Tag tag
        = new MDatabase.Tag (Minput_method, language, name, extra);
@@ -458,7 +521,8 @@ namespace M17N.Input
        return im;
       try {
        im = new MInputMethod (tag);
-      } catch {
+      } catch (Exception e) {
+       Console.WriteLine (e);
        im = null;
       }
       return im;
@@ -504,10 +568,11 @@ namespace M17N.Input
       adjust_markers (ic, from, to, mt);
     }
 
-    private static object insert (object[] args, MPlist bindings)
+    private static object insert (object[] args, MPlist bindings,
+                                 object context)
     {
-      MInputContext ic = (MInputContext) args[0];
-      object arg = ((MExpression) args[1]).Eval (bindings);
+      MInputContext ic = (MInputContext) context;
+      object arg = ((MExpression) args[0]).Eval (bindings, ic);
 
       if (arg is int)
        preedit_replace (ic, ic.cursor_pos, ic.cursor_pos, (int) arg);
@@ -522,82 +587,87 @@ namespace M17N.Input
     {
       private class Block
       {
-       public Block Prev, Next;
        public int Index;
        public object Data;
 
-       public Block (Block prev, int index, MPlist plist)
+       public Block (int index, MPlist plist)
        {
-         Prev = prev;
-         if (prev != null)
-           prev.Next = this;
          Index = index;
-         Data = plist.IsMText ? plist.Text : plist.Plist;
+         if (plist.IsMText)
+           Data = plist.Text;
+         else
+           Data = plist.Plist;
        }
 
        public int Count
        {
-         get { return (data is MText
-                       ? ((MText) data).Length
-                       : ((MPlist) data).Count); }
+         get { return (Data is MText
+                       ? ((MText) Data).Length
+                       : ((MPlist) Data).Count); }
        }
 
-       public Block First
+       public object this[int i]
        {
          get {
-           Block b;
-           for (b = this; b.Prev != null; b = n.Prev);
-           return b;
+           if (Data is MText) return ((MText) Data)[i];
+           return  ((MPlist) Data)[i];
          }
        }
+      }
 
-       public Block Last
-       {
-         get {
-           Block b;
-           for (b = this; b.Next != null; b = n.Next);
-           return b;
-         }
-       }
+      private Block[] blocks;
+      private int row = 0;
+      private int index = 0;
+      public object[] group;
 
-       public object this[int i]
-       {
-         get { return (data is MText
-                       ? ((MText) data)[i]
-                       : ((MPlist) data)[i]); }
-       }
+      private bool IsFixed { get { return group != null; } }
+      private int Total {
+       get {
+         Block last = blocks[blocks.Length - 1];
+         return last.Index + last.Count; }
       }
 
-      private Block block;
-      private int current_index = -1;
-      private int total_count = 0;
-      private object[] group = null;
+      public int Column {
+       get { return (IsFixed ? index % group.Length
+                     : index - blocks[row].Index); }
+      }
 
-      public Candidates (MPlist list, int column)
-      {
-       if (column > 0)
-         group = new object[column];
-       Block b = null;
-       int index;
-       for (index = 0; ! list.IsEmpty; list = list.next)
-         {
-           b = new Block (b, index, list);
-           if (index == 0)
-             block = b;
-           index += b.Count;
-         }
-       total_count = index;
+      public object Group {
+       get { return (IsFixed ? group : blocks[row].Data); }
       }
 
-      public int InGroupIndex
+      public int GroupLength
       {
        get {
-         return (group == null
-                 ? current_index - block.Index
-                 : current_index % group.Length);
+         if (IsFixed)
+           {
+             int nitems = group.Length;
+             int start = index - (index % nitems);
+             int total = Total;
+             return (start + nitems <= total ? nitems : total - start);
+           }
+         return blocks[row].Count;
        }
       }
 
+      public object Current {
+       get {
+         return (IsFixed ? group[index % group.Length]
+                 : blocks[row][index - blocks[row].Index]);
+       }
+      }
+
+      public Candidates (MPlist list, int column)
+      {
+       int nblocks = list.Count;
+
+       blocks = new Block[nblocks];
+       for (int i = 0, start = 0; i < nblocks; i++, list = list.next)
+         start += (blocks[i] = new Block (index, list)).Count;
+       if (column > 0)
+         group = new object[column];
+      }
+
       public static void Detach (MInputContext ic)
       {
        ic.preedit.PopProp (0, ic.preedit.Length, Mcandidates);
@@ -612,208 +682,137 @@ namespace M17N.Input
       // number of valid candidates in "group".  Update "block" if
       // necessary.  Return "group".
 
-      private object fill_group (int index, out int nitems)
+      private int fill_group (int start)
       {
-       int column = group.Length;
+       int nitems = group.Length;
+       int r = row;
+       Block b = blocks[r];
 
-       if (index > block.Index + column)
-         block = block.Last;
-       while (index < block.Index)
-         block = block.Prev;
+       if (start < b.Index)
+         while (start < b.Index)
+            b = blocks[--r];
+       else
+         while (start >= b.Index + b.Count)
+           b = blocks[++r];
+       row = r;
 
-       Block b = block;
        int count = b.Count;
-       int inblock = index - b.Index;
-       for (nitems = 0; ntimes < column; ntimes++)
+       start -= b.Index;
+       for (int i = 0; i < nitems; i++, start++)
          {
-           group[nitems] = b[inblock++];
-           if (inblock >= count)
+           if (start >= count)
              {
-               b = b.Next;
-               if (b == null)
-                 break;
+               r++;
+               if (r == blocks.Length)
+                 return i;
+               b = blocks[r];
                count = b.Count;
-               inblock = 0;
+               start = 0;
              }
+           group[i] = b[start];
          }
-       return group;
+       return nitems;
       }
 
-      // Update "block" to what contains the first candidate of the
-      // previous candidate-group, update "current_index", and update
-      // "group" if necessary.  Return the previous candidate-group.
-      // Set NITEMS to the number of valid candidates contained in
-      // that group.
+      // Update "row" to what contains the first candidate of
+      // the previous candidate-group, update "current_index", and
+      // update "group" if necessary.  Return the previous
+      // candidate-group.  Set NITEMS to the number of valid
+      // candidates contained in that group.
 
-      public object PrevGroup (out int nitems, out int ingroup)
+      public int PrevGroup ()
       {
-       object val;
+       int nitems;
+       int col = Column;
 
-       ingroup = InGroupIndex;
-       if (group == null)
+       if (IsFixed)
          {
-           block = (block.Prev != null) ? block.Prev : block.Last;
-           current_index = block.Index;
-           nitems = block.Count;
-           val = block.Data;
+           nitems = group.Length;
+           if ((index -= col + nitems) < 0)
+             index = (Total / nitems) * nitems;
+           nitems = fill_group (index);
          }
        else
          {
-           nitems = group.Length;
-           current_index -= ingroup + nitems;
-           if (current_index < 0)
-             current_index = (total_count / nitems) * nitems;
-           val = fill_group (current_index, out nitems);
+           row = row > 0 ? row-- : blocks.Length - 1;
+           nitems = blocks[row].Count;
+           index = blocks[row].Index;
          }
-       if (ingroup >= nitems)
-         ingroup = nitems - 1;
-       current_index += ingroup;
-       return val;
+       index += col < nitems ? col : nitems - 1;
+       return nitems;
       }
 
-      public object NextGroup (out int nitems)
+      public int NextGroup ()
       {
-       int ingroup = InGroupIndex;
-       object val;
+       int nitems;
+       int col = Column;
 
-       nitems = 0;
-       if (group == null)
+       if (IsFixed)
          {
-           block = (block.Next != null) ? block.Next : block.First;
-           current_index = block.Index;
-           nitems = block.Count;
-           val = block.Data;
+           nitems = group.Length;
+           if ((index += nitems - col) >= Total)
+             index = 0;
+           nitems = fill_group (index);
          }
        else
          {
-           nitems = group.Length;
-           current_index += column - ingroup;
-           if (current_index >= total_count)
-             current_index = 0;
-           val = fill_group (current_index, out nitems);
+           row = row < blocks.Length - 1 ? row + 1 : 0;
+           nitems = blocks[row].Count;
+           index = blocks[row].Count;
          }
-       if (ingroup >= nitems)
-         ingroup = nitems - 1;
-       current_index += ingroup;
-       return val;
+       index += col < nitems ? col : nitems - 1;
+       return nitems;
       }
 
-      public object Next (out int nitems)
+      public void Prev ()
       {
-       int ingroup = InGroupIndex + 1;
-       object val;
-       int index = current_index + 1;
+       int col = Column;
 
-       nitems = group == null ? block.Count : group.Length;
-
-       if (ingroup >= nitems)
+       if (col == 0)
          {
-           val = NextGroup (out nitems);
-           current_index = index < total_count ? index : 0;
-           return val;
-         }
-       if (group == null)
-         {
-           nitems = block.Count;
-           val = block.Data;
+           int nitems = PrevGroup ();
+           index += col < nitems - 1 ? col : nitems - 1;
          }
        else
-         {
-           nitems = group.Length;
-           val = group;
-         }
-       current_index++;
-       return val;
+         index--;
       }
 
-      public object Prev (out int nitems)
+      public void Next ()
       {
-       int ingroup = InGroupIndex - 1;
-       object val;
-       int index = current_index - 1;
+       int col = Column;
+       int nitems = GroupLength;
 
-       if (ingroup < 0)
-         {
-           val = PrevGroup (out nitems);
-           current_index = index >= 0 ? index : total_count - 1;
-           return val;
-         }
-       if (group == null)
+       if (col == nitems - 1)
          {
-           nitems = block.Count;
-           val = block.Data;
+           nitems = NextGroup ();
+           index -= Column;
          }
        else
-         {
-           nitems = group.Length;
-           val = group;
-         }
-       current_index--;
-       return val;
+         index++;
       }
 
-      public object First (out int nitems)
+      public void First ()
       {
-       if (group == null)
-         {
-           nitems = block.Count;
-           current_index = block.Index;
-           return block.Data;
-         }
-       nitems = group.Length;
-       current_index = (current_index / nitems) * nitems;
-       return group;
+       index -= Column;
       }
 
-      public object Last (out int nitems)
+      public void Last ()
       {
-       if (group == null)
-         {
-           nitems = block.Count;
-           current_index = block.Index + block.Count - 1;;
-           return block.Data;
-         }
-       nitems = group.Length;
-       current_index = (current_index / nitems) * nitems + nitems - 1;
-       return group;
+       index += GroupLength - (Column + 1);
       }
 
-      public object Select (int index, out int ingroup, out int len)
+      public void Select (int col)
       {
-       if (index < current_index)
-
-
-       MPlist prev;
-       return find_group (index, out ingroup_index, out text_len, out prev);
+       int maxcol = GroupLength - 1;
+       if (col > maxcol)
+         col = maxcol;
+       index = index - Column + col;
       }
 
-      private MPlist find_group (int index, out int ingroup_index,
-                                out int text_len, out MPlist previous)
+      public void Update (MInputContext ic)
       {
-       MPlist p;
-       int i = 0;
+       int from, to;
 
-       for (p = list, previous = null; ! p.IsEmpty; previous = p, p = p.next)
-         {
-           int len = p.IsMText ? p.Text.Length : p.Plist.Count;
-           if (index < i + len)
-             break;
-           i += len;
-         }
-       ingroup_index = index - i;
-       if (p.IsMText)
-         text_len = 1;
-       else
-         text_len = p.Plist[ingroup_index].Text.Length;
-       return p;
-      }
-
-      private void Update (MInputContext ic, object group, int ingroup)
-      {
-       int from, to, len;
-
-       if (current_index == index)
-         return;
        if (ic.candidates == null)
          {
            from = ic.cursor_pos;
@@ -825,47 +824,13 @@ namespace M17N.Input
            from = ic.candidate_from;
            to = ic.candidate_to;
          }
-       group = 
-       p = find_group (index, out ingroup, out len, out prev);
-       to = from + len;
-       if (p.IsMText)
-         preedit_replace (ic, from, to, p.Text[ingroup]);
-       else
-         preedit_replace (ic, from, to, p.Plist[ingroup].Text);
-       ic.preedit.PushProp (from, to, Mcandidates, this);
-       ic.cursor_pos = to;
-       ic.candidate_from = from;
-       ic.candidate_to = to;
-       ic.preedit_changed = true;
-       ic.cursor_pos_changed = true;
-       ic.candidate_changed = true;
-      }
 
-      private void Update (MInputContext ic, int index)
-      {
-       int from, to, len;
-       object group;
+       object candidate = ic.candidates.Current;
 
-       if (current_index == index)
-         return;
-       if (ic.candidates == null)
-         {
-           from = ic.cursor_pos;
-           to = ic.cursor_pos;
-           ic.candidates = this;
-         }
-       else
-         {
-           from = ic.candidate_from;
-           to = ic.candidate_to;
-         }
-       group = 
-       p = find_group (index, out ingroup, out len, out prev);
-       to = from + len;
-       if (p.IsMText)
-         preedit_replace (ic, from, to, p.Text[ingroup]);
+       if (candidate is MText)
+         preedit_replace (ic, from, to, (MText) candidate);
        else
-         preedit_replace (ic, from, to, p.Plist[ingroup].Text);
+         preedit_replace (ic, from, to, (int) candidate);
        ic.preedit.PushProp (from, to, Mcandidates, this);
        ic.cursor_pos = to;
        ic.candidate_from = from;
@@ -874,35 +839,28 @@ namespace M17N.Input
        ic.cursor_pos_changed = true;
        ic.candidate_changed = true;
       }
-
-      public void Prev (MInputContext ic) {}
-      public void Next (MInputContext ic) {}
-      public void First (MInputContext ic) {}
-      public void Last (MInputContext ic) {}
-      public void PrevGroup (MInputContext ic) {}
-      public void NextGroup (MInputContext ic) {}
-      public void Select (MInputContext ic, int index) {}
-
     }
 
-    private static object insert_candidates (object[] args, MPlist bindings)
+    private static object insert_candidates (object[] args, MPlist bindings,
+                                            object context)
     {
-      MInputContext ic = (MInputContext) args[0];
-      MPlist list = (MPlist) args[1];
+      MInputContext ic = (MInputContext) context;
+      MPlist list = (MPlist) args[0];
       int column = 0;
 
       MPlist slot = (MPlist) bindings.Find (Mcandidates_group_size);
       if (slot != null)
        column = slot.Integer;
-      Candidates candidtes = new Candidates (list);
-      candidates.Update (ic, 0);
+      Candidates candidates = new Candidates (list, column);
+      candidates.Update (ic);
       return 1;
     }
 
-    private static object select (object[] args, MPlist bindings)
+    private static object select (object[] args, MPlist bindings,
+                                 object context)
     {
-      MInputContext ic = (MInputContext) args[0];
-      object arg = args[1];
+      MInputContext ic = (MInputContext) context;
+      object arg = args[0];
 
       if (ic.candidates == null)
        return 0;
@@ -911,35 +869,50 @@ namespace M17N.Input
          MSymbol sym = (MSymbol) arg;
 
          if (sym == Mat_less_than)
-           ic.candidates.Update (ic, 0);
+           ic.candidates.First ();
          else if (sym == Mat_greater_than)
-           ic.candidates.Update (ic, -1);
+           ic.candidates.Last ();
          else if (sym == Mat_minus)
-           ic.candidates.Prev (ic);
+           ic.candidates.Prev ();
          else if (sym == Mat_plus)
-           ic.candidates.Next (ic);
+           ic.candidates.Next ();
          else if (sym == Mat_open_square_bracket)
-           ic.candidates.PrevGroup (ic);
+           ic.candidates.PrevGroup ();
          else if (sym == Mat_close_square_bracket)
-           ic.candidates.NextGroup (ic);
+           ic.candidates.NextGroup ();
+         else
+           return 0;
        }
       else if (arg is int)
-       ic.candidates.SelectInGroup (ic, (int) arg);
+       ic.candidates.Select ((int) arg);
+      ic.candidates.Update (ic);
       return 0;
     }
 
-    private static object delete (object[] args, MPlist bindings) { return 1; }
-    private static object show (object[] args, MPlist bindings) { return 1; }
-    private static object hide (object[] args, MPlist bindings) { return 1; }
-    private static object move (object[] args, MPlist bindings) { return 1; }
-    private static object mark (object[] args, MPlist bindings) { return 1; }
-    private static object pushback (object[] args, MPlist bindings) { return 1; }
-    private static object pop (object[] args, MPlist bindings) { return 1; }
-    private static object undo (object[] args, MPlist bindings) { return 1; }
-    private static object commit (object[] args, MPlist bindings) { return 1; }
-    private static object unhandle (object[] args, MPlist bindings) { return 1; }
-    private static object shift (object[] args, MPlist bindings) { return 1; }
-    private static object call (object[] args, MPlist bindings) { return 1; }
+    private static object delete (object[] args, MPlist bindings,
+                                 object context) { return 1; }
+    private static object show (object[] args, MPlist bindings,
+                               object context) { return 1; }
+    private static object hide (object[] args, MPlist bindings,
+                               object context) { return 1; }
+    private static object move (object[] args, MPlist bindings,
+                               object context) { return 1; }
+    private static object mark (object[] args, MPlist bindings,
+                               object context) { return 1; }
+    private static object pushback (object[] args, MPlist bindings,
+                                   object context) { return 1; }
+    private static object pop (object[] args, MPlist bindings,
+                              object context) { return 1; }
+    private static object undo (object[] args, MPlist bindings,
+                               object context) { return 1; }
+    private static object commit (object[] args, MPlist bindings,
+                                 object context) { return 1; }
+    private static object unhandle (object[] args, MPlist bindings,
+                                   object context) { return 1; }
+    private static object shift (object[] args, MPlist bindings,
+                                object context) { return 1; }
+    private static object call (object[] args, MPlist bindings,
+                               object context) { return 1; }
   }
 
   public class MInputContext
@@ -976,9 +949,9 @@ namespace M17N.Input
     private MText following_text;
     private bool key_unhandled;
 
-    internal MPlist GetCandidates (out int ingroup_index, out int text_len)
+    internal object GetCandidates (out int column)
     {
-      ingroup_index = text_len = 0;
+      column = 0;
       if (cursor_pos == 0)
        return null;
       MInputMethod.Candidates candidates
@@ -986,8 +959,8 @@ namespace M17N.Input
                                                     MInputMethod.Mcandidates);
       if (candidates == null)
        return null;
-      return candidates.FindGroup (candidate_index,
-                                  out ingroup_index, out text_len);
+      column = candidates.Column;
+      return candidates.Current;
     }
   }
 }
index 9097d70..994a248 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ EXAMPLE = symbol.exe plist.exe chartab.exe text.exe textprop.exe database.exe \
 TEST = rearsticky.exe frontsticky.exe bothsticky.exe \
        sensitive.exe frontsensitive.exe rearsensitive.exe
 
-DEBUG_FLAG =
+DEBUG_FLAG = -debug
 
 all: ${DLL} ${EXAMPLE} ${TEST}
 
@@ -23,10 +23,13 @@ M17NCore.dll: M17N.dll ${CORE_SRC}
 M17NExpr.dll: M17N.dll M17NCore.dll ${EXPR_SRC}
        $(CS) $(DEBUG_FLAG) -out:$@ -t:library -r:M17N.dll -r:M17NCore.dll ${EXPR_SRC}
 
-M17NIM.dll: M17N.dll M17NCore.dll M17NExpr.dll ${INPUT_SRC}
+M17NIM.dll: ${INPUT_SRC} M17N.dll M17NCore.dll M17NExpr.dll
        $(CS) $(DEBUG_FLAG) -out:$@ -t:library -r:M17N.dll -r:M17NCore.dll -r:M17NExpr.dll ${INPUT_SRC}
 
-input.exe: %.cs
+input.exe: input.cs ${DLL}
+       $(CS) $(DEBUG_FLAG) -codepage:65001 -r:M17N.dll -r:M17NCore -r:M17NExpr  -r:M17NIM.dll $<
+
+expr.exe: expr.cs
        $(CS) $(DEBUG_FLAG) -codepage:65001 -r:M17N.dll -r:M17NCore -r:M17NExpr  -r:M17NIM.dll $<
 
 %.exe: %.cs
diff --git a/expr.cs b/expr.cs
index 07aca8b..43d6bec 100644 (file)
--- a/expr.cs
+++ b/expr.cs
@@ -38,7 +38,7 @@ public class Test
       }
     Console.WriteLine (bindings);
     expr.PrettyPrint ();
-    Console.WriteLine ("\n  => " + expr.Eval (bindings));
+    Console.WriteLine ("\n  => " + expr.Eval (bindings, null));
     Console.WriteLine (bindings);
   }
 }