*** empty log message ***
authorhanda <handa>
Fri, 25 Sep 2009 13:11:40 +0000 (13:11 +0000)
committerhanda <handa>
Fri, 25 Sep 2009 13:11:40 +0000 (13:11 +0000)
MInputMethod.cs
XmlExpr.cs

index fcc0973..87777f6 100644 (file)
@@ -63,6 +63,8 @@ namespace M17N.Input
     private static Dictionary<MDatabase.Tag, MInputMethod> im_table
       = new Dictionary<MDatabase.Tag, MInputMethod> ();
 
     private static Dictionary<MDatabase.Tag, MInputMethod> im_table
       = new Dictionary<MDatabase.Tag, MInputMethod> ();
 
+    internal static MInputMethod im_global;
+
     // Sub classes
     private class Exception : System.Exception
     {
     // Sub classes
     private class Exception : System.Exception
     {
@@ -306,7 +308,7 @@ namespace M17N.Input
       }
     }
 
       }
     }
 
-    public class KeySeq : Xex.Object
+    public class KeySeq : Xex.TermValue
     {
       List<Key> keyseq = new List<Key> ();
 
     {
       List<Key> keyseq = new List<Key> ();
 
@@ -584,7 +586,7 @@ namespace M17N.Input
       }
     }
 
       }
     }
 
-    internal class PluginMethod : Function
+    internal class PluginMethod : Xex.Function
     {
       public Plugin plugin;
       public MSymbol method;
     {
       public Plugin plugin;
       public MSymbol method;
@@ -596,10 +598,10 @@ namespace M17N.Input
          method = name.name.Substring (plugin.name.Length + 1);
        }
 
          method = name.name.Substring (plugin.name.Length + 1);
        }
 
