*** empty log message ***
[m17n/m17n-lib-cs.git] / XmlExpr.cs
index c10a312..08954e8 100644 (file)
@@ -61,7 +61,7 @@ namespace System.Xml
        string str = (InnerException != null ? InnerException.ToString ()
                      : base.ToString ()) + "\n" + "Xexpression:" + name + "\n";
        if (node != null)
-         str += "  at " + node.Parent.OuterXml + "\n";
+         str += "  at " + node.OuterXml + "\n";
        if (stack != null)
          {
            str += "Call stack: ";
@@ -86,6 +86,7 @@ namespace System.Xml
       public static Symbol VariableRangeConflict = "variable-range-conflict";
       public static Symbol VariableWrongRange = "variable-wrong-range";
       public static Symbol VariableWrongValue = "variable-wrong-value";
+
       public static Symbol UnknownFunction = "unknown-function";
       public static Symbol MacroExpansionError = "macro-expansion-error";
       public static Symbol NoVariableName = "no-variable-anme";
@@ -739,11 +740,15 @@ namespace System.Xml
 
       internal void ThrowSymbol (Term tag)
       {
+       int i = catch_count;
        foreach (CatchTag elt in catch_stack)
          {
-           catch_count--;
+           i--;
            if (elt.Tag.Matches (tag))
-             return;
+             {
+               catch_count = i;
+               return;
+             }
          }
        throw new Error (Error.UncaughtThrow,
                         "No corresponding catch: {0}", tag);
@@ -856,8 +861,20 @@ namespace System.Xml
 
       internal Variable Defvar (Symbol name)
       {
-       Variable vari = new Variable (this, name, Zero);
-       variables[name] = vari;
+       Variable vari;
+
+       if (variables.TryGetValue (name, out vari))
+         {
+           Variable.Typed typed = vari as Variable.Typed;
+           if (typed != null)
+             throw new Error (Error.VariableTypeConflict,
+                              "Not a non-typed variable: {0}", name);
+         }
+       else
+         {
+           vari = new Variable (this, name, Zero);
+           variables[name] = vari;
+         }
        return vari;
       }
 
@@ -971,7 +988,7 @@ namespace System.Xml
          domain.functions[kv.Key] = kv.Value;
       }
 
-      public Variable GetVar (Symbol name)
+      public Variable GetVarCreate (Symbol name)
       {
        Variable vari;
 
@@ -980,6 +997,15 @@ namespace System.Xml
        return vari;
       }
 
+      public Variable GetVar (Symbol name)
+      {
+       Variable vari;
+
+       if (! variables.TryGetValue (name, out vari))
+         return null;
+       return vari;
+      }
+
       public override string ToString ()
       {
        string str = "<(functions";
@@ -1381,16 +1407,26 @@ namespace System.Xml
     private static Term Fand (Domain domain, Variable vari, Term[] args)
     {
       foreach (Term arg in args)
-       if (! arg.Eval (domain).IsTrue)
-         return Zero;
+       {
+         Term result = arg.Eval (domain);
+         if (domain.Thrown ())
+           result;
+         if (! result.IsTrue)
+           return Zero;
+       }
       return One;
     }
 
     private static Term For (Domain domain, Variable vari, Term[] args)
     {
       foreach (Term arg in args)
-       if (arg.Eval (domain).IsTrue)
-         return One;
+       {
+         Term result = arg.Eval (domain);
+         if (domain.Thrown ())
+           return result;
+         if (result.IsTrue)
+           return One;
+       }
       return Zero;
     }
 
@@ -1404,13 +1440,21 @@ namespace System.Xml
       Term result = One;
 
       foreach (Term arg in args)
-       result = arg.Eval (domain);
+       {
+         result = arg.Eval (domain);
+         if (domain.Thrown ())
+           return result;
+       }
       return result;
     }
 
     private static Term Fif (Domain domain, Variable vari, Term[] args)
     {
-      if (args[0].Eval (domain).IsTrue)
+      Term result = args[0].Eval (domain);
+
+      if (domain.Thrown)
+       return result;
+      if (result.IsTrue)
        return args[1].Eval (domain);
       if (args.Length == 2)
        return Zero;
@@ -1419,11 +1463,19 @@ namespace System.Xml
 
     private static Term Fwhen (Domain domain, Variable vari, Term[] args)
     {
-      if (! args[0].Eval (domain).IsTrue)
+      Term result = args[0].Eval (domain);
+
+      if (domain.Thrown)
+       return result;
+      if (! result.IsTrue)
        return Zero;
-      Term result = One;
+      result = One;
       for (int i = 1; i < args.Length; i++)
-       result = args[i].Eval (domain);
+       {
+         result = args[i].Eval (domain);
+         if (domain.Thrown)
+           return result;
+       }
       return result;
     }
 
@@ -1556,7 +1608,7 @@ namespace System.Xml
        {
          result = terms[i].Eval (domain);
          if (domain.Thrown (out caught))
-           break;
+           return result;
        }
       return result;
     }
@@ -1633,7 +1685,7 @@ namespace System.Xml
       public virtual bool Matches (TermValue other) { return Equals (other); }
       public override abstract bool Equals (object obj);
       public override abstract int GetHashCode ();
-      public abstract string ToString (bool detail);
+      public virtual string ToString (bool detail) { return ToString (); }
     }
 
     private class Varref : TermValue
