*** empty log message ***
authorhanda <handa>
Fri, 16 Oct 2009 05:48:50 +0000 (05:48 +0000)
committerhanda <handa>
Fri, 16 Oct 2009 05:48:50 +0000 (05:48 +0000)
MExpression.cs [deleted file]
MInputMethod.cs
XmlExpr.cs
xex.xml
xml.cs [new file with mode: 0644]

diff --git a/MExpression.cs b/MExpression.cs
deleted file mode 100644 (file)
index d8fbadf..0000000
+++ /dev/null
@@ -1,883 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.IO;
-using System.Xml;
-
-using M17N;
-using M17N.Core;
-
-namespace M17N.Core
-{
-  public class MExpression
-  {
-    private static MSymbol Mvarref = "symbol-value";
-    private static MSymbol Mdefun = "defun";
-    private static MSymbol Mcond = "cond";
-    private static MSymbol Mprogn = "progn";
-    private static MSymbol Mwhen = "when";
-
-    public class Domain
-    {
-      private Domain parent;
-      internal MPlist functions = new MPlist ();
-      internal MPlist bindings = new MPlist ();
-      private Stack<MPlist> boundaries = new Stack<MPlist> ();
-      internal Translator translator;
-      public object context;
-
-      internal Domain ()
-      {
-       boundaries.Push (bindings);
-      }
-
-      public Domain (object context) : this (basic, context) { }
-
-      public Domain (Domain parent, object context)
-      {
-       this.parent = parent;
-       this.context = context;
-       boundaries.Push (bindings);
-      }
-
-      public void AddTranslator (Translator translator)
-      {
-       if (this.translator == null)
-         this.translator = translator;
-       else
-         this.translator += translator;
-      }
-
-      public void Bind (MSymbol sym, object value)
-      {
-       bindings = bindings.Cons (sym, value);
-      }
-
-      public MPlist SetBoundary ()
-      {
-       boundaries.Push (bindings);
-       return bindings;
-      }
-
-      public void UnboundTo (MPlist boundary)
-      {
-       while (boundary != boundaries.Pop ());
-       while (bindings != boundary)
-         bindings = bindings.next;
-      }
-
-      public void Defun (string name, Builtin builtin, int min_arg, int max_arg)
-      {
-       Defun (name, builtin, min_arg, max_arg, false);
-      }
-
-      public void Defun (string name, Builtin builtin, int min_arg, int max_arg,
-                        bool specialp)
-      {
-       MSymbol sym = name;
-       Function func = (Function) functions.Get (sym);
-
-       if (func != null)
-         {
-           if (func.min_arg < min_arg || func.max_arg > max_arg)
-             throw new Exception ("Incompatible argument numbers to override: "
-                                  + name);
-           func.builtin = builtin;
-           func.lambda = null;
-           func.min_arg = min_arg;
-           func.max_arg = max_arg;
-           func.specialp = specialp;
-         }
-       else
-         {
-           func = new Function (sym, builtin, min_arg, max_arg, specialp);
-           functions = functions.Cons (sym, func);
-         }
-      }
-
-      public void Defun (MSymbol sym, MPlist args, MPlist body)
-      {
-       Function func = (Function) functions.Get (sym);
-
-       if (func != null)
-         {
-           int nargs = args == null ? 0 : args.Count;
-
-           if (func.min_arg < nargs || func.max_arg > nargs)
-             throw new Exception ("Incompatible argument numbers to override: "
-                                  + sym);
-           func.lambda.SetArgs (args);
-           func.lambda.SetBody (body, this);
-           func.builtin = null;
-         }
-       else
-         {
-           func = new Function (sym, args, body, this);
-           functions = functions.Cons (sym, func);
-         }         
-      }
-
-      public void Defun (XmlNode node)
-      {
-       MSymbol sym = node.Attributes["id"].Value;
-       Function func = (Function) functions.Get (sym);
-
-       if (func != null)
-         {
-           XmlNode args = node.FirstChild;
-           int nargs = args.Name == "args" ? args.ChildNodes.Count : 0;
-
-           if (func.min_arg < nargs || func.max_arg > nargs)
-             throw new Exception ("Incompatible argument numbers to override: "
-                                  + sym);
-           func.lambda.Set (node, this);
-           func.builtin = null;
-         }
-       else
-         {
-           func = new Function (sym, node, this);
-           functions = functions.Cons (sym, func);
-         }         
-      }
-
-      internal Function GetFunc (MSymbol name)
-      {
-       Function func = (Function) functions.Get (name);
-
-       if (func == null)
-         {
-           if (parent != null)
-             return parent.GetFunc (name);
-           throw new Exception ("Unknown function: " + name);
-         }
-       return func;
-      }
-
-      public bool CopyFunc (Domain domain, MSymbol name)
-      {
-       Function func = (Function) functions.Get (name);
-       if (func == null)
-         return false;
-       domain.functions = domain.functions.Cons (name, func);
-       return true;
-      }
-
-      public void CopyFunc (Domain domain)
-      {
-       foreach (MPlist p in functions)
-         domain.functions = domain.functions.Cons (p.key, p.val);
-      }
-
-      public object GetValue (MSymbol name)
-      {
-       MPlist slot = bindings.Find (name);
-
-       if (slot == null)
-         {
-           if (parent != null)
-             return parent.GetValue (name);
-           throw new Exception ("Unbound variable: " + name);
-         }
-       return slot.val;
-      }
-
-      public object SetValue (MSymbol name, object val)
-      {
-       MPlist boundary = boundaries.Peek ();
-
-       for (MPlist plist = bindings; plist != boundary; plist = plist.next)
-         if (plist.key == name)
-           {
-             plist.val = val;
-             return val;
-           }
-       bindings = bindings.Cons (name, val);
-       return val;
-      }
-
-      public bool IsBound (MSymbol name)
-      {
-       return (bindings.Find (name) != null);
-      }
-
-      public void Translate (MPlist plist)
-      {
-       if (parent != null)
-         parent.Translate (plist);
-       if (translator != null)
-         for (MPlist p = plist; ! p.IsEmpty; p = p.next)
-           translator (p, this);
-      }
-
-      public override string ToString ()
-      {
-       string str = "<(functions";
-       foreach (MPlist p in functions)
-         str += " " + p.key;
-       str += ") (bindings " + bindings + ")";
-       if (context != null)
-         str += " (" + context + ")";
-       str += ">";
-       return str;
-      }
-    }
-
-    public delegate object Builtin (MExpression[] args, Domain domain);
-    public delegate void Translator (MPlist plist, Domain domain);
-
-    internal class Function
-    {
-      internal class Lambda
-      {
-       internal MSymbol[] args;
-       internal MExpression[] body;
-
-       public Lambda (MPlist args, MPlist body, Domain domain)
-       {
-         SetArgs (args);
-         SetBody (body, domain);
-       }
-
-       public Lambda (XmlNode node, Domain domain)
-       {
-         Set (node, domain);
-       }
-
-       public void SetArgs (MPlist args)
-       {
-         int len = args == null ? 0 : args.Count;
-
-         if (this.args == null)
-           this.args = new MSymbol[len];
-         for (int i = 0; i < len; i++, args = args.next)
-           this.args[i] = args.Symbol;
-       }
-
-       public void SetBody (MPlist body, Domain domain)
-       {
-         int len = body == null ? 0 : body.Count;
-         if (this.body == null)
-           this.body = new MExpression[len];
-         for (int i = 0; i < len; i++, body = body.next)
-           {
-             domain.Translate (body);
-             this.body[i] = new MExpression (body.key, body.val, domain);
-           }
-       }
-
-       public void Set (XmlNode node, Domain domain)
-       {
-         XmlNodeList body = node.ChildNodes;
-         int idx = 0;
-
-         if (body[0].Name == "args")
-           {
-             XmlNodeList args = body[0].ChildNodes;
-             if (this.args == null)
-               this.args = new MSymbol[args.Count];
-             for (int i = 0; i < args.Count; i++)
-               this.args[i] = args[i].InnerText;
-             idx++;
-           }
-         else if (this.args == null)
-           this.args = new MSymbol[0];
-         if (this.body == null)
-           this.body = new MExpression[body.Count - idx];
-         for (int i = 0; idx < body.Count; i++, idx++)
-           this.body[i] = new MExpression (body[idx], domain);
-       }
-      }
-
-      public readonly MSymbol Name;
-      public Builtin builtin;
-      public int min_arg, max_arg;
-      internal Lambda lambda;
-      public bool specialp = false;
-
-      internal static Function ignore, varref, block;
-
-      public Function (MSymbol name, Builtin builtin,
-                      int min_arg, int max_arg, bool specialp)
-      {
-       Name = name;
-       this.builtin = builtin;
-       this.min_arg = min_arg;
-       this.max_arg = max_arg;
-       this.specialp = specialp;
-      }
-
-      internal Function (MSymbol name, MPlist args, MPlist body,
-                        Domain domain)
-      {
-       Name = name;
-       lambda = new Lambda (args, body, domain);
-       this.min_arg = this.max_arg = lambda.args.Length;
-      }
-
-      internal Function (MSymbol name, XmlNode node, Domain domain)
-      {
-       Name = name;
-       lambda = new Lambda (node, domain);
-       this.min_arg = this.max_arg = lambda.args.Length;
-      }
-
-      private Function ()
-      {
-       Name = MSymbol.nil;
-      }
-
-      static Function ()
-      {
-       ignore = new Function ();
-       varref = new Function (Mvarref, get_value, 1, 1, true);
-       block = new Function (Mprogn, progn, 0, -1, true);
-      }
-
-      private static object get_value (MExpression[] args, Domain domain)
-      {
-       return domain.GetValue ((MSymbol) args[0].val);
-      }
-
-      public object Call (MExpression[] args, Domain domain)
-      {
-       if (builtin != null)
-         {
-           if (! specialp)
-             foreach (MExpression e in args)
-               e.Eval (domain);
-           return builtin (args, domain);
-         }
-       if (lambda == null)
-         return null;
-       MPlist orig_bindings = domain.bindings;
-       object result = false;
-       try {
-         int i = 0;
-         foreach (MSymbol arg in lambda.args)
-           domain.Bind (arg, args[i++].Eval (domain));
-         foreach (MExpression e in lambda.body)
-           result = e.Eval (domain);
-       } finally {
-         domain.bindings = orig_bindings;
-       }
-       return result;
-      }
-    }
-
-    private static Domain basic;
-
-    static MExpression ()
-    {
-      basic = new Domain ();
-
-      basic.Defun ("set", set_value, 2, 2, true);
-      basic.Defun ("=", set_value, 2, 2, true);
-      basic.Defun ("!", not, 1, 1, false);
-      basic.Defun ("+", plus, 2, -1, false);
-      basic.Defun ("*", multi, 2, -1, false);
-      basic.Defun ("-", minus, 1, -1, false);
-      basic.Defun ("/", divide, 2, -1, false);
-      basic.Defun ("%", percent, 2, -1, false);
-      basic.Defun ("|", logior, 2, -1, false);
-      basic.Defun ("&", logand, 2, -1, false);
-      basic.Defun ("+=", pluseq, 2, -1, true);
-      basic.Defun ("*=", multieq, 2, -1, true);
-      basic.Defun ("-=", minuseq, 2, -1, true);
-      basic.Defun ("/=", divideeq, 2, -1, true);
-      basic.Defun ("%=", percenteq, 2, -1, true);
-      basic.Defun ("|=", logioreq, 2, -1, true);
-      basic.Defun ("&=", logandeq, 2, -1, true);
-      basic.Defun ("<<", lshift, 2, 2, false);
-      basic.Defun (">>", rshift, 2, 2, false);
-      basic.Defun ("<<=", lshifteq, 2, 2, true);
-      basic.Defun (">>=", rshifteq, 2, 2, true);
-      basic.Defun ("==", eq, 2, -1, false);
-      basic.Defun ("!=", noteq, 2, 2, false);
-      basic.Defun ("<", less, 2, -1, false);
-      basic.Defun ("<=", lesseq, 2, -1, false);
-      basic.Defun (">", more, 2, -1, false);
-      basic.Defun (">=", moreeq, 2, -1, false);
-      basic.Defun ("progn", progn, 0, -1, true);
-      basic.Defun ("if", ifclause, 2, -1, true);
-      basic.Defun ("when", whenclause, 1, -1, true);
-      basic.Defun ("while", whileclause, 1, -1, true);
-
-      basic.AddTranslator (new Translator (translate_cond));
-    }
-
-    private static object set_value (MExpression[] args, Domain domain)
-    {
-      return domain.SetValue ((MSymbol) args[0].args[0].val,
-                             args[1].Eval (domain));
-    }
-
-    private static object not (MExpression[] args, Domain domain)
-    {
-      if (args[0].val is int)
-       return (int) args[0].val == 0;
-      if (args[0].val is bool)
-       return ! ((bool) args[0].val);
-      return true;
-    }
-
-    private static object plus (MExpression[] args, Domain domain)
-    {
-      if (args[0].val is int)
-       {
-         int n = 0;
-         foreach (MExpression e in args)
-           n += (int) e.val;
-         return n;
-       }
-      else if (args[0].val is MText)
-       {
-         MText mt = new MText ();
-         foreach (MExpression e in args)
-           mt += (MText) e.val;
-         return mt;
-       }
-      throw new Exception ("Not an integer nor MText: " + args[0].val);
-    }
-
-      private static object multi (MExpression[] args, Domain domain)
-      {
-       int n = 1;
-       foreach (MExpression e in args)
-         n *= (int) e.val;
-       return n;
-      }
-
-      private static object minus (MExpression[] args, Domain domain)
-      {
-       int n = (int) args[0].val;
-       if (args.Length == 1)
-         return - n;
-       for (int i = 1; i < args.Length; i++)
-         n -= (int) args[i].val;
-       return n;
-      }
-
-      private static object divide (MExpression[] args, Domain domain)
-      {
-       int n = (int) args[0].val;
-       for (int i = 1; i < args.Length; i++)
-         n /= (int) args[i].val;
-       return n;
-      }
-
-      private static object percent (MExpression[] args, Domain domain)
-      {
-       int n = (int) args[0].val;
-       for (int i = 1; i < args.Length; i++)
-         n %= (int) args[i].val;
-       return n;
-      }
-
-      private static object logior (MExpression[] args, Domain domain)
-      {
-       int n = 0;
-       foreach (MExpression e in args)
-         n |= (int) e.val;
-       return n;
-      }
-
-      private static object logand (MExpression[] args, Domain domain)
-      {
-       int n = 0;
-       foreach (MExpression e in args)
-         n &= (int) e.val;
-       return n;
-      }
-
-      private static object pluseq (MExpression[] args, Domain domain)
-      {
-       MSymbol sym = (MSymbol) args[0].args[0].val;
-       object val = domain.GetValue (sym);
-
-       if (val is int)
-         {
-           int n = (int) val;
-           for (int i = 1; i < args.Length; i++)
-             n += (int) args[i].Eval (domain);
-           val = n;
-         }
-       else if (val is MText)
-         {
-           MText mt = (MText) val;
-           for (int i = 1; i < args.Length; i++)
-             mt.Cat ((MText) args[i].Eval (domain));
-           val = mt;
-         }
-       domain.SetValue (sym, val);
-       return val;
-      }
-
-      private static object multieq (MExpression[] args, Domain domain)
-      {
-       MSymbol sym = (MSymbol) args[0].args[0].val;
-       int n = (int) domain.GetValue (sym);
-
-       for (int i = 1; i < args.Length; i++)
-         n *= (int) args[i].Eval (domain);
-       return domain.SetValue (sym, (object) n);
-      }
-
-      private static object minuseq (MExpression[] args, Domain domain)
-      {
-       MSymbol sym = (MSymbol) args[0].args[0].val;
-       int n = (int) domain.GetValue (sym);
-
-       for (int i = 1; i < args.Length; i++)
-         n -= (int) args[i].Eval (domain);
-       return domain.SetValue (sym, (object) n);
-      }
-
-      private static object divideeq (MExpression[] args, Domain domain)
-      {
-       MSymbol sym = (MSymbol) args[0].args[0].val;
-       int n = (int) domain.GetValue (sym);
-
-       for (int i = 1; i < args.Length; i++)
-         n /= (int) args[i].Eval (domain);
-       return domain.SetValue (sym, (object) n);
-      }
-
-      private static object percenteq (MExpression[] args, Domain domain)
-      {
-       MSymbol sym = (MSymbol) args[0].args[0].val;
-       int n = (int) domain.GetValue (sym);
-
-       for (int i = 1; i < args.Length; i++)
-         n %= (int) args[i].Eval (domain);
-       return domain.SetValue (sym, (object) n);
-      }
-
-      private static object logioreq (MExpression[] args, Domain domain)
-      {
-       MSymbol sym = (MSymbol) args[0].args[0].val;
-       int n = (int) domain.GetValue (sym);
-
-       for (int i = 1; i < args.Length; i++)
-         n |= (int) args[i].Eval (domain);
-       return domain.SetValue (sym, (object) n);
-      }
-
-      private static object logandeq (MExpression[] args, Domain domain)
-      {
-       MSymbol sym = (MSymbol) args[0].args[0].val;
-       int n = (int) domain.GetValue (sym);
-
-       for (int i = 1; i < args.Length; i++)
-         n &= (int) args[i].Eval (domain);
-       return domain.SetValue (sym, (object) n);
-      }
-
-      private static object lshift (MExpression[] args, Domain domain)
-      {
-       return (int) args[0].val << (int) args[1].val;
-      }
-
-      private static object lshifteq (MExpression[] args, Domain domain)
-      {
-       MSymbol sym = (MSymbol) args[0].args[0].val;
-       int n = (int) domain.GetValue (sym);
-
-       n <<= (int) args[1].Eval (domain);
-       return domain.SetValue (sym, (object) n);
-      }
-
-      private static object rshift (MExpression[] args, Domain domain)
-      {
-       return (int) args[0].val >> (int) args[1].val;
-      }
-
-      private static object rshifteq (MExpression[] args, Domain domain)
-      {
-       MSymbol sym = (MSymbol) args[0].args[0].val;
-       int n = (int) domain.GetValue (sym);
-
-       n >>= (int) args[1].Eval (domain);
-       return domain.SetValue (sym, (object) n);
-      }
-
-      private static object eq (MExpression[] args, Domain domain)
-      {
-       int n = (int) args[0].val;
-
-       for (int i = 1; i < args.Length; i++)
-         if (n != (int) args[i].val)
-           return false;
-       return true;
-      }
-
-      private static object noteq (MExpression[] args, Domain domain)
-      {
-       return ((int) args[0].val != (int) args[1].val);
-      }
-
-      private static object less (MExpression[] args, Domain domain)
-      {
-       int n = (int) args[0].val;
-
-       for (int i = 1; i < args.Length; i++)
-         {
-           int n1 = (int) args[i].val;
-           if (n >= n1)
-             return false;
-           n = n1;
-         }
-       return true;
-      }
-
-      private static object lesseq (MExpression[] args, Domain domain)
-      {
-       int n = (int) args[0].val;
-       for (int i = 1; i < args.Length; i++)
-         {
-           int n1 = (int) args[i].val;
-           if (n > n1)
-             return false;
-           n = n1;
-         }
-       return true;
-      }
-
-      private static object more (MExpression[] args, Domain domain)
-      {
-       int n = (int) args[0].val;
-       for (int i = 1; i < args.Length; i++)
-         {
-           int n1 = (int) args[i].val;
-           if (n <= n1)
-             return false;
-           n = n1;
-         }
-       return true;
-      }
-
-      private static object moreeq (MExpression[] args, Domain domain)
-      {
-       int n = (int) args[0].val;
-       for (int i = 1; i < args.Length; i++)
-         {
-           int n1 = (int) args[i].val;
-           if (n < n1)
-             return false;
-           n = n1;
-         }
-       return true;
-      }
-
-      private static object progn (MExpression[] args, Domain domain)
-      {
-       object result = false;
-
-       foreach (MExpression e in args)
-         result = e.Eval (domain);
-       return result;
-      }
-
-      private static bool check_condition (MExpression condition, Domain domain)
-      {
-       object result = condition.Eval (domain);
-       return (result is bool ? (bool) result
-               : result is int ? ((int) result) != 0
-               : true);
-      }
-
-      private static object ifclause (MExpression[] args, Domain domain)
-      {
-       object result = false;
-
-       if (check_condition (args[0], domain))
-         result = args[1].Eval (domain);
-       else
-         for (int i = 2; i < args.Length; i++)
-           result = args[i].Eval (domain);
-       return result;
-      }
-
-      private static object whenclause (MExpression[] args, Domain domain)
-      {
-       object result = false;
-
-       if (check_condition (args[0], domain))
-         for (int i = 1; i < args.Length; i++)
-           result = args[i].Eval (domain);
-       return result;
-      }
-
-      private static object whileclause (MExpression[] args, Domain domain)
-      {
-       while (check_condition (args[0], domain))
-         for (int i = 1; i < args.Length; i++)
-           args[i].Eval (domain);
-       return false;
-      }
-
-    // (cond (COND1 ...) (COND2 ...) ...)
-    //   => (cond (when COND1 ...) (when COND2 ...) ...)
-    private static void translate_cond (MPlist plist, Domain domain)
-    {
-      if (plist.IsPlist)
-       {
-         plist = plist.Plist;
-         if (plist.IsSymbol && plist.Symbol == Mcond)
-           {
-             plist.val = Mprogn;
-             for (plist = plist.next; ! plist.IsEmpty; plist = plist.next)
-               {
-                 if (! plist.IsPlist)
-                   throw new Exception ("Invalid cond form: " + plist);
-                 plist.Plist.Push (MSymbol.symbol, Mwhen);
-               }               
-           }
-       }
-    }
-
-    private Function function;
-    private MExpression[] args;
-    private object val;
-
-    public MExpression[] Args { get { return args; } }
-    public object Val { get { return val; } }
-
-    private MExpression (object val)
-    {
-      this.val = val;
-    }
-
-    // EXPR = SYMBOL | MTEXT | INTEGER | FUNCALL | PROGN
-    // FUNCALL = '(' SYMBOL EXPR* ')'
-    // PROGN = '(' EXPR * ')'
-    private MExpression (MSymbol key, object val, Domain domain)
-    {
-      if (key == MSymbol.symbol)
-       {
-         function = Function.varref;
-         args = new MExpression[1];
-         args[0] = new MExpression (val);
-       }
-      else if (key == MSymbol.integer
-              || key == MSymbol.mtext)
-       {
-         this.val = val;
-       }
-      else if (key == MSymbol.plist)
-       {
-         MPlist p = (MPlist) val;
-
-         if (p.IsSymbol)
-           {
-             MSymbol sym = p.Symbol;
-
-             if (sym == Mdefun)
-               {
-                 p = p.next;
-                 if (! p.IsSymbol)
-                   throw new Exception ("Invalid function argument: "
-                                        + p.val);
-                 sym = p.Symbol;
-                 p = p.next;
-                 if (! p.IsPlist)
-                   throw new Exception ("Invalid function argument: "
-                                        + p.val);
-                 domain.Defun (sym, p.Plist, p.next);
-                 // This Mexpression is just a dummy.
-               }
-             else
-               {
-                 function = domain.GetFunc (sym);
-                 p = p.next;
-                 int nargs = p.Count;
-                 if (nargs < function.min_arg
-                     || (function.max_arg >= 0 && nargs > function.max_arg))
-                   throw new Exception ("Invalid number of arguments to: "
-                                        + sym + " " + nargs);
-                 args = new MExpression[nargs];
-                 for (int i = 0; i < nargs; i++, p = p.next)
-                   {
-                     domain.Translate (p);
-                     args[i] = new MExpression (p.key, p.val, domain);
-                   }
-               }
-           }
-         else
-           {
-             args = new MExpression[1];
-             args[0] = new MExpression (p, domain);
-           }
-       }
-      else
-       throw new Exception ("Invalid expression: " + key + ":" + val);
-    }
-
-    public MExpression (MPlist plist, Domain domain)
-    {
-      function = Function.block;
-      args = new MExpression[plist.Count];
-      for (int i = 0; ! plist.IsEmpty; i++, plist = plist.next)
-       {
-         domain.Translate (plist);
-         args[i] = new MExpression (plist.key, plist.val, domain);
-       }
-    }
-
-    public MExpression (XmlNode node, Domain domain)
-    {
-      MSymbol sym = node.Name;
-
-      function = domain.GetFunc (sym);
-
-      XmlAttributeCollection attrs = node.Attributes;
-
-      int nargs = attrs.Count + node.ChildNodes.Count;
-      if (nargs < function.min_arg
-         || (function.max_arg >= 0 && nargs > function.max_arg))
-       throw new Exception ("Invalid number of arguments: " + node.InnerXml);
-      args = new MExpression[nargs];
-      int i;
-      for (i = 0; i < attrs.Count; i++)
-       {
-         string str = sttrs[i].Value;
-
-       }
-    }
-
-    public object Eval (Domain domain)
-    {
-      if (function == null)
-       {
-         if (val is MSymbol)
-           val = domain.GetValue ((MSymbol) val);
-       }
-      else
-       val = function.Call (args, domain);
-      return val;
-    }
-
-    public override string ToString ()
-    {
-      string str;
-
-      if (function != null)
-       {
-         str = "(" + function.Name.Name;
-         if (args != null)
-           foreach (MExpression e in args)
-             str += " " + e.ToString ();
-         str += ")";
-       }
-      else if (val != null)
-       {
-         if (val is MText)
-           str = "\"" + (string) ((MText) val) + "\"";
-         else
-           str = val.ToString ();
-       }
-      else
-       str = "()";
-      return str;
-    }
-  }
-}
index f2fe910..60e48d0 100644 (file)
@@ -946,12 +946,28 @@ namespace M17N.Input
        index += GroupLength - (Column + 1);
       }
 
