2 using System.Collections;
3 using System.Collections.Generic;
7 namespace System.Xml.Expression
9 public abstract class Xex
11 public static bool Debug = false;
13 public static void DebugWrite (string fmt, params object[] arg)
16 Console.Write (fmt, arg);
19 public struct Name : IEquatable<Name>
21 private static NameTable nt = new NameTable ();
25 public Name (string str)
30 public static implicit operator Name (string str)
32 return new Name (str);
35 public static implicit operator string (Name name)
40 public static bool operator== (Name n1, Name n2)
42 return (object) n1.name == (object) n2.name;
45 public static bool operator!= (Name n1, Name n2)
47 return (object) n1.name != (object) n2.name;
50 public static bool operator== (Name n1, string n2)
52 return (object) n1.name == (object) n2;
55 public static bool operator!= (Name n1, string n2)
57 return (object) n1.name != (object) n2;
60 public static bool operator== (string n1, Name n2)
62 return (object) n1 == (object) n2.name;
65 public static bool operator!= (string n1, Name n2)
67 return (object) n1 != (object) n2.name;
70 public bool Equals (Name name)
72 return Object.ReferenceEquals (this.name, name.name);
75 public override bool Equals (object obj)
77 return Object.ReferenceEquals (this.name, obj);
80 public override int GetHashCode ()
82 return name.GetHashCode ();
85 public static NameTable Table { get { return nt; } }
87 public override string ToString () { return name; }
90 private static Name Nexpr = "expr";
92 private static Name Nfuncall = "funcall";
93 private static Name Nvariable = "variable";
94 private static Name Ninteger = "integer";
95 private static Name Nstring = "string";
96 private static Name Nboolean = "boolean";
97 private static Name Nsymbol = "symbol";
98 private static Name Nlist = "list";
99 private static Name Nobject = "object";
101 private static Name Ndefun = "defun";
102 private static Name Nfname = "fname";
103 private static Name Nargs = "args";
104 private static Name Nargs_unevalled = "args-unevalled";
105 private static Name Noptional = "optional";
106 private static Name Nrest = "rest";
107 private static Name Nbody = "body";
109 private static Name Ndefvar = "defvar";
110 private static Name Ndescription = "description";
111 private static Name Nrange = "range";
113 private static Name Nprogn = "progn";
115 internal abstract class Function
118 public int min_arg, max_arg;
120 public Function () { }
122 public Function (Name name, int min_arg, int max_arg)
125 this.min_arg = min_arg;
126 this.max_arg = max_arg;
129 public abstract object Call (object[] args, Domain domain);
131 public override string ToString ()
136 internal class Subroutine : Function
138 public Builtin builtin;
140 public Subroutine (Builtin builtin, Name name,
141 int min_arg, int max_arg)
142 : base (name, min_arg, max_arg)
144 this.builtin = builtin;
147 public override object Call (object[] args, Domain domain)
151 for (int i = 0; i < args.Length; i++)
153 object val = ((Xex) args[i]).Eval (domain);
155 throw new Exception (args[i] + ":evaled to null");
158 DebugWrite ("calling (" + this);
159 foreach (object a in args)
160 DebugWrite (" " + a);
161 DebugWrite (") => ");
162 result = builtin (args, domain);
163 DebugWrite (result + "\n");
168 internal class SpecialForm : Function
170 public Builtin builtin;
172 public SpecialForm (Builtin builtin, Name name,
173 int min_arg, int max_arg)
174 : base (name, min_arg, max_arg)
176 this.builtin = builtin;
179 public override object Call (object[] args, Domain domain)
183 DebugWrite ("calling (" + this);
184 foreach (object a in args)
185 DebugWrite (" " + a);
186 DebugWrite (") => ");
187 result = builtin (args, domain);
188 DebugWrite (result + "\n");
193 internal class Lambda : Function
195 internal bool args_evalled;
196 internal Name[] args;
199 public Lambda (XmlNode node)
201 int nargs = 0, noptions = 0, nrest = 0;
202 name = node.Attributes[Nfname].Value;
204 node = node.FirstChild;
206 && (node.Name == Nargs || node.Name == Nargs_unevalled))
209 args_evalled = node.Name == Nargs;
210 for (n = node.FirstChild; n != null; n = n.NextSibling)
212 if (n.Name != Nsymbol)
216 if (n != null && n.Name == Noptional)
217 for (n = n.NextSibling; n != null; n = n.NextSibling)
226 max_arg = nargs + noptions + nrest;
229 args = new Name[max_arg];
231 for (int i = 0; i < max_arg; n = n.NextSibling)
232 if (n.Name == Nsymbol)
233 args[i++] = n.InnerText;
237 min_arg = max_arg = 0;
241 public void SetBody (XmlNode node, Domain domain)
244 for (node = node.FirstChild; node != null && node.Name != Nbody;
245 node = node.NextSibling);
248 XmlNodeList nlist = node.ChildNodes;
250 body = new Xex[nlist.Count];
251 for (int i = 0; i < nlist.Count; i++)
252 body[i] = New (nlist[i], domain);
256 public override object Call (object[] args, Domain domain)
258 Bindings current = domain.bindings;
259 object result = false;
264 for (i = 0; i < min_arg; i++)
265 args[i] = ((Xex) args[i]).Eval (domain);
266 for (i = 0; i < min_arg; i++)
268 Variable var = domain.GetVar (this.args[i]);
269 domain.Bind (var, args[i]);
271 DebugWrite ("calling (" + this);
272 foreach (Xex e in body)
273 result = e.Eval (domain);
274 DebugWrite (") => " + result + "\n");
276 domain.UnboundTo (current);
281 public override string ToString ()
283 string str = "(" + name;
284 foreach (Name a in args)
291 internal abstract class Variable
293 public readonly Name name;
294 public readonly Name type;
297 public Variable (Name name, Name type, object value)
310 if (! ValueP (value))
311 throw new Exception ("Invalid value of " + name + ": " + value);
316 public abstract bool ValueP (object value);
318 public override string ToString () { return name + "=" + val; }
321 internal class VarInt : Variable
328 public Range[] ranges;
330 public VarInt (Name name, object value) : base (name, Ninteger, value) { }
332 public override bool ValueP (object value)
336 if (! (value is int))
341 foreach (Range r in ranges)
342 if (i >= r.from && i <= r.to)
348 internal class VarStr : Variable
350 public string[] ranges;
352 public VarStr (Name name, object value) : base (name, Nstring, value) { }
354 public override bool ValueP (object value)
358 if (! (value is string))
362 str = (string) value;
363 foreach (string s in ranges)
370 internal class VarBool : Variable
372 public VarBool (Name name, object value)
373 : base (name, Nboolean, value) { }
375 public override bool ValueP (object value)
377 if (! (value is bool))
383 internal class VarMisc : Variable
385 public VarMisc (Name name, object value) : base (name, Nobject, value) { }
387 public override bool ValueP (object value)
393 internal class Bindings
395 private Variable vari;
396 private object old_value;
397 private Bindings next;
399 private Bindings (Variable vari)
402 old_value = vari.val;
405 public static Bindings Bind (Bindings bindings,
406 Variable vari, object value)
408 Bindings b = new Bindings (vari);
410 b.vari.Value = value;
415 internal Bindings UnboundTo (Bindings boundary)
417 for (Bindings b = this; b != boundary; b = b.next)
418 vari.val = b.old_value;
422 public override string ToString ()
424 string str = "(bindings";
425 for (Bindings b = this; b != null; b = b.next)
426 str += " " + vari.name + "=" + b.old_value;
432 internal class ThrowException : Exception
437 public ThrowException (Name tag, object value) : base ()
447 public object context;
449 internal Dictionary<Name, Function> functions;
450 internal Dictionary<Name, Variable> variables;
451 internal Bindings bindings;
455 functions = new Dictionary<Name, Function> ();
456 variables = new Dictionary<Name, Variable> ();
459 public Domain (object context) : this (basic, context)
463 public Domain (Domain parent, object context)
465 functions = new Dictionary<Name, Function> (parent.functions);
466 variables = new Dictionary<Name, Variable> (parent.variables);
467 this.context = context;
470 internal void Bind (Variable vari, object value)
472 bindings = Bindings.Bind (bindings, vari, value);
473 DebugWrite ("binding " + vari);
476 internal void UnboundTo (Bindings boundary)
478 if (bindings != null)
479 bindings = bindings.UnboundTo (boundary);
482 public void DefSubr (Builtin builtin, string str,
483 int min_arg, int max_arg)
487 = new Function.Subroutine (builtin, name, min_arg, max_arg);
490 public void DefSpecial (Builtin builtin, string str,
491 int min_arg, int max_arg)
495 = new Function.SpecialForm (builtin, name, min_arg, max_arg);
498 internal Function.Lambda RegisterFunction (XmlNode node)
500 Function.Lambda lambda = new Function.Lambda (node);
502 functions[lambda.name] = lambda;
506 internal Function Defun (XmlNode node)
508 Name name = node.Attributes[Nfname].Value;
511 if (! functions.TryGetValue (name, out func))
512 func = RegisterFunction (node);
513 ((Function.Lambda) func).SetBody (node, this);
517 public void Defvar (Name name, XmlNode node)
521 if (node.Name == Ndescription)
522 node = node.NextSibling;
525 Name type = node.Name;
526 XmlNodeList range_list = null;
528 string val = node.InnerText;
530 node = node.NextSibling;
533 range_list = node.ChildNodes;
534 nranges = range_list.Count;
537 if (type == Ninteger)
539 VarInt vi = new VarInt (name, parse_integer (val));
540 if (range_list != null)
542 vi.ranges = new VarInt.Range[nranges];
544 for (int i = 0; i < nranges; i++)
546 XmlNode n = range_list[i];
548 if (n.Name == Nrange)
551 parse_integer (n.FirstChild.InnerText);
553 parse_integer (n.LastChild.InnerText);
557 int num = parse_integer (n.InnerText);
558 vi.ranges[i].from = vi.ranges[i].to = num;
564 else if (type == Nstring)
566 VarStr vs = new VarStr (name, val);
567 if (range_list != null)
568 vs.ranges = new string[nranges];
569 for (int i = 0; i < nranges; i++)
570 vs.ranges[i] = range_list[i].Value;
573 else if (type == Nboolean)
575 vari = new VarBool (name, val == "true");
578 throw new Exception ("Unknown type: " + type);
581 vari = new VarMisc (name, null);
582 variables[name] = vari;
585 internal Function GetFunc (Name name)
589 if (! functions.TryGetValue (name, out func))
590 throw new Exception ("Unknown function: " + name);
594 public bool CopyFunc (Domain domain, Name name)
596 Function func = GetFunc (name);
598 domain.functions[name] = func;
602 public void CopyFunc (Domain domain)
604 foreach (KeyValuePair<Name, Function> kv in functions)
605 domain.functions[kv.Key] = kv.Value;
608 internal Variable GetVar (Name name)
612 if (! variables.TryGetValue (name, out vari))
613 variables[name] = vari = new VarMisc (name, null);
617 public override string ToString ()
619 string str = "<(functions";
620 foreach (KeyValuePair<Name, Function> kv in functions)
622 str += ") (variabls";
623 foreach (KeyValuePair<Name, Variable> kv in variables)
626 if (bindings != null)
627 str += " " + bindings;
629 str += " (" + context + ")";
635 public delegate object Builtin (object[] args, Domain domain);
637 private static Domain basic = new Domain ();
639 internal static Function Fprogn;
643 basic.DefSubr (set_value, "set", 2, 2);
644 basic.DefSubr (set_value, "=", 2, 2);
645 basic.DefSpecial (and, "and", 1, -1);
646 basic.DefSpecial (and, "&&", 1, -1);
647 basic.DefSpecial (or, "or", 1, -1);
648 basic.DefSpecial (or, "||", 1, -1);
649 basic.DefSubr (not, "not", 1, 1);
650 basic.DefSubr (not, "!", 1, 1);
651 basic.DefSubr (add, "add", 2, -1);
652 basic.DefSubr (add, "+", 2, -1);
653 basic.DefSubr (mul, "mul", 2, -1);
654 basic.DefSubr (mul, "*", 2, -1);
655 basic.DefSubr (sub, "sub", 1, -1);
656 basic.DefSubr (sub, "-", 1, -1);
657 basic.DefSubr (div, "div", 2, -1);
658 basic.DefSubr (div, "/", 2, -1);
659 basic.DefSubr (mod, "mod", 2, 2);
660 basic.DefSubr (mod, "%", 2, 2);
661 basic.DefSubr (logior, "logior", 2, -1);
662 basic.DefSubr (logior, "|", 2, -1);
663 basic.DefSubr (logand, "logand", 2, -1);
664 basic.DefSubr (logand, "&", 2, -1);
665 basic.DefSubr (add_set, "add-set", 2, -1);
666 basic.DefSubr (add_set, "+=", 2, -1);
667 basic.DefSubr (mul_set, "mul-set", 2, -1);
668 basic.DefSubr (mul_set, "*=", 2, -1);
669 basic.DefSubr (sub_set, "sub-set", 2, -1);
670 basic.DefSubr (sub_set, "-=", 2, -1);
671 basic.DefSubr (div_set, "div-set", 2, -1);
672 basic.DefSubr (div_set, "/=", 2, -1);
673 basic.DefSubr (mod_set, "mod-set", 2, 2);
674 basic.DefSubr (mod_set, "%=", 2, 2);
675 basic.DefSubr (logior_set, "logior-set", 2, -1);
676 basic.DefSubr (logior_set, "|=", 2, -1);
677 basic.DefSubr (logand_set, "logand-set", 2, -1);
678 basic.DefSubr (logand_set, "&=", 2, -1);
679 basic.DefSubr (lsh, "lsh", 2, 2);
680 basic.DefSubr (lsh, "<<", 2, 2);
681 basic.DefSubr (rsh, "rsh", 2, 2);
682 basic.DefSubr (rsh, ">>", 2, 2);
683 basic.DefSubr (lsh_set, "lsh-set", 2, 2);
684 basic.DefSubr (lsh_set, "<<=", 2, 2);
685 basic.DefSubr (rsh_set, "rsh-set", 2, 2);
686 basic.DefSubr (rsh_set, ">>=", 2, 2);
687 basic.DefSubr (eq, "eq", 2, -1);
688 basic.DefSubr (eq, "==", 2, -1);
689 basic.DefSubr (noteq, "noteq", 2, 2);
690 basic.DefSubr (noteq, "!=", 2, 2);
691 basic.DefSubr (less_than, "lt", 2, -1);
692 basic.DefSubr (less_than, "<", 2, -1);
693 basic.DefSubr (less_eq, "le", 2, -1);
694 basic.DefSubr (less_eq, "<=", 2, -1);
695 basic.DefSubr (greater_than, "gt", 2, -1);
696 basic.DefSubr (greater_than, ">", 2, -1);
697 basic.DefSubr (greater_eq, "ge", 2, -1);
698 basic.DefSubr (greater_eq, ">=", 2, -1);
699 basic.DefSubr (eval_clause, "eval", 1, 1);
700 basic.DefSpecial (progn_clause, "progn", 0, -1);
701 basic.DefSpecial (progn_clause, "expr", 0, -1);
702 basic.DefSpecial (if_clause, "if", 2, -1);
703 basic.DefSpecial (when_clause, "when", 1, -1);
704 basic.DefSpecial (while_clause, "while", 1, -1);
706 Fprogn = basic.GetFunc (Nprogn);
709 private static bool is_true (object val)
711 return (val is bool ? (bool) val
712 : val is int ? (int) val == 0
716 private static object set_value (object[] args, Domain domain)
718 Variable vari = domain.GetVar ((Name) args[0]);
720 vari.Value = args[1];
724 private static object and (object[] args, Domain domain)
726 foreach (object arg in args)
727 if (! is_true (((Xex) arg).Eval (domain)))
732 private static object or (object[] args, Domain domain)
734 foreach (object arg in args)
735 if (is_true (((Xex) arg).Eval (domain)))
740 private static object not (object[] args, Domain domain)
742 return ! is_true (args);
745 private static object add (object[] args, Domain domain)
748 foreach (object arg in args)
753 private static object mul (object[] args, Domain domain)
756 foreach (object arg in args)
761 private static object sub (object[] args, Domain domain)
763 int n = (int) args[0];
764 if (args.Length == 1)
766 for (int i = 1; i < args.Length; i++)
771 private static object div (object[] args, Domain domain)
773 int n = (int) args[0];
774 for (int i = 1; i < args.Length; i++)
779 private static object mod (object[] args, Domain domain)
781 return ((int) args[0] % (int) args[1]);
784 private static object logior (object[] args, Domain domain)
787 foreach (object arg in args)
792 private static object logand (object[] args, Domain domain)
794 int n = (int) args[0];
795 for (int i = 1; i < args.Length; i++)
800 private static object add_set (object[] args, Domain domain)
802 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
803 int n = (int) vari.val;
805 for (int i = 1; i < args.Length; i++)
811 private static object mul_set (object[] args, Domain domain)
813 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
814 int n = (int) vari.val;
816 for (int i = 1; i < args.Length; i++)
822 private static object sub_set (object[] args, Domain domain)
824 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
825 int n = (int) vari.val;
827 for (int i = 1; i < args.Length; i++)
833 private static object div_set (object[] args, Domain domain)
835 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
836 int n = (int) vari.val;
838 for (int i = 1; i < args.Length; i++)
844 private static object mod_set (object[] args, Domain domain)
846 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
847 int n = (int) vari.val;
849 for (int i = 1; i < args.Length; i++)
855 private static object logior_set (object[] args, Domain domain)
857 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
858 int n = (int) vari.val;
860 for (int i = 1; i < args.Length; i++)
866 private static object logand_set (object[] args, Domain domain)
868 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
869 int n = (int) vari.val;
871 for (int i = 1; i < args.Length; i++)
877 private static object lsh (object[] args, Domain domain)
879 return (int) args[0] << (int) args[1];
882 private static object lsh_set (object[] args, Domain domain)
884 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
885 int n = (int) vari.val;
892 private static object rsh (object[] args, Domain domain)
894 return (int) args[0] >> (int) args[1];
897 private static object rsh_set (object[] args, Domain domain)
899 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
900 int n = (int) vari.val;
907 private static object eq (object[] args, Domain domain)
911 for (int i = 1; i < args.Length; i++)
917 private static object noteq (object[] args, Domain domain)
919 return (args[0] != args[1]);
922 private static object less_than (object[] args, Domain domain)
924 int n = (int) args[0];
926 for (int i = 1; i < args.Length; i++)
928 int n1 = (int) args[i];
936 private static object less_eq (object[] args, Domain domain)
938 int n = (int) args[0];
939 for (int i = 1; i < args.Length; i++)
941 int n1 = (int) args[i];
949 private static object greater_than (object[] args, Domain domain)
951 int n = (int) args[0];
952 for (int i = 1; i < args.Length; i++)
954 int n1 = (int) args[i];
962 private static object greater_eq (object[] args, Domain domain)
964 int n = (int) args[0];
965 for (int i = 1; i < args.Length; i++)
967 int n1 = (int) args[i];
975 private static object eval_clause (object[] args, Domain domain)
977 return ((Xex) args[0]).Eval (domain);
980 private static object progn_clause (object[] args, Domain domain)
982 object result = true;
984 foreach (object arg in args)
985 result = ((Xex) arg).Eval (domain);
989 private static object if_clause (object[] args, Domain domain)
993 if (is_true (((Xex) args[0]).Eval (domain)))
994 result = ((Xex) args[1]).Eval (domain);
998 for (int i = 2; i < args.Length; i++)
999 result = ((Xex) args[i]).Eval (domain);
1004 private static object when_clause (object[] args, Domain domain)
1006 if (! is_true (((Xex) args[0]).Eval (domain)))
1009 object result = true;
1010 for (int i = 1; i < args.Length; i++)
1011 result = ((Xex) args[i]).Eval (domain);
1015 private static object while_clause (object[] args, Domain domain)
1017 while (is_true (((Xex) args[0]).Eval (domain)))
1018 for (int i = 1; i < args.Length; i++)
1019 ((Xex) args[i]).Eval (domain);
1023 public abstract object Eval (Domain domain);
1024 public abstract Name TypeOf { get; }
1026 private class Funcall : Xex
1028 internal Function func;
1029 internal Xex[] args;
1030 internal object[] real_args;
1032 public Funcall (Function func, Xex[] args)
1036 real_args = new object[args.Length];
1039 public override object Eval (Domain domain)
1041 for (int i = 0; i < args.Length; i++)
1042 real_args[i] = args[i];
1043 return func.Call (real_args, domain);
1046 public override Name TypeOf { get { return Nfuncall; } }
1048 public override string ToString ()
1050 string str = "(" + func.name;
1052 foreach (Xex e in args)
1053 str += " " + e.ToString ();
1058 private class Varref : Xex
1060 internal Variable vari;
1062 public Varref (Variable vari) { this.vari = vari; }
1064 public override object Eval (Domain domain)
1069 public override Name TypeOf { get { return Nvariable; } }
1071 public override string ToString ()
1073 return "$" + vari.name + "/" + vari.val;
1077 private class Const : Xex
1081 public Const (object val) { this.val = val; }
1083 public override object Eval (Domain domain) { return val; }
1085 public override Name TypeOf {
1088 return (val is int ? Ninteger
1089 : val is string ? Nstring
1090 : val is bool ? Nboolean
1091 : val is Name ? Nsymbol
1096 public override string ToString () { return val.ToString (); }
1099 internal static int parse_integer (string str)
1101 int len = str.Length;
1102 bool negative = false;
1105 return (len == 0 ? 0 : str[0] - '0');
1110 if (c == '0' && str[1] == 'x')
1113 for (int idx = 2; idx < len; idx++)
1119 i = i * 16 + (c - '0');
1123 i = i * 16 + (c - 'A');
1127 i = i * 16 + (c - 'a');
1136 for (int idx = 1; idx < len; idx++)
1139 if (c < '0' || c > '9')
1141 i = i * 10 + (c - '0');
1143 return negative ? - i : i;
1146 private static int pre_parse (XmlNodeList nlist, Domain domain)
1149 foreach (XmlNode node in nlist)
1151 if (node.Name == Ndefun)
1152 domain.RegisterFunction (node);
1153 else if (node.Name == Ndefvar)
1154 domain.Defvar ((Name) node.Attributes[0].Value, node.FirstChild);
1161 private static void post_parse (XmlNodeList nlist, Xex[] args,
1164 for (int i = 0, j = 0; i < nlist.Count; i++)
1166 XmlNode node = nlist[i];
1168 if (node.Name == Ndefun)
1169 domain.Defun (node);
1170 else if (node.Name != Ndefvar)
1171 args[j++] = New (node, domain);
1175 public static Xex New (string url, Domain domain)
1177 XmlDocument doc = new XmlDocument (Name.Table);
1180 using (XmlTextReader reader = new XmlTextReader (url, Name.Table))
1184 } while (reader.NodeType != XmlNodeType.None
1185 && (reader.NodeType != XmlNodeType.Element
1186 || Nexpr != reader.Name));
1187 if (reader.NodeType == XmlNodeType.None)
1188 throw new Exception ("Node <expr> not found");
1189 node = doc.ReadNode (reader);
1192 return New (node, domain);
1195 public static Xex New (XmlNode node, Domain domain)
1197 Name name = node.Name;
1199 if (name == Nvariable)
1201 Variable vari = domain.GetVar ((Name) node.Attributes[0].Value);
1202 xex = new Xex.Varref (vari);
1204 else if (name == Ninteger)
1205 xex = new Xex.Const (parse_integer (node.InnerText));
1206 else if (name == Nstring)
1207 xex = new Xex.Const (node.InnerText);
1208 else if (name == Nsymbol)
1209 xex = new Xex.Const ((Name) node.InnerText);
1210 else if (name == Nboolean)
1211 xex = new Xex.Const (node.InnerText == "true");
1212 else if (name == Nlist)
1214 List<Xex> list = new List<Xex> ();
1215 for (XmlNode n = node.FirstChild; n != null; n = n.NextSibling)
1216 list.Add (New (n, domain));
1217 xex = new Xex.Const (list);
1221 if (name == Nfuncall)
1222 name = node.Attributes[0].Value;
1223 Function func = domain.GetFunc (name);
1225 XmlNodeList nlist = node.ChildNodes;
1226 int nargs = nlist.Count;
1228 if (nargs < func.min_arg
1229 || (func.max_arg >= 0 && nargs > func.max_arg))
1230 throw new Exception ("Invalid number of arguments to: "
1231 + name + " " + nargs);
1232 nargs = pre_parse (nlist, domain);
1233 Xex[] args = new Xex[nargs];
1234 post_parse (nlist, args, domain);
1235 xex = new Xex.Funcall (func, args);