-      public override Term Call (Xex.Domain domain, Xex.Variable vari,
-                                Xex.Term[] args)
+      public override Xex.Term Call (Xex.Domain domain, Xex.Variable vari,
+                                    Xex.Term[] args)
       {
       {
-       Xex.Term[] args = (Xex.Term[]) args.Clone ();
+       args = (Xex.Term[]) args.Clone ();
        for (int i = 0; i < args.Length; i++)
          {
            args[i] = args[i].Eval (domain);
        for (int i = 0; i < args.Length; i++)
          {
            args[i] = args[i].Eval (domain);
@@ -634,74 +636,96 @@ namespace M17N.Input
     internal abstract class Marker : Xex.TermValue
     {
       MSymbol name;
     internal abstract class Marker : Xex.TermValue
     {
       MSymbol name;
-      MInputContext ic;
 
 
-      public Marker (MSymbol name, MInputContext ic)
+      public Marker (MSymbol name)
        {
          this.name = name;
        {
          this.name = name;
-         this.ic = ic;
        }
 
        }
 
-      public abstract int Position { get; set; }
-    }
+      public abstract int Position (MInputContext ic);
+      public abstract void Mark (MInputContext ic);
 
 
-    internal class NamedMarker : Marker
-    {
-      int position;
+      public class Named : Marker
+      {
+       int pos;
 
 
-      public NamedMaker (MSymbol name, MInputContext ic) : base (name, ic)
-       {
-         ic.markers.Put (name, this);
-       }
+       public Named (MSymbol name) : base (name) { }
 
 
-      public override int Position {
-       get { return position; }
-       set { position = value; }
+       public override int Position (MInputContext ic) { return pos; }
+
+       public override void Mark (MInputContext ic) { pos = ic.cursor_pos; } 
       }
       }
-    }
      
      
-    internal class SystemMarker : Marker
-    {
-      public SystemMarker (MSymbol name, MInputContext ic) : base (name, ic)
-       {
-       }
+      public class Predefined : Marker
+      {
+       public Predefined (MSymbol name) : base (name) { }
        
        
-      public override int Position {
-       get {
-         switch (name.Name[1])
-           {
-           case '<': return 0;
-           case '>': return ic.preedit.Length;
-           case '-': return ic.cursor_pos - 1;
-           case '+': return ic.cursor_pos + 1;
-           case '[':
-             if (ic.cursor_pos > 0)
-               {
-                 int pos = ic.cursor_os;
-                 int to;
-                 ic.preedit.FindProp (MInputMethod.Mcandidates, pos - 1,
-                                      out pos, out to);
-                 return pos;
-               }
-             return 0;
-           case ']':
-             if (ic.cursor_pos < ic.preedit.Length - 1)
-               {
-                 int pos = ic.cursor_pos;
-                 int from;
-                 ic.preedit.FindProp (MInputMethod.Mcandidates, pos,
-                                      out from, out pos);
-                 return pos;
-               }
-             return ic.preedit.Length;
-           default:
-             return name.Name[1] - '0';
-           }
+       public override int Position (MInputContext ic)
+       {
+         switch (name.Name[1]) {
+         case '<': return 0;
+         case '>': return ic.preedit.Length;
+         case '-': return ic.cursor_pos - 1;
+         case '+': return ic.cursor_pos + 1;
+         case '[':
+           if (ic.cursor_pos > 0)
+             {
+               int pos = ic.cursor_os;
+               int to;
+               ic.preedit.FindProp (MInputMethod.Mcandidates, pos - 1,
+                                    out pos, out to);
+               return pos;
+             }
+           return 0;
+         case ']':
+           if (ic.cursor_pos < ic.preedit.Length - 1)
+             {
+               int pos = ic.cursor_pos;
+               int from;
+               ic.preedit.FindProp (MInputMethod.Mcandidates, pos,
+                                    out from, out pos);
+               return pos;
+             }
+           return ic.preedit.Length;
+         default:
+           return name.Name[1] - '0';
+         }
        }
        }
-       set {
+      
+       public override void Mark (MInputContext ic)
+       {
          throw new Exception ("Can't set predefined marker: " + name);
        }
       }
          throw new Exception ("Can't set predefined marker: " + name);
        }
       }
+
+      static internal Dictionary<MSymbol,Predefined> predefined_markers;
+
+      static Marker ()
+      {
+       predefined_markers = new Dictionary<MSymbol,Predefined> ();
+       MSymbol[] symlist = new MSYmbol[] {"@<", "@>", "@-", "@+", "@[", "@]",
+                                          "@0", "@1", "@2", "@3", "@4",
+                                          "@5", "@6", "@7", "@8", "@9" };
+       foreach (MSymbol s in strline)
+         predefined_markers[s] = new Predefined (s);
+      }
+
+      public static Marker Get (MInputContext ic, MSymbol name)
+      {
+       Marker m;
+
+       if (predefined_markers.TryGetValue (name, out m))
+         return m;
+       if (name.Name[0] == '@')
+         throw new Exception ("Invalid marker name: " + name);
+       m = (Marker) ic->markers.Get (name);
+       if (m == null)
+         {
+           m = new Named (name);
+           ic->markers.Put (name, m);
+         }
+       return m;
+      }
     }
       
     internal class Map
     }
       
     internal class Map
@@ -832,6 +856,8 @@ namespace M17N.Input
       M17n.DebugPrint ("Found {0} input methods\n", list.Count);
       foreach (MDatabase mdb in list)
        im_table[mdb.tag] = new MInputMethod (mdb.tag);
       M17n.DebugPrint ("Found {0} input methods\n", list.Count);
       foreach (MDatabase mdb in list)
        im_table[mdb.tag] = new MInputMethod (mdb.tag);
+      tag = new MDatabase.Tag (Minput_method, MSymbol.t, MSymbol.nil, "global");
+      im_global = im_table[tag];
     }
 
     // Constructor
     }
 
     // Constructor
@@ -864,7 +890,7 @@ namespace M17N.Input
       variables = new Xex.Variable[var_names.Length];
       int i = 0;
       foreach (Xex.Name name in var_names)
       variables = new Xex.Variable[var_names.Length];
       int i = 0;
       foreach (Xex.Name name in var_names)
-       variables[i++] = domain.GetVar (name);
+       variables[i++] = domain.GetVar (name, false);
       commands = this.commands;
       return true;
     }
       commands = this.commands;
       return true;
     }
@@ -992,8 +1018,6 @@ namespace M17N.Input
        description = (MText) "No description";
       if (title == null)
        title = new MText (tag[2].Name);
        description = (MText) "No description";
       if (title == null)
        title = new MText (tag[2].Name);