-      public void Select (int col)
+      public object Select (int col)
       {
        int maxcol = GroupLength - 1;
        if (col > maxcol)
          col = maxcol;
        index = index - Column + col;
+       return Current;
+      }
+
+      public object Select (Selector selector)
+      {
+       switch (selector.Tag)
+         {
+         case '<': First (); break;
+         case '>': Last (); break;
+         case '-': Prev (); break;
+         case '+': Next (); break;
+         case '[': PrevGroup (); break;
+         case ']': NextGroup (); break;
+         default: break;
+         }
+       return Current;
       }
 
       public override string ToString ()
@@ -969,22 +985,20 @@ namespace M17N.Input
       static Selector ()
        {
          selectors = new Dictionary<MSymbol, Selector> ();
-         MSymbol[] symlist = new MSymbol[] { "@<", "@=", "@>", "@-", "@+",
-                                             "@[", "@]" };
-         foreach (MSymbol s in symlist)
-           selectors[s] = new Selector (s);
-         selectors["@first"] = new Selector ('<');
-         selectors["@current"] = new Selector ('=');
-         selectors["@last"] = new Selector ('>');
-         selectors["@previous"] = new Selector ('-');
-         selectors["@next"] = new Selector ('+');
-         selectors["@previous-candidate-change"] = new Selector ('[');
-         selectors["@next-candidate-change"] = new Selector (']');
+         selectors ["@<"] = selectors["@first"] = new Selector ('<');
+         selectors ["@="] = selectors["@current"] = new Selector ('=');
+         selectors ["@>"] = selectors["@last"] = new Selector ('>');
+         selectors ["@-"] = selectors["@previous"] = new Selector ('-');
+         selectors ["@+"] = selectors["@next"] = new Selector ('+');
+         selectors ["@["] = selectors["@previous-candidate-change"]
+           = new Selector ('[');
+         selectors ["@]"] = selectors["@next-candidate-change"]
+           = new Selector (']');
        }
 
