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 struct Name : IEquatable<Name>
15 private static NameTable nt = new NameTable ();
19 public Name (string str)
24 public static implicit operator Name (string str)
26 return new Name (str);
29 public static implicit operator string (Name name)
34 public static bool operator== (Name n1, Name n2)
36 return (object) n1.name == (object) n2.name;
39 public static bool operator!= (Name n1, Name n2)
41 return (object) n1.name != (object) n2.name;
44 public static bool operator== (Name n1, string n2)
46 return (object) n1.name == (object) n2;
49 public static bool operator!= (Name n1, string n2)
51 return (object) n1.name != (object) n2;
54 public static bool operator== (string n1, Name n2)
56 return (object) n1 == (object) n2.name;
59 public static bool operator!= (string n1, Name n2)
61 return (object) n1 != (object) n2.name;
64 public bool Equals (Name name)
66 return Object.ReferenceEquals (this.name, name.name);
69 public override bool Equals (object obj)
71 return Object.ReferenceEquals (this.name, obj);
74 public override int GetHashCode ()
76 return name.GetHashCode ();
79 public static NameTable Table { get { return nt; } }
81 public override string ToString () { return name; }
84 private static Name Nexpr = "expr";
86 private static Name Nfuncall = "funcall";
87 private static Name Nvariable = "variable";
88 private static Name Ninteger = "integer";
89 private static Name Nstring = "string";
90 private static Name Nboolean = "boolean";
91 private static Name Nsymbol = "symbol";
92 private static Name Nlist = "list";
93 private static Name Nobject = "object";
95 private static Name Ndefun = "defun";
96 private static Name Nfname = "fname";
97 private static Name Nargs = "args";
98 private static Name Nargs_unevalled = "args-unevalled";
99 private static Name Noptional = "optional";
100 private static Name Nrest = "rest";
101 private static Name Nbody = "body";
103 private static Name Ndefvar = "defvar";
104 private static Name Ndescription = "description";
105 private static Name Nrange = "range";
107 private static Name Nprogn = "progn";
109 internal abstract class Function
112 public int min_arg, max_arg;
114 public Function () { }
116 public Function (Name name, int min_arg, int max_arg)
119 this.min_arg = min_arg;
120 this.max_arg = max_arg;
123 public abstract object Call (object[] args, Domain domain);
125 public override string ToString ()
130 internal class Subroutine : Function
132 public Builtin builtin;
134 public Subroutine (Builtin builtin, Name name,
135 int min_arg, int max_arg)
136 : base (name, min_arg, max_arg)
138 this.builtin = builtin;
141 public override object Call (object[] args, Domain domain)
145 for (int i = 0; i < args.Length; i++)
147 object val = args[i];
149 val = ((Xex) val).Eval (domain);
151 throw new Exception (args[i] + ":evaled to null");
154 result = builtin (args, domain);
159 internal class SpecialForm : Function
161 public Builtin builtin;
163 public SpecialForm (Builtin builtin, Name name,
164 int min_arg, int max_arg)
165 : base (name, min_arg, max_arg)
167 this.builtin = builtin;
170 public override object Call (object[] args, Domain domain)
172 return builtin (args, domain);
176 internal class Lambda : Function
178 internal bool args_evalled;
179 internal Name[] args;
182 public Lambda (XmlNode node)
184 int nargs = 0, noptions = 0, nrest = 0;
185 name = node.Attributes[Nfname].Value;
187 node = node.FirstChild;
189 && (node.Name == Nargs || node.Name == Nargs_unevalled))
192 args_evalled = node.Name == Nargs;
193 for (n = node.FirstChild; n != null; n = n.NextSibling)
195 if (n.Name != Nsymbol)
199 if (n != null && n.Name == Noptional)
200 for (n = n.NextSibling; n != null; n = n.NextSibling)
209 max_arg = nargs + noptions + nrest;
212 args = new Name[max_arg];
214 for (int i = 0; i < max_arg; n = n.NextSibling)
215 if (n.Name == Nsymbol)
216 args[i++] = n.InnerText;
220 min_arg = max_arg = 0;
224 public void SetBody (XmlNode node, Domain domain)
227 for (node = node.FirstChild; node != null && node.Name != Nbody;
228 node = node.NextSibling);
231 XmlNodeList nlist = node.ChildNodes;
233 body = new Xex[nlist.Count];
234 for (int i = 0; i < nlist.Count; i++)
235 body[i] = New (nlist[i], domain);
239 public override object Call (object[] args, Domain domain)
241 Bindings current = domain.bindings;
242 object result = false;
247 for (i = 0; i < min_arg; i++)
248 args[i] = ((Xex) args[i]).Eval (domain);
249 for (i = 0; i < min_arg; i++)
251 Variable var = domain.GetVar (this.args[i]);
252 domain.Bind (var, args[i]);
254 foreach (Xex e in body)
255 result = e.Eval (domain);
257 domain.UnboundTo (current);
262 public override string ToString ()
264 string str = "(" + name;
265 foreach (Name a in args)
272 internal abstract class Variable
274 public readonly Name name;
275 public readonly Name type;
278 public Variable (Name name, Name type, object value)
291 if (! ValueP (value))
292 throw new Exception ("Invalid value of " + name + ": " + value);
297 public abstract bool ValueP (object value);
299 public override string ToString () { return name + "(" + val + ")"; }
302 internal class VarInt : Variable
309 public Range[] ranges;
311 public VarInt (Name name, object value) : base (name, Ninteger, value) { }
313 public override bool ValueP (object value)
317 if (! (value is int))
322 foreach (Range r in ranges)
323 if (i >= r.from && i <= r.to)
329 internal class VarStr : Variable
331 public string[] ranges;
333 public VarStr (Name name, object value) : base (name, Nstring, value) { }
335 public override bool ValueP (object value)
339 if (! (value is string))
343 str = (string) value;
344 foreach (string s in ranges)
351 internal class VarBool : Variable
353 public VarBool (Name name, object value)
354 : base (name, Nboolean, value) { }
356 public override bool ValueP (object value)
358 if (! (value is bool))
364 internal class VarMisc : Variable
366 public VarMisc (Name name, object value) : base (name, Nobject, value) { }
368 public override bool ValueP (object value)
374 internal class Bindings
376 private Variable vari;
377 private object old_value;
378 private Bindings next;
380 private Bindings (Variable vari)
383 old_value = vari.val;
386 public static Bindings Bind (Bindings bindings,
387 Variable vari, object value)
389 Bindings b = new Bindings (vari);
391 b.vari.Value = value;
396 internal Bindings UnboundTo (Bindings boundary)
398 for (Bindings b = this; b != boundary; b = b.next)
399 b.vari.val = b.old_value;
403 public override string ToString ()
405 string str = "(bindings";
406 for (Bindings b = this; b != null; b = b.next)
407 str += " " + vari.name + "=" + b.old_value;
413 internal class ThrowException : Exception
418 public ThrowException (Name tag, object value) : base ()
428 public object context;
429 public int depth = 0;
431 internal Dictionary<Name, Function> functions;
432 internal Dictionary<Name, Variable> variables;
433 internal Bindings bindings;
437 functions = new Dictionary<Name, Function> ();
438 variables = new Dictionary<Name, Variable> ();
441 public Domain (object context) : this (basic, context)
445 public Domain (Domain parent, object context)
447 functions = new Dictionary<Name, Function> (parent.functions);
448 variables = new Dictionary<Name, Variable> (parent.variables);
449 this.context = context;
452 internal void Bind (Variable vari, object value)
454 bindings = Bindings.Bind (bindings, vari, value);
457 internal void UnboundTo (Bindings boundary)
459 if (bindings != null)
460 bindings = bindings.UnboundTo (boundary);
463 public void DefSubr (Builtin builtin, string str,
464 int min_arg, int max_arg)
468 = new Function.Subroutine (builtin, name, min_arg, max_arg);
471 public void DefSpecial (Builtin builtin, string str,
472 int min_arg, int max_arg)
476 = new Function.SpecialForm (builtin, name, min_arg, max_arg);
479 internal Function.Lambda RegisterFunction (XmlNode node)
481 Function.Lambda lambda = new Function.Lambda (node);
483 functions[lambda.name] = lambda;
487 internal Function Defun (XmlNode node)
489 Name name = node.Attributes[Nfname].Value;
492 if (! functions.TryGetValue (name, out func))
493 func = RegisterFunction (node);
494 ((Function.Lambda) func).SetBody (node, this);
498 public void Defvar (Name name, XmlNode node)
502 if (node.Name == Ndescription)
503 node = node.NextSibling;
506 Name type = node.Name;
507 XmlNodeList range_list = null;
509 string val = node.InnerText;
511 node = node.NextSibling;
514 range_list = node.ChildNodes;
515 nranges = range_list.Count;
518 if (type == Ninteger)
520 VarInt vi = new VarInt (name, parse_integer (val));
521 if (range_list != null)
523 vi.ranges = new VarInt.Range[nranges];
525 for (int i = 0; i < nranges; i++)
527 XmlNode n = range_list[i];
529 if (n.Name == Nrange)
532 parse_integer (n.FirstChild.InnerText);
534 parse_integer (n.LastChild.InnerText);
538 int num = parse_integer (n.InnerText);
539 vi.ranges[i].from = vi.ranges[i].to = num;
545 else if (type == Nstring)
547 VarStr vs = new VarStr (name, val);
548 if (range_list != null)
549 vs.ranges = new string[nranges];
550 for (int i = 0; i < nranges; i++)
551 vs.ranges[i] = range_list[i].Value;
554 else if (type == Nboolean)
556 vari = new VarBool (name, val == "true");
559 throw new Exception ("Unknown type: " + type);
562 vari = new VarMisc (name, null);
563 variables[name] = vari;
566 internal Function GetFunc (Name name)
570 if (! functions.TryGetValue (name, out func))
571 throw new Exception ("Unknown function: " + name);
575 public bool CopyFunc (Domain domain, Name name)
577 Function func = GetFunc (name);
579 domain.functions[name] = func;
583 public void CopyFunc (Domain domain)
585 foreach (KeyValuePair<Name, Function> kv in functions)
586 domain.functions[kv.Key] = kv.Value;
589 internal Variable GetVar (Name name)
593 if (! variables.TryGetValue (name, out vari))
594 variables[name] = vari = new VarMisc (name, null);
598 public override string ToString ()
600 string str = "<(functions";
601 foreach (KeyValuePair<Name, Function> kv in functions)
603 str += ") (variabls";
604 foreach (KeyValuePair<Name, Variable> kv in variables)
607 if (bindings != null)
608 str += " " + bindings;
610 str += " (" + context + ")";
615 public void DebugWrite (bool head, string fmt, params object[] arg)
621 Console.WriteLine ();
622 for (int i = 0; i < depth; i++)
625 Console.Write (fmt, arg);
630 public delegate object Builtin (object[] args, Domain domain);
632 private static Domain basic = new Domain ();
634 internal static Function Fprogn;
638 basic.DefSubr (set_value, "set", 2, 2);
639 basic.DefSubr (set_value, "=", 2, 2);
640 basic.DefSpecial (and, "and", 1, -1);
641 basic.DefSpecial (and, "&&", 1, -1);
642 basic.DefSpecial (or, "or", 1, -1);
643 basic.DefSpecial (or, "||", 1, -1);
644 basic.DefSubr (not, "not", 1, 1);
645 basic.DefSubr (not, "!", 1, 1);
646 basic.DefSubr (add, "add", 2, -1);
647 basic.DefSubr (add, "+", 2, -1);
648 basic.DefSubr (mul, "mul", 2, -1);
649 basic.DefSubr (mul, "*", 2, -1);
650 basic.DefSubr (sub, "sub", 1, -1);
651 basic.DefSubr (sub, "-", 1, -1);
652 basic.DefSubr (div, "div", 2, -1);
653 basic.DefSubr (div, "/", 2, -1);
654 basic.DefSubr (mod, "mod", 2, 2);
655 basic.DefSubr (mod, "%", 2, 2);
656 basic.DefSubr (logior, "logior", 2, -1);
657 basic.DefSubr (logior, "|", 2, -1);
658 basic.DefSubr (logand, "logand", 2, -1);
659 basic.DefSubr (logand, "&", 2, -1);
660 basic.DefSubr (add_set, "add-set", 2, -1);
661 basic.DefSubr (add_set, "+=", 2, -1);
662 basic.DefSubr (mul_set, "mul-set", 2, -1);
663 basic.DefSubr (mul_set, "*=", 2, -1);
664 basic.DefSubr (sub_set, "sub-set", 2, -1);
665 basic.DefSubr (sub_set, "-=", 2, -1);
666 basic.DefSubr (div_set, "div-set", 2, -1);
667 basic.DefSubr (div_set, "/=", 2, -1);
668 basic.DefSubr (mod_set, "mod-set", 2, 2);
669 basic.DefSubr (mod_set, "%=", 2, 2);
670 basic.DefSubr (logior_set, "logior-set", 2, -1);
671 basic.DefSubr (logior_set, "|=", 2, -1);
672 basic.DefSubr (logand_set, "logand-set", 2, -1);
673 basic.DefSubr (logand_set, "&=", 2, -1);
674 basic.DefSubr (lsh, "lsh", 2, 2);
675 basic.DefSubr (lsh, "<<", 2, 2);
676 basic.DefSubr (rsh, "rsh", 2, 2);
677 basic.DefSubr (rsh, ">>", 2, 2);
678 basic.DefSubr (lsh_set, "lsh-set", 2, 2);
679 basic.DefSubr (lsh_set, "<<=", 2, 2);
680 basic.DefSubr (rsh_set, "rsh-set", 2, 2);
681 basic.DefSubr (rsh_set, ">>=", 2, 2);
682 basic.DefSubr (eq, "eq", 2, -1);
683 basic.DefSubr (eq, "==", 2, -1);
684 basic.DefSubr (noteq, "noteq", 2, 2);
685 basic.DefSubr (noteq, "!=", 2, 2);
686 basic.DefSubr (less_than, "lt", 2, -1);
687 basic.DefSubr (less_than, "<", 2, -1);
688 basic.DefSubr (less_eq, "le", 2, -1);
689 basic.DefSubr (less_eq, "<=", 2, -1);
690 basic.DefSubr (greater_than, "gt", 2, -1);
691 basic.DefSubr (greater_than, ">", 2, -1);
692 basic.DefSubr (greater_eq, "ge", 2, -1);
693 basic.DefSubr (greater_eq, ">=", 2, -1);
694 basic.DefSubr (eval_clause, "eval", 1, 1);
695 basic.DefSpecial (progn_clause, "progn", 0, -1);
696 basic.DefSpecial (progn_clause, "expr", 0, -1);
697 basic.DefSpecial (if_clause, "if", 2, -1);
698 basic.DefSpecial (when_clause, "when", 1, -1);
699 basic.DefSpecial (while_clause, "while", 1, -1);
701 Fprogn = basic.GetFunc (Nprogn);
704 private static bool is_true (object val)
706 return (val is bool ? (bool) val
707 : val is int ? (int) val == 0
711 private static object set_value (object[] args, Domain domain)
713 Variable vari = domain.GetVar ((Name) args[0]);
715 vari.Value = args[1];
719 private static object and (object[] args, Domain domain)
721 foreach (object arg in args)
722 if (! is_true (((Xex) arg).Eval (domain)))
727 private static object or (object[] args, Domain domain)
729 foreach (object arg in args)
730 if (is_true (((Xex) arg).Eval (domain)))
735 private static object not (object[] args, Domain domain)
737 return ! is_true (args);
740 private static object add (object[] args, Domain domain)
743 foreach (object arg in args)
748 private static object mul (object[] args, Domain domain)
751 foreach (object arg in args)
756 private static object sub (object[] args, Domain domain)
758 int n = (int) args[0];
759 if (args.Length == 1)
761 for (int i = 1; i < args.Length; i++)
766 private static object div (object[] args, Domain domain)
768 int n = (int) args[0];
769 for (int i = 1; i < args.Length; i++)
774 private static object mod (object[] args, Domain domain)
776 return ((int) args[0] % (int) args[1]);
779 private static object logior (object[] args, Domain domain)
782 foreach (object arg in args)
787 private static object logand (object[] args, Domain domain)
789 int n = (int) args[0];
790 for (int i = 1; i < args.Length; i++)
795 private static object add_set (object[] args, Domain domain)
797 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
798 int n = (int) vari.val;
800 for (int i = 1; i < args.Length; i++)
806 private static object mul_set (object[] args, Domain domain)
808 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
809 int n = (int) vari.val;
811 for (int i = 1; i < args.Length; i++)
817 private static object sub_set (object[] args, Domain domain)
819 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
820 int n = (int) vari.val;
822 for (int i = 1; i < args.Length; i++)
828 private static object div_set (object[] args, Domain domain)
830 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
831 int n = (int) vari.val;
833 for (int i = 1; i < args.Length; i++)
839 private static object mod_set (object[] args, Domain domain)
841 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
842 int n = (int) vari.val;
844 for (int i = 1; i < args.Length; i++)
850 private static object logior_set (object[] args, Domain domain)
852 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
853 int n = (int) vari.val;
855 for (int i = 1; i < args.Length; i++)
861 private static object logand_set (object[] args, Domain domain)
863 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
864 int n = (int) vari.val;
866 for (int i = 1; i < args.Length; i++)
872 private static object lsh (object[] args, Domain domain)
874 return (int) args[0] << (int) args[1];
877 private static object lsh_set (object[] args, Domain domain)
879 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
880 int n = (int) vari.val;
887 private static object rsh (object[] args, Domain domain)
889 return (int) args[0] >> (int) args[1];
892 private static object rsh_set (object[] args, Domain domain)
894 Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val);
895 int n = (int) vari.val;
902 private static object eq (object[] args, Domain domain)
906 for (int i = 1; i < args.Length; i++)
912 private static object noteq (object[] args, Domain domain)
914 return (args[0] != args[1]);
917 private static object less_than (object[] args, Domain domain)
919 int n = (int) args[0];
921 for (int i = 1; i < args.Length; i++)
923 int n1 = (int) args[i];
931 private static object less_eq (object[] args, Domain domain)
933 int n = (int) args[0];
934 for (int i = 1; i < args.Length; i++)
936 int n1 = (int) args[i];
944 private static object greater_than (object[] args, Domain domain)
946 int n = (int) args[0];
947 for (int i = 1; i < args.Length; i++)
949 int n1 = (int) args[i];
957 private static object greater_eq (object[] args, Domain domain)
959 int n = (int) args[0];
960 for (int i = 1; i < args.Length; i++)
962 int n1 = (int) args[i];
970 private static object eval_clause (object[] args, Domain domain)
972 return ((Xex) args[0]).Eval (domain);
975 private static object progn_clause (object[] args, Domain domain)
977 object result = true;
979 foreach (object arg in args)
980 result = ((Xex) arg).Eval (domain);
984 private static object if_clause (object[] args, Domain domain)
988 if (is_true (((Xex) args[0]).Eval (domain)))
989 result = ((Xex) args[1]).Eval (domain);
993 for (int i = 2; i < args.Length; i++)
994 result = ((Xex) args[i]).Eval (domain);
999 private static object when_clause (object[] args, Domain domain)
1001 if (! is_true (((Xex) args[0]).Eval (domain)))
1004 object result = true;
1005 for (int i = 1; i < args.Length; i++)
1006 result = ((Xex) args[i]).Eval (domain);
1010 private static object while_clause (object[] args, Domain domain)
1012 while (is_true (((Xex) args[0]).Eval (domain)))
1013 for (int i = 1; i < args.Length; i++)
1014 ((Xex) args[i]).Eval (domain);
1018 public abstract object Eval (Domain domain);
1019 public abstract Name TypeOf { get; }
1021 private class Funcall : Xex
1023 internal Function func;
1024 internal Xex[] args;
1025 internal object[] real_args;
1027 public Funcall (Function func, Xex[] args)
1031 real_args = new object[args.Length];
1034 public override object Eval (Domain domain)
1036 domain.DebugWrite (true, "(({0}", func);
1037 for (int i = 0; i < args.Length; i++)
1039 domain.DebugWrite (false, " {0}", args[i]);
1040 real_args[i] = args[i];
1042 domain.DebugWrite (false, ")");
1044 object result = func.Call (real_args, domain);
1046 domain.DebugWrite (true, " => {0})", result);
1050 public override Name TypeOf { get { return Nfuncall; } }
1052 public override string ToString ()
1054 string str = "(" + func.name;
1056 foreach (Xex e in args)
1057 str += " " + e.ToString ();
1062 private class Varref : Xex
1064 internal Variable vari;
1066 public Varref (Variable vari) { this.vari = vari; }
1068 public override object Eval (Domain domain)
1070 domain.DebugWrite (true, "(get-value {0})", vari);
1074 public override Name TypeOf { get { return Nvariable; } }
1076 public override string ToString ()
1078 return "$" + vari.name + "/" + vari.val;
1082 private class Const : Xex
1086 public Const (object val) { this.val = val; }
1088 public override object Eval (Domain domain)
1090 domain.DebugWrite (true, "(const {0})\n", val);
1094 public override Name TypeOf {
1097 return (val is int ? Ninteger
1098 : val is string ? Nstring
1099 : val is bool ? Nboolean
1100 : val is Name ? Nsymbol
1105 public override string ToString () { return val.ToString (); }
1108 internal static int parse_integer (string str)
1110 int len = str.Length;
1111 bool negative = false;
1114 return (len == 0 ? 0 : str[0] - '0');
1119 if (c == '0' && str[1] == 'x')
1122 for (int idx = 2; idx < len; idx++)
1128 i = i * 16 + (c - '0');
1132 i = i * 16 + (c - 'A');
1136 i = i * 16 + (c - 'a');
1145 for (int idx = 1; idx < len; idx++)
1148 if (c < '0' || c > '9')
1150 i = i * 10 + (c - '0');
1152 return negative ? - i : i;
1155 private static int pre_parse (XmlNodeList nlist, Domain domain)
1158 foreach (XmlNode node in nlist)
1160 if (node.Name == Ndefun)
1161 domain.RegisterFunction (node);
1162 else if (node.Name == Ndefvar)
1163 domain.Defvar ((Name) node.Attributes[0].Value, node.FirstChild);
1170 private static void post_parse (XmlNodeList nlist, Xex[] args,
1173 for (int i = 0, j = 0; i < nlist.Count; i++)
1175 XmlNode node = nlist[i];
1177 if (node.Name == Ndefun)
1178 domain.Defun (node);
1179 else if (node.Name != Ndefvar)
1180 args[j++] = New (node, domain);
1184 public static Xex New (string url, Domain domain)
1186 XmlDocument doc = new XmlDocument (Name.Table);
1189 using (XmlTextReader reader = new XmlTextReader (url, Name.Table))
1193 } while (reader.NodeType != XmlNodeType.None
1194 && (reader.NodeType != XmlNodeType.Element
1195 || Nexpr != reader.Name));
1196 if (reader.NodeType == XmlNodeType.None)
1197 throw new Exception ("Node <expr> not found");
1198 node = doc.ReadNode (reader);
1201 return New (node, domain);
1204 public static Xex New (XmlNode node, Domain domain)
1206 Name name = node.Name;
1208 if (name == Nvariable)
1210 Variable vari = domain.GetVar ((Name) node.Attributes[0].Value);
1211 xex = new Xex.Varref (vari);
1213 else if (name == Ninteger)
1214 xex = new Xex.Const (parse_integer (node.InnerText));
1215 else if (name == Nstring)
1216 xex = new Xex.Const (node.InnerText);
1217 else if (name == Nsymbol)
1218 xex = new Xex.Const ((Name) node.InnerText);
1219 else if (name == Nboolean)
1220 xex = new Xex.Const (node.InnerText == "true");
1221 else if (name == Nlist)
1223 List<Xex> list = new List<Xex> ();
1224 for (XmlNode n = node.FirstChild; n != null; n = n.NextSibling)
1225 list.Add (New (n, domain));
1226 xex = new Xex.Const (list);
1230 if (name == Nfuncall)
1231 name = node.Attributes[0].Value;
1232 Function func = domain.GetFunc (name);
1234 XmlNodeList nlist = node.ChildNodes;
1235 int nargs = nlist.Count;
1237 if (nargs < func.min_arg
1238 || (func.max_arg >= 0 && nargs > func.max_arg))
1239 throw new Exception ("Invalid number of arguments to: "
1240 + name + " " + nargs);
1241 nargs = pre_parse (nlist, domain);
1242 Xex[] args = new Xex[nargs];
1243 post_parse (nlist, args, domain);
1244 xex = new Xex.Funcall (func, args);