-      if (variables == null)
-       variables = new Variable[0];
       if (commands == null)
        commands = new Command[0];
       if (! full)
       if (commands == null)
        commands = new Command[0];
       if (! full)
@@ -1003,7 +1027,7 @@ namespace M17N.Input
          State state = new State ((MSymbol) "init");
          plist = new MPlist ();
          foreach (KeyValuePair<MSymbol, Map>kv in maps)
          State state = new State ((MSymbol) "init");
          plist = new MPlist ();
          foreach (KeyValuePair<MSymbol, Map>kv in maps)
-           state.branches.Add (kv.Key, new Xex (plist, domain));
+           state.branches.Add (kv.Key, null);
          states.Add (state.name, state);
        }
     }
          states.Add (state.name, state);
        }
     }
@@ -1050,8 +1074,6 @@ namespace M17N.Input
        description = (MText) "No description";
       if (title == null)
        title = new MText (tag[2].Name);
        description = (MText) "No description";
       if (title == null)
        title = new MText (tag[2].Name);
-      if (variables == null)
-       variables = new Variable[0];
       if (commands == null)
        commands = new Command[0];
       if (! full)
       if (commands == null)
        commands = new Command[0];
       if (! full)
@@ -1059,9 +1081,8 @@ namespace M17N.Input
       if (states.IsEmpty)
        {
          State state = new State ((MSymbol) "init");
       if (states.IsEmpty)
        {
          State state = new State ((MSymbol) "init");
-         MPlist plist = new MPlist ();
          foreach (KeyValuePair<MSymbol, Map>kv in maps)
          foreach (KeyValuePair<MSymbol, Map>kv in maps)
-           state.branches.Add (kv.Key, new Xex (plist, domain));
+           state.branches.Add (kv.Key, null);
          states.Add (state.name, state);
        }
     }
          states.Add (state.name, state);
        }
     }
@@ -1215,7 +1236,6 @@ namespace M17N.Input
     private void new_variable (Xex.Name name, string desc, int val,
                               MPlist pl, Xex.Variable vari)
     {
     private void new_variable (Xex.Name name, string desc, int val,
                               MPlist pl, Xex.Variable vari)
     {
-      Xex.Term term = new Xex.Term (val);
       int[] range;
 
       if (pl.IsEmpty)
       int[] range;
 
       if (pl.IsEmpty)
@@ -1237,13 +1257,14 @@ namespace M17N.Input
              else if (pl.IsInteger)
                range[i * 2] = range[i * 2 + 1] = pl.Integer;
              else
              else if (pl.IsInteger)
                range[i * 2] = range[i * 2 + 1] = pl.Integer;
              else
-               throw new Exception ("Invalid range: " + p);
+               throw new Exception ("Invalid range: " + pl);
            }
        }
       if (vari == null)
            }
        }
       if (vari == null)