-      private char tag;
+      private readonly char tag;
 
-      private Selector (MSymbol sym) { tag = sym.Name[1]; }
+      public char Tag { get { return tag; } }
 
       private Selector (char tag) { this.tag = tag; }
 
@@ -1000,20 +1014,6 @@ namespace M17N.Input
          throw new Exception ("Invalid selector name: " + name);
        return selector;
       }
-
-      public void Select (Candidates candidates)
-      {
-       switch (tag)
-         {
-         case '<': candidates.First (); break;
-         case '>': candidates.Last (); break;
-         case '-': candidates.Prev (); break;
-         case '+': candidates.Next (); break;
-         case '[': candidates.PrevGroup (); break;
-         case ']': candidates.NextGroup (); break;
-         default: break;
-         }
-      }
     }
 
     internal class Map
@@ -2043,7 +2043,7 @@ namespace M17N.Input
 
            if (! p.IsSymbol)
              continue;
-           domain.Defun ((Xex.Symbol) p.Symbol.Name, false, null, null, true);
+           domain.Defun ((Xex.Symbol) p.Symbol.Name, null, null, true);
          }
       for (MPlist pl = plist; ! pl.IsEmpty; pl = pl.next)
        if (pl.IsPlist)
@@ -2052,7 +2052,7 @@ namespace M17N.Input
 
            if (! p.IsSymbol)
              continue;