@@ -1649,7 +1701,7 @@ namespace System.Xml
       public override Term Eval (Domain domain)
       {
        if (vari == null || vari.domain != domain)
-         vari = domain.GetVar (vname);
+         vari = domain.GetVarCreate (vname);
        return vari.Value;
       }
 
@@ -1681,6 +1733,7 @@ namespace System.Xml
     {
       private static Symbol name = "funcall";
       public static Symbol Name { get { return name; } }
+      private static Term[] null_args = new Term[0];
 
       internal Function func;
       internal Variable vari;
@@ -1688,8 +1741,9 @@ namespace System.Xml
 
       public Funcall (Function func, Variable vari, Term[] args)
        {
+         if (args == null)
+           args = null_args;
          int nargs = args.Length;
-
          if (nargs < func.min_args
              || (func.max_args >= 0 && nargs > func.max_args))
            throw new Error (Error.WrongArgument,
@@ -1714,7 +1768,7 @@ namespace System.Xml
        Function func = domain.GetFunc (fname);
        Variable vari;
        attr = node.Attributes[Qvname];
-       vari = attr == null ? null : domain.GetVar (attr.Value);
+       vari = attr == null ? null : domain.GetVarCreate (attr.Value);
        XmlNodeList nlist = node.ChildNodes;
        int nargs = nlist.Count;
        Term[] args = new Term[nargs];
@@ -1957,7 +2011,7 @@ namespace System.Xml
          intval = 0;
 
          Function func = domain.GetFunc (fname);
-         Variable vari = vname == Qnull ? null : domain.GetVar (vname);
+         Variable vari = vname == Qnull ? null : domain.GetVarCreate(vname);
          Funcall funcall = new Funcall (func, vari, args);
          if (func is Function.Macro)
            {
@@ -2344,9 +2398,10 @@ namespace System.Xml
       Function func = domain.GetFunc (name);
 
       for (node = node.FirstChild; node != null; node = node.NextSibling)
-       if (node.Name != Qdescription
-           && node.Name != Qargs)
+       if (node.Name != Qdescription && node.Name != Qargs)
          break;
+      Console.WriteLine ("found body " + node.Name);
+      
       Term[] body = Parse (domain, node, null);
       if (is_defun)
        ((Function.Lambda) func).SetBody (body);
@@ -2456,8 +2511,9 @@ namespace System.Xml
       XmlDocument doc = new XmlDocument (Symbol.NameTable);
       XmlNode node;
 
-      using (XmlTextReader reader = new XmlTextReader (url, doc.NameTable))
+      using (XmlTextReader reader = new XmlTextReader (url, Symbol.NameTable))
        {
+         reader.WhitespaceHandling = WhitespaceHandling.None;
          do {
            reader.Read ();
          } while (reader.NodeType != XmlNodeType.None
@@ -2470,6 +2526,11 @@ namespace System.Xml
       return Parse (domain, node.FirstChild, null);
     }
 
+    public static Term Eval (Domain domain, Term term)
+    {
+      return Eval (domain, new Term[] { term });
+    }
+
     public static Term Eval (Domain domain, Term[] terms)
     {
       Term result = Zero;