-       domain.Defvar (new Xex.Variable.Int (name, desc, term, range));
+       domain.Defvar (new Xex.Variable.Int (name, desc, val, range));
       else
        {
       else
        {
+         Xex.Term term = new Xex.Term (val);
          vari.Value = term;
          vari.DefaultValue = term;
          vari.Range = range;
          vari.Value = term;
          vari.DefaultValue = term;
          vari.Range = range;
@@ -1253,7 +1274,6 @@ namespace M17N.Input
     private void new_variable (Xex.Name name, string desc, MText val,
                               MPlist pl, Xex.Variable vari)
     {
     private void new_variable (Xex.Name name, string desc, MText val,
                               MPlist pl, Xex.Variable vari)
     {
-      Xex.Term term = new Xex.Term ((string) val);
       string[] range;
 
       if (pl.IsEmpty)
       string[] range;
 
       if (pl.IsEmpty)
@@ -1264,15 +1284,16 @@ namespace M17N.Input
          for (int i = 0; i < range.Length; i++)
            {
              if (pl.IsMText)
          for (int i = 0; i < range.Length; i++)
            {
              if (pl.IsMText)
-               range[i] = pl.Text;
+               range[i] = (string) pl.Text;
              else
              else
-               throw new Exception ("Invalid range: " + p);
+               throw new Exception ("Invalid range: " + pl);
            }
        }
       if (vari == null)
            }
        }
       if (vari == null)
-       domain.Defvar (new Xex.Variable.Str (name, desc, term, range));
+       domain.Defvar (new Xex.Variable.Str (name, desc, (string) val, range));
       else
        {
       else
        {
+         Xex.Term term = new Xex.Term ((string) val);
          vari.Value = term;
          vari.DefaultValue = term;
          vari.Range = range;
          vari.Value = term;
          vari.DefaultValue = term;
          vari.Range = range;
@@ -1282,8 +1303,8 @@ namespace M17N.Input
     private void new_variable (Xex.Name name, string desc, MSymbol val,
                               MPlist pl, Xex.Variable vari)
     {
     private void new_variable (Xex.Name name, string desc, MSymbol val,
                               MPlist pl, Xex.Variable vari)
     {
-      Xex.Term term = new Xex.Term ((Xex.Name) val.name);
       Xex.Name[] range;
       Xex.Name[] range;
+      Xex.Name sym = val.Name;
 
       if (pl.IsEmpty)
        range = null;
 
       if (pl.IsEmpty)
        range = null;
@@ -1293,15 +1314,16 @@ namespace M17N.Input
          for (int i = 0; i < range.Length; i++)
            {
              if (pl.IsSymbol)
          for (int i = 0; i < range.Length; i++)
            {
              if (pl.IsSymbol)
-               range[i] = pl.Symbol.name;
+               range[i] = pl.Symbol.Name;
              else
              else
-               throw new Exception ("Invalid range: " + p);
+               throw new Exception ("Invalid range: " + pl);
            }
        }
       if (vari == null)
            }
        }
       if (vari == null)
-       domain.Defvar (new Xex.Variable.Sym (name, desc, term, range));
+       domain.Defvar (new Xex.Variable.Sym (name, desc, sym, range));
       else
        {
       else
        {
+         Xex.Term term = new Xex.Term (sym);
          vari.Value = term;
          vari.DefaultValue = term;
          vari.Range = range;
          vari.Value = term;
          vari.DefaultValue = term;
          vari.Range = range;
@@ -1310,44 +1332,55 @@ namespace M17N.Input
 
     private void parse_variables (MPlist plist)
     {
 
     private void parse_variables (MPlist plist)
     {
-      variables = new Variable[plist.Count];
+      var_names = new Xex.Name[plist.Count];
 
 
-      for (int i = 0; ! plist.IsEmpty; plist = plist.next)
-       if (plist.IsPlist && plist.Plist.IsSymbol)
-         {
-           MPlist p = plist.Plist;
-           Xex.Name name = (Name) p.Symbol.name;
+      for (int i = 0; ! plist.IsEmpty; i++, plist = plist.next)
+       {
+         if (! plist.IsPlist || ! plist.Plist.IsSymbol)
+           throw new Exception ("Invalid variable: " + plist);
+
+         MPlist p = plist.Plist;
+         Xex.Name name = (Xex.Name) p.Symbol.Name;
+         var_names[i] = name;
+         p = p.next;
+         string desc = (string) parse_description (p);
+         Xex.Variable vari = im_global.domain.GetVar (name, false);
+
+         if (vari != null)
+           domain.Defvar (vari);
+         if (desc != null)
            p = p.next;
            p = p.next;
-           string desc = parse_description (p);
-           Xex.Variable vari = null;
-           Xex.Term val;
-
-           if (im_global.domain.GetVar (name, out vari))
-             domain.Defvar (vari);
-           if (desc != null)
-             p = p.next;
-           if (! p.IsEmpty)
-             {
-               if (p.IsInteger)
-                 new_variable (name, desc, p.Integer, p.next, vari);
-               else if (p.IsMText)
-                 new_variable (name, desc, p.Text, p.next, vari);
-               else if (p.IsSymbol)
-                 new_variable (name, desc, p.Symbol, p.next, vari);
-               else
-                 throw new Exception ("Unknown type: " + p.val);
-             }
-         }
+         if (! p.IsEmpty)
+           {
+             if (p.IsInteger)
+               new_variable (name, desc, p.Integer, p.next, vari);
+             else if (p.IsMText)
+               new_variable (name, desc, p.Text, p.next, vari);
+             else if (p.IsSymbol)
+               new_variable (name, desc, p.Symbol, p.next, vari);
+             else
+               throw new Exception ("Invalid variable type: " + p.val);
+           }
+       }
     }
 
     private void parse_variables (XmlNode node)
     {
       XmlNodeList node_list = node.ChildNodes;
 
     }
 
     private void parse_variables (XmlNode node)
     {
       XmlNodeList node_list = node.ChildNodes;
 
-      variables = new Variable[node_list.Count];
+      var_names = new Xex.Name[node_list.Count];
       for (int i = 0; i < node_list.Count; i++)
       for (int i = 0; i < node_list.Count; i++)
-       if (node_list[i].NodeType == XmlNodeType.Element)
-         variables[i] = new Variable (node_list[i]);
+       {
+         Xex.Name name = node_list[i].Attributes[0].Value;
+         Xex.Variable vari = im_global.domain.GetVar (name, false);
+
+         if (vari != null)
+           domain.Defvar (vari);
+         else
+           domain.Defvar (node_list[i]);
+
+         var_names[i] = name;
+       }
     }
 
     private void parse_commands (MPlist plist)
     }
 
     private void parse_commands (MPlist plist)
@@ -1408,37 +1441,12 @@ namespace M17N.Input
     private void parse_macros (XmlNode node)
     {
       for (XmlNode nn = node.FirstChild; nn != null; nn = nn.NextSibling)
     private void parse_macros (XmlNode node)
     {
       for (XmlNode nn = node.FirstChild; nn != null; nn = nn.NextSibling)
-       if (nn.NodeType == XmlNodeType.Element
-           && nn.Name == "xi:include")
-         {
-           XmlNode n = nn.FirstChild.FirstChild;
-           MSymbol language = n.InnerText;
-           n = n.NextSibling;
-           MSymbol name = n.InnerText;
-           n = n.NextSibling;
-           MSymbol subname = (n != null ? n.InnerText : MSymbol.nil);
-           n = n.ParentNode.NextSibling;
-           MSymbol section = n.InnerText;
-           n = n.NextSibling;
-           MSymbol id = (n != null ? n.InnerText : MSymbol.nil);
-
-           MInputMethod im = MInputMethod.Find (language, name, subname);
-           if (im == null || ! im.Open ())
-             continue;
-           if (id == MSymbol.nil)
-             im.domain.CopyFunc (domain);
-           else
-             im.domain.CopyFunc (domain, id);
-         }
-      for (XmlNode nn = node.FirstChild; nn != null; nn = nn.NextSibling)
-       if (nn.NodeType == XmlNodeType.Element
-           && nn.Name != "xi:include")
+       if (nn.NodeType == XmlNodeType.Element)
          domain.Defun ((MSymbol) node.GetAttribute ("id"));
       for (XmlNode nn = node.FirstChild; nn != null; nn = nn.NextSibling)
          domain.Defun ((MSymbol) node.GetAttribute ("id"));
       for (XmlNode nn = node.FirstChild; nn != null; nn = nn.NextSibling)
-       if (nn.NodeType == XmlNodeType.Element
-           && nn.Name != "xi:include")
+       if (nn.NodeType == XmlNodeType.Element)
          domain.Defun ((MSymbol) node.GetAttribute ("id"), null,
          domain.Defun ((MSymbol) node.GetAttribute ("id"), null,
-                             nn.FirstChild);
+                       nn.FirstChild);
     }
 
     private void parse_maps (XmlNode node)
     }
 
     private void parse_maps (XmlNode node)
@@ -1631,15 +1639,14 @@ namespace M17N.Input
     private static Xex.Term Fmarker (Xex.Domain domain, Xex.Variable vari,
                                     Xex.Term[] args)
     {
     private static Xex.Term Fmarker (Xex.Domain domain, Xex.Variable vari,
                                     Xex.Term[] args)
     {
-      MSymbol sym = (MSymbol) args[0].Args[0].Val;
-
-      return ((MInputContext) domain.context).marker (sym);
+      MSymbol name = (string) args[0].Nameval;
+      return Marker.Get (name);
     }
 
     }
 
-    private static Xex.Term char_at (Xex.Domain domain, Xex.Variable vari,
-                                    Xex.Term[] args)
+    private static Xex.Term Fchar_at (Xex.Domain domain, Xex.Variable vari,
+                                     Xex.Term[] args)
     {
     {
-      return ((MInputContext) domain.context).char_at ((int) args[0].Val);
+      return ((MInputContext) domain.context).char_at (args[0].Intval);
     }
 
     private static Xex.Term Fdelete (Xex.Domain domain, Xex.Variable vari,
     }
 
     private static Xex.Term Fdelete (Xex.Domain domain, Xex.Variable vari,
@@ -1678,14 +1685,22 @@ namespace M17N.Input
     private static Xex.Term Fmove (Xex.Domain domain, Xex.Variable vari,
                                 Xex.Term[] args)
     {
     private static Xex.Term Fmove (Xex.Domain domain, Xex.Variable vari,
                                 Xex.Term[] args)
     {
-      ((MInputContext) domain.context).move (args[0].Intval);
+      if (args[0].IsInt)
+       ((MInputContext) domain.context).move (args[0].Intval);
+      else
+       {
+         Marker m = (Marker) args[0].Objval;
+         MInputContext ic = (MInputContext) domain.context;
+         ((MInputContext) domain.context).move (m.Position (ic));
+       }
       return args[0];
     }
 
     private static Xex.Term Fmark (Xex.Domain domain, Xex.Variable vari,
                                   Xex.Term[] args)
     {
       return args[0];
     }
 
     private static Xex.Term Fmark (Xex.Domain domain, Xex.Variable vari,
                                   Xex.Term[] args)
     {
-      ((MInputContext) domain.context).mark ((Marker) args[0].Objval);
+      Marker m = (Marker) args[0].Objval;
+      m.Mark ((MInputContext) domain.context);
       return args[0];
     }
 
       return args[0];
     }
 
@@ -1696,7 +1711,7 @@ namespace M17N.Input
     }
 
     private static Xex.Term Fpushback (Xex.Domain domain, Xex.Variable vari,
     }
 
     private static Xex.Term Fpushback (Xex.Domain domain, Xex.Variable vari,
-                                      Xex[] args)
+                                      Xex.Term[] args)
     {
       MInputContext ic = (MInputContext) domain.context;
 
     {
       MInputContext ic = (MInputContext) domain.context;
 
@@ -1872,7 +1887,7 @@ namespace M17N.Input
 
     internal void insert (Xex.Term arg)
     {
 
     internal void insert (Xex.Term arg)
     {
-      if (arg.IsInt is int)
+      if (arg.IsInt)
        preedit_replace (cursor_pos, cursor_pos, arg.Intval);
       else
        preedit_replace (cursor_pos, cursor_pos, new MText (arg.Strval));
        preedit_replace (cursor_pos, cursor_pos, arg.Intval);
       else
        preedit_replace (cursor_pos, cursor_pos, new MText (arg.Strval));
index 84d808e..ae56091 100644 (file)
@@ -103,7 +103,7 @@ namespace System.Xml.Expression
     private static Name Ndescription = "description";
     private static Name Nrange = "range";
 
     private static Name Ndescription = "description";
     private static Name Nrange = "range";
 
-    internal abstract class Function
+    public abstract class Function
     {
       public Name name;
       public int min_arg, max_arg;
     {
       public Name name;
       public int min_arg, max_arg;
@@ -385,7 +385,7 @@ namespace System.Xml.Expression
        }
       }
 
        }
       }
 
-      internal class Str : Variable
+      public class Str : Variable
       {
        public string[] range;
 
       {
        public string[] range;
 
@@ -435,7 +435,7 @@ namespace System.Xml.Expression
        }
       }
 
        }
       }
 
-      internal class Sym : Variable
+      public class Sym : Variable
       {
        public Name[] range;
 
       {
        public Name[] range;
 
@@ -680,6 +680,11 @@ namespace System.Xml.Expression
        return lambda;
       }
 
        return lambda;
       }
 
+      public void Defun (Name name, Name[] args, bool args_evalled)
+      {
+       Function func = new Function.Lambda (this, name, args, args_evalled)
+      }
+
       public void Defun (XmlNode node)
       {
        Name name = node.Attributes[Nfname].Value;
       public void Defun (XmlNode node)
       {
        Name name = node.Attributes[Nfname].Value;
@@ -690,7 +695,7 @@ namespace System.Xml.Expression
        ((Function.Lambda) func).SetBody (node, this);
       }
 
        ((Function.Lambda) func).SetBody (node, this);
       }
 
-      public void Defvar (XmlNode node)
+      public Variable Defvar (XmlNode node)
       {
        Name name = node.Attributes[0].Value;
        String desc;
       {
        Name name = node.Attributes[0].Value;
        String desc;
@@ -817,11 +822,13 @@ namespace System.Xml.Expression
              vari = new Variable (name, Zero);
          }
        variables[name] = vari;
              vari = new Variable (name, Zero);
          }
        variables[name] = vari;
+       return vari;
       }
 
       }
 
-      public void Defvar (Variable vari)
+      public Variable Defvar (Variable vari)
       {
        variables[vari.name] = vari;
       {
        variables[vari.name] = vari;
+       return vari;
       }
 
       internal Variable Defvar (Name name)
       }
 
       internal Variable Defvar (Name name)
@@ -854,12 +861,16 @@ namespace System.Xml.Expression
          domain.functions[kv.Key] = kv.Value;
       }
 
          domain.functions[kv.Key] = kv.Value;
       }
 
-      public Variable GetVar (Name name)
+      public Variable GetVar (Name name, bool create)
       {
        Variable vari;
 
        if (! variables.TryGetValue (name, out vari))
       {
        Variable vari;
 
        if (! variables.TryGetValue (name, out vari))
-         variables[name] = vari = new Variable (name, Zero);
+         {
+           if (! create)
+             return null;
+           variables[name] = vari = new Variable (name, Zero);
+         }
        return vari;
       }
 
        return vari;
       }
 
@@ -1464,7 +1475,7 @@ namespace System.Xml.Expression
          if (name == Nfuncall)
            name = node.Attributes[0].Value;
          else if (node.Attributes[Nvname] != null)
          if (name == Nfuncall)
            name = node.Attributes[0].Value;
          else if (node.Attributes[Nvname] != null)
-           vari = domain.GetVar (node.Attributes[Nvname].Value);
+           vari = domain.GetVar (node.Attributes[Nvname].Value, true);
          func = domain.GetFunc (name);
          XmlNodeList nlist = node.ChildNodes;
          int nargs = nlist.Count;
          func = domain.GetFunc (name);
          XmlNodeList nlist = node.ChildNodes;
          int nargs = nlist.Count;
@@ -1478,10 +1489,16 @@ namespace System.Xml.Expression
            args[i] = new Term (nlist[i], domain);
        }
 
            args[i] = new Term (nlist[i], domain);
        }
 
+      public Funcall (Domain domain, Name fname, Term[] args)
+       {
+         func = domain.GetFunc (fname);
+         this.args = args;
+       }
+
       public Funcall (Domain domain, Name fname, Name vname, Term[] args)
        {
          func = domain.GetFunc (fname);
       public Funcall (Domain domain, Name fname, Name vname, Term[] args)
        {
          func = domain.GetFunc (fname);
-         vari = domain.GetVar (vname);
+         vari = domain.GetVar (vname, true);
          this.args = args;
        }
 
          this.args = args;
        }
 
@@ -1539,7 +1556,7 @@ namespace System.Xml.Expression
              else if (name == Nstring)
                objval = node.InnerText.Clone ();
              else if (name == Nvarref)
              else if (name == Nstring)
                objval = node.InnerText.Clone ();
              else if (name == Nvarref)
-               objval = domain.GetVar ((Name) node.Attributes[0].Value);
+               objval = domain.GetVar ((Name) node.Attributes[0].Value, true);
              else if (name == Nlist)
                {
                  List<Term> list = new List<Term> ();
              else if (name == Nlist)
                {
                  List<Term> list = new List<Term> ();