-           domain.Defun ((Xex.Symbol) p.Symbol.Name, false, null,
+           domain.Defun ((Xex.Symbol) p.Symbol.Name, null,
                          parse_actions (p.next, false), false);
          }
     }
@@ -2157,9 +2157,9 @@ namespace M17N.Input
          if (args[0].IsInt)
            candidate = can.Select (args[0].Intval);
          else
-           candidate = ((Selector) args[0].Objval).Select (can);
+           candidate = can.Select ((Selector) args[0].Objval);
          if (candidate is MText)
-           ic.insert ((MTtext) candidate, can);
+           ic.insert ((MText) candidate, can);
          else
            ic.insert ((int) candidate, can);
        }
@@ -2450,8 +2450,7 @@ namespace M17N.Input
        preedit.Ins (from, c);
        if (candidates != null)
          {
-           preedit.PushProp (cursor_pos - 1, cursor_pos,
-                           Mcandidates, candidates);
+           preedit.PushProp (from, from + 1, Mcandidates, candidates);
            changed |= (ChangedStatus.Preedit | ChangedStatus.CursorPos
                        | CandidateAll);
          }
@@ -2464,12 +2463,11 @@ namespace M17N.Input
        preedit[from, to] = mt;
        if (candidates != null)
          {
-           preedit.PushProp (cursor_pos - mt.Length, cursor_pos,
-                             Mcandidates, candidates);
+           preedit.PushProp (from, from + mt.Length, Mcandidates, candidates);
            changed |= (ChangedStatus.Preedit | ChangedStatus.CursorPos
                        | CandidateAll);
          }
-       adjust_markers (from, to, mt.Length);
+       adjust_markers (from, to, mt == null ? 0 : mt.Length);
       }
 
       internal void insert (int c, Candidates candidates)
index a07ab65..ba26919 100644 (file)
@@ -93,7 +93,6 @@ namespace System.Xml.Expression
     private static Symbol Qdefun = "defun";
     private static Symbol Qfname = "fname";
     private static Symbol Qargs = "args";
-    private static Symbol Qargs_unevalled = "args-unevalled";
     private static Symbol Qfixed = "fixed";
     private static Symbol Qoptional = "optional";
     private static Symbol Qrest = "rest";
@@ -103,7 +102,7 @@ namespace System.Xml.Expression
     private static Symbol Qdescription = "description";
     private static Symbol Qrange = "range";
 
-    public abstract class Function
+    internal abstract class Function
     {
       public Symbol name;
       public int min_arg, max_arg;
@@ -170,60 +169,135 @@ namespace System.Xml.Expression
        }
       }
 
-      internal class Lambda : Function
+      private static void parse_head (Domain domain, XmlNode node,
+                                     out Symbol name,
+                                     out int min_arg, out int max_arg,
+                                     out Variable[] args)
+      {
+       int nfixed = 0;
+       int noptional = 0;
+       int nrest = 0;
+       name = node.Attributes[Qfname].Value;
+           
+       node = node.FirstChild;
+       if (node != null && node.Name == Qargs)
+         {
+           XmlNode n;
+           for (n = node.FirstChild; n != null; n = n.NextSibling)
+             {
+               if (n.Name == Qfixed)
+                 nfixed++;
+               else if (n.Name == Qoptional)
+                 noptional++;
+               else if (n.Name == Qrest)
+                 nrest++;
+               else
+                 throw new Exception ("Invalid argument type: " + n);
+             }
+           min_arg = nfixed;
+           max_arg = nfixed + noptional + nrest;
+           args = new Variable[max_arg];
+           n = node.FirstChild;
+           for (int i = 0; i < max_arg; n = n.NextSibling)
+             args[i++] = domain.Defvar ((Symbol) n.Attributes[0].Value);
+           if (nrest == 1)
+             max_arg = - max_arg;
+         }
+       else
+         {
+           min_arg = max_arg = 0;
+           args = null;
+         }
+      }
+
+      private static void parse_body (Domain domain, XmlNode node,
+                                     out Term[] body)
+      {
+       for (node = node.FirstChild; node != null; node = node.NextSibling)
+         if (node.Name != Qdescription
+             && node.Name != Qargs)
+           break;
+       int nterms = 0;
+       for (XmlNode n = node; n != null; n = n.NextSibling)
+         nterms++;
+       if (nterms > 0)
+         {
+           body = new Term[nterms];
+           for (nterms = 0; node != null; node = node.NextSibling, nterms++)
+             body[nterms] = new Term (domain, node);
+         }
+       else
+         body = null;
+      }
+
+      internal class Macro : Function
       {
-       internal bool args_evalled;
        internal Variable[] args;
        internal Term[] body;
 
-       public Lambda (Domain domain, XmlNode node)
+       public Macro (Domain domain, XmlNode node)
          {
-           int nfixed = 0;
-           int noptional = 0;
-           int nrest = 0;
-           name = node.Attributes[Qfname].Value;
-           
-           node = node.FirstChild;
-           if (node != null
-               && (node.Name == Qargs || node.Name == Qargs_unevalled))
-             {
-               XmlNode n;
-               args_evalled = node.Name == Qargs;
-               for (n = node.FirstChild; n != null; n = n.NextSibling)
-                 {
-                   if (n.Name == Qfixed)
-                     nfixed++;
-                   else if (n.Name == Qoptional)
-                     noptional++;
-                   else if (n.Name == Qrest)
-                     nrest++;
-                   else
-                     throw new Exception ("Invalid argument type: " + n);
-                 }
-               min_arg = nfixed;
-               max_arg = nfixed + noptional + nrest;
-               args = new Variable[max_arg];
-               n = node.FirstChild;
-               for (int i = 0; i < max_arg; n = n.NextSibling)
-                 args[i++] = domain.Defvar ((Symbol) n.Attributes[0].Value);
-               if (nrest == 1)
-                 max_arg = - max_arg;
-             }
-           else
+           parse_head (domain, node, out name, out min_arg, out max_arg,
+                       out args);
+         }
+
+       public void SetBody (Domain domain, XmlNode node)
+       {
+         parse_body (domain, node, out body);
+       }
+
+       public override Term Call (Domain domain, Variable vari, Term[] args)
+       {
+         Bindings current = domain.bindings;
+         Term result = Zero;
+
+         try {
+           int i;
+           Term[] newargs = new Term[args.Length];
+           for (i = 0; i < min_arg; i++)
+             newargs[i] = args[i].Eval (domain);
+           args = newargs;
+           for (i = 0; i < min_arg; i++)
+             domain.Bind (this.args[i], args[i]);
+           if (body != null)
              {
-               min_arg = max_arg = 0;
+               try {
+                 domain.Catch (CatchTag.Return);
+                 foreach (Term term in body)
+                   {
+                     result = term.Eval (domain);
+                     if (domain.Thrown)
+                       return result;
+                   }
+               } finally {
+                 domain.Uncatch ();
+               }
              }
+         } finally {
+           domain.UnboundTo (current);
+         }
+         return result;
+       }
+      }
+
+      internal class Lambda : Function
+      {
+       internal Variable[] args;
+       internal Term[] body;
+
+       public Lambda (Domain domain, XmlNode node)
+         {
+           parse_head (domain, node, out name, out min_arg, out max_arg,
+                       out args);
          }
 
-       public Lambda (Domain domain, Symbol name,
-                      bool args_evalled, Symbol[] args)
+       public Lambda (Domain domain, Symbol name, Symbol[] args)
          {
            int nfixed = 0;
            int noptional = 0;
            int nrest = 0;
 
            this.name = name;
-           this.args_evalled = args_evalled;
            if (args != null)
              {
                int i = 0;
@@ -257,20 +331,7 @@ namespace System.Xml.Expression
 
        public void SetBody (Domain domain, XmlNode node)
        {
-         for (node = node.FirstChild; node != null; node = node.NextSibling)
-           if (node.Name != Qdescription
-               && node.Name != Qargs
-               && node.Name != Qargs_unevalled)
-             break;
-         int nterms = 0;
-         for (XmlNode n = node; n != null; n = n.NextSibling)
-           nterms++;
-         if (nterms > 0)
-           {
-             body = new Term[nterms];
-             for (nterms = 0; node != null; node = node.NextSibling, nterms++)
-               body[nterms] = new Term (domain, node);
-           }
+         parse_body (domain, node, out body);
        }
 
        public void SetBody (Term[] body)
@@ -285,7 +346,7 @@ namespace System.Xml.Expression
 
          try {
            int i;
-           if (args_evalled)
+           if (args != null)
              {
                Term[] newargs = new Term[args.Length];
                for (i = 0; i < min_arg; i++)
@@ -297,8 +358,7 @@ namespace System.Xml.Expression
            if (body != null)
              {
                try {
-                 if (args_evalled)
-                   domain.Catch (CatchTag.Return);
+                 domain.Catch (CatchTag.Return);
                  foreach (Term term in body)
                    {
                      result = term.Eval (domain);
@@ -306,8 +366,7 @@ namespace System.Xml.Expression
                        return result;
                    }
                } finally {
-                 if (args_evalled)
-                   domain.Uncatch ();
+                 domain.Uncatch ();
                }
              }
          } finally {
@@ -718,6 +777,9 @@ namespace System.Xml.Expression
 
       public void DefTerm (Symbol name, TermParser parser)
       {
+       if (termtypes.ContainsKey (name)
+           || functions.ContainsKey (name))
+         throw new Exception ("already defined: " + name);
        termtypes[name] = new TermType (name, parser);
       }
 
@@ -725,6 +787,8 @@ namespace System.Xml.Expression
                           int min_arg, int max_arg, params string[] aliases)
       {
        Symbol name = str;
+       if (termtypes.ContainsKey (name))
+         throw new Exception ("already defined as termtype: " + name);
        Function func = new Function.Subroutine (builtin, name, setvar,
                                                 min_arg, max_arg);
        functions[name] = func;
@@ -737,6 +801,8 @@ namespace System.Xml.Expression
                              params string[] aliases)
       {
        Symbol name = str;
+       if (termtypes.ContainsKey (name))
+         throw new Exception ("already defined as termtype: " + name);
        Function func = new Function.SpecialForm (builtin, name,
                                                  min_arg, max_arg);
        functions[name] = func;
@@ -749,14 +815,16 @@ namespace System.Xml.Expression
        functions[(Symbol) alias] = functions[(Symbol) str];
       }
 
-      public void Defun (Symbol name, bool args_evalled,
-                        Symbol[] args, Term[] body, bool prototype)
+      public void Defun (Symbol name, Symbol[] args, Term[] body,
+                        bool prototype)
       {
        Function func;
 
+       if (termtypes.ContainsKey (name))
+         throw new Exception ("already defined as termtype: " + name);
        if (prototype || ! functions.TryGetValue (name, out func))
          {
-           func = new Function.Lambda (this, name, args_evalled, args);
+           func = new Function.Lambda (this, name, args);
            functions[name] = func;
          }
        if (! prototype)
@@ -766,6 +834,8 @@ namespace System.Xml.Expression
       public void Defun (XmlNode node, bool prototype)
       {
        Symbol name = node.Attributes[Qfname].Value;
+       if (termtypes.ContainsKey (name))
+         throw new Exception ("already defined as termtype: " + name);
        Function func;
 
        if (prototype || ! functions.TryGetValue (name, out func))
@@ -782,6 +852,22 @@ namespace System.Xml.Expression
        functions[func.name] = func;
       }
 
+      public void Defmacro (XmlNode node, bool prototype)
+      {
+       Symbol name = node.Attributes[Qfname].Value;
+       if (termtypes.ContainsKey (name))
+         throw new Exception ("already defined as termtype: " + name);
+       Function func;
+
+       if (prototype || ! functions.TryGetValue (name, out func))
+         {
+           func = new Function.Macro (this, node);
+           functions[name] = func;
+         }
+       if (! prototype)
+         ((Function.Macro) func).SetBody (this, node);
+      }
+
       public Variable Defvar (XmlNode node)
       {
        Symbol name = node.Attributes[0].Value;
@@ -1598,61 +1684,38 @@ namespace System.Xml.Expression
       internal Variable vari;
       internal Term[] args;
 
-      private Funcall (Function func, Variable vari, Term[] args)
-       {
-         this.func = func;
-         this.vari = vari;
-         this.args = args;
-       }
-
-      public Funcall (Domain domain, Symbol fname, Term[] args)
-       {
-         func = domain.GetFunc (fname);
-         if (args != null)
-           {
-             int nargs = args.Length;
-             if (nargs < func.min_arg
-                 || (func.max_arg >= 0 && nargs > func.max_arg))
-               throw new Exception ("Invalid number of arguments to: "
-                                    + fname + " " + nargs);
-           }
-         this.args = args;
-       }
-
-      public Funcall (Domain domain, Symbol fname, Symbol vname, Term[] args)
+      public Funcall (Function func, Variable vari, Term[] args)
        {
-         func = domain.GetFunc (fname);
          if (args != null)
            {
              int nargs = args.Length;
              if (nargs < func.min_arg
                  || (func.max_arg >= 0 && nargs > func.max_arg))
                throw new Exception ("Invalid number of arguments to: "
-                                    + fname + " " + nargs);
+                                    + func.name + " " + nargs);
            }
+         this.func = func;
+         this.vari = vari;
          this.args = args;
-         if (vname != Qnull)
-           vari = domain.GetVar (vname, true);
        }
 
       internal static TermValue parser (Domain domain, XmlNode node)
        {
          Symbol fname = node.Name;
-         Symbol vname = Qnull;
          XmlAttribute attr;
 
          if (fname == Qfuncall)
            fname = node.Attributes[Qfname].Value;
+         Function func = domain.GetFunc (fname);
+         Variable vari;
          attr = node.Attributes[Qvname];
-         if (attr != null)
-           vname = attr.Value;
-
+         vari = attr == null ? null : domain.GetVar (attr.Value, true);
          XmlNodeList nlist = node.ChildNodes;
          int nargs = nlist.Count;
          Term[] args = new Term[nargs];
          for (int i = 0; i < nargs; i++)
            args[i] = new Term (domain, nlist[i]);
-         return new Funcall (domain, fname, vname, args);
+         return new Funcall (func, vari, args);
        }
 
       public override Term Eval (Domain domain)
@@ -1749,16 +1812,16 @@ namespace System.Xml.Expression
 
       // <funcall fname="FNAME">...</funcall>
       public Term (Domain domain, Symbol fname, Term[] args)
-       {
-         intval = 0;
-         objval = new Funcall (domain, fname, args);
-       }
+       : this (domain, fname, Qnull, args) { }
 
       // <funcall fname="FNAME" vname="VNAME">...</funcall>
       public Term (Domain domain, Symbol fname, Symbol vname, Term[] args)
        {
          intval = 0;
-         objval = new Funcall (domain, fname, vname, args);
+
+         Function func = domain.GetFunc (fname);
+         Variable vari = vname == Qnull ? null : domain.GetVar (vname, true);
+         objval = new Funcall (func, vari, args);
        }
 
       public object Objval {
diff --git a/xex.xml b/xex.xml
index ef86e97..4db06fb 100644 (file)
--- a/xex.xml
+++ b/xex.xml
     </if>
   </defun>
 
-  <defun fname="temp">
-    <set vname="y"><varref vname="SELECT"/></set>
-    <varref vname="y"/>
-  </defun>
-
   <defun fname="looptest">
-    <args-unevalled><fixed vname="l"/></args-unevalled>
+    <args><fixed vname="l"/></args>
     <loop><loop>
       <foreach vname="term"><varref vname="l"/>
        <eval><varref vname="term"/></eval>
@@ -63,7 +58,5 @@
     </eval>
     <concat><integer>?a</integer><integer>?b</integer></concat>
     <quote><add><varref vname="x"/><integer>1</integer></add></quote>
-    <set vname="SELECT"><integer>11</integer></set>
-    <temp/>
   </append>
 </expr>
diff --git a/xml.cs b/xml.cs
new file mode 100644 (file)
index 0000000..deba9b7
--- /dev/null
+++ b/xml.cs
@@ -0,0 +1,106 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Xml;
+using Mvp.Xml.XInclude;
+
+public class Test
+{
+  static void read_element (XmlTextReader reader)
+  {
+    bool cont = true;
+
+    Console.Write ("\n(" + reader.Name);
+    if (reader.MoveToFirstAttribute ())
+      {
+       do {
+         Console.Write (" (" + reader.Name + " " + reader.Value + ")");
+       } while (reader.MoveToNextAttribute ());
+       reader.MoveToElement ();
+      }
+    while (cont && reader.Read ())
+      switch (reader.NodeType)
+       {
+       case XmlNodeType.Element:
+         if (reader.Name == "doxygen")
+           reader.Skip ();
+         else
+           read_element (reader);
+         break;
+       case XmlNodeType.Text:
+         Console.Write ("\n\"" + reader.Value + "\"");
+         break;
+       case XmlNodeType.EndElement:
+         cont = false;
+         break;
+       }
+    Console.Write (")");
+  }
+
+  static void print_node (XmlNode node)
+  {
+    XmlAttributeCollection acol = node.Attributes;
+    if (acol != null)
+      {
+       XmlAttribute a = node.Attributes["key"];
+       if (a != null)
+         Console.Write (a.Value);
+      }
+    Console.Write ("\n(");
+    switch (node.NodeType)
+      {
+      case XmlNodeType.Element:
+       Console.Write (node.Name);
+       XmlAttributeCollection attrs = node.Attributes;
+       foreach (XmlAttribute attr in attrs)
+         Console.Write (" ({0} {1})", attr.Name, attr.Value);
+       break;
+      case XmlNodeType.Text:
+       Console.WriteLine ("\n\"{0}\"", node.Value);
+       break;
+      default:
+       Console.WriteLine ("\n{0}", node.NodeType);
+       break;
+      }
+    node = node.FirstChild;
+    while (node != null)
+      {
+       print_node (node);
+       node = node.NextSibling;
+      }
+    Console.Write (")");
+  }
+
+
+  public static void Main (string[] args)
+  {
+    FileStream stream;
+    XmlTextReader reader;
+    XmlDocument doc;
+
+#if false
+    stream = File.OpenRead ("/usr/local/work/m17n-db-xml/MIM/ispell.mimx");
+    reader = new XmlTextReader (stream);
+    doc = new XmlDocument ();
+    reader.WhitespaceHandling = WhitespaceHandling.None;
+    reader.Read ();
+    Console.WriteLine (reader.Name + ":" + reader.NodeType);
+    while (reader.NodeType != XmlNodeType.Element)
+      reader.Read ();
+    doc.LoadXml ("<" + reader.Name + "/>");
+    reader.Read ();
+    while (reader.NodeType != XmlNodeType.Element
+          || reader.Name != args[0])
+      reader.Skip ();
+    doc.DocumentElement.InsertAfter (doc.ReadNode (reader), null);
+    print_node (doc.DocumentElement);
+    reader.Close ();
+    stream.Dispose ();
+#else
+    doc = new XmlDocument (xex);
+    XmlReader read = new XIncludingReader (XmlReader.Create (args[0]));
+    doc.Load (read);
+    print_node (doc.DocumentElement);
+#endif
+  }
+}
\ No newline at end of file