2 using System.Collections;
3 using System.Collections.Generic;
7 namespace System.Xml.Expression
9 public abstract class Xex
11 public struct Name : IEquatable<Name>
13 private static NameTable nt = new NameTable ();
17 public Name (string str)
22 public static implicit operator Name (string str)
24 return new Name (str);
27 public static implicit operator string (Name name)
32 public static bool operator== (Name n1, Name n2)
34 return (object) n1.name == (object) n2.name;
37 public static bool operator!= (Name n1, Name n2)
39 return (object) n1.name != (object) n2.name;
42 public static bool operator== (Name n1, string n2)
44 return (object) n1.name == (object) n2;
47 public static bool operator!= (Name n1, string n2)
49 return (object) n1.name != (object) n2;
52 public static bool operator== (string n1, Name n2)
54 return (object) n1 == (object) n2.name;
57 public static bool operator!= (string n1, Name n2)
59 return (object) n1 != (object) n2.name;
62 public bool Equals (Name name)
64 return Object.ReferenceEquals (this.name, name.name);
67 public override bool Equals (object obj)
69 return Object.ReferenceEquals (this.name, obj);
72 public override int GetHashCode ()
74 return name.GetHashCode ();
77 public static NameTable Table { get { return nt; } }
79 public override string ToString () { return name; }
82 private static Name Nexpr = "expr";
84 private static Name Nfuncall = "funcall";
85 private static Name Nvariable = "variable";
86 private static Name Ninteger = "integer";
87 private static Name Nstring = "string";
88 private static Name Nboolean = "boolean";
89 private static Name Nsymbol = "symbol";
90 private static Name Nlist = "list";
91 private static Name Nobject = "object";
93 private static Name Ndefun = "defun";
94 private static Name Nfname = "fname";
95 private static Name Nargs = "args";
96 private static Name Noptional = "optional";
97 private static Name Nrest = "rest";
98 private static Name Nbody = "body";
100 private static Name Ndefvar = "defvar";
101 private static Name Ndescription = "description";
102 private static Name Nrange = "range";
104 private static Name Nprogn = "progn";
106 internal abstract class Function
108 public readonly Name name;
109 public int min_arg, max_arg;
111 public Function (Name name, int min_arg, int max_arg)
114 this.min_arg = min_arg;
115 this.max_arg = max_arg;
118 public abstract object Call (Xex[] args, Domain domain);
120 public override string ToString ()
125 internal class Subroutine : Function
127 public Builtin builtin;
129 public Subroutine (Builtin builtin, Name name,
130 int min_arg, int max_arg)
131 : base (name, min_arg, max_arg)
133 this.builtin = builtin;
136 public override object Call (Xex[] args, Domain domain)
140 foreach (Xex a in args)
141 if (a.Eval (domain) == null)
142 throw new Exception (a + ":evaled to null");
143 Console.Write ("calling (" + this);
144 foreach (Xex a in args)
145 Console.Write (" " + a);
146 Console.Write (") => ");
147 result = builtin (args, domain);
148 Console.WriteLine (result);
153 internal class SpecialForm : Function
155 public Builtin builtin;
157 public SpecialForm (Builtin builtin, Name name,
158 int min_arg, int max_arg)
159 : base (name, min_arg, max_arg)
161 this.builtin = builtin;
164 public override object Call (Xex[] args, Domain domain)
168 Console.Write ("calling (" + this);
169 foreach (Xex a in args)
170 Console.Write (" " + a);
171 Console.Write (") => ");
172 result = builtin (args, domain);
173 Console.WriteLine (result);
178 internal class Lambda : Function
180 internal bool args_evaled = true;
181 internal Name[] args;
184 public Lambda (XmlNode node)
186 Name name = node.Attributes[Nfname].Value;
187 int nargs = 0, noptions = 0, nrest = 0;
190 node = node.FirstChild;
191 if (node != null && node.Name == Nargs)
193 for (XmlNode n = node.FirstChild; n != null; n = n.NextSibling)
195 if (n.Name == Noptional || n.Name == Nrest)
199 if (n != null && n.Name == Noptional)
200 for (n = n.NextSibling; n != null; n = n.NextSibling)
206 if (n != null && n.Name == Nrest)
207 for (n = n.NextSibling; n != null; n = n.NextSibling)
210 max_arg = nargs + noptions + nrest;
215 args = new Xex[nargs];
216 node = node.FirstChild;
217 for (int i = 0; i < nargs; node = node.NextSibling)
218 if (node.Name != Noptional && node.Name != Nrest)
219 args[i++] = New (node, domain);
222 public void SetBody (XmlNode node, Domain domain)
224 XmlNodeList nlist = node.ChildNodes;
226 body = new Xex[nlist.Count];
227 for (int i = 0; i < nlist.Count; i++)
228 body[i] = New (nlist[i], domain);
231 public void Setup (XmlNode node, Domain domain)
233 node = node.FirstChild;
234 if (node.Name == Nargs)
236 SetArgs (node, max_arg, domain);
237 node = node.NextSibling;
239 if (node.Name == Nbody)
240 SetBody (node, domain);
243 public override object Call (Xex[] args, Domain domain)
245 Bindings current = domain.bindings;
246 object result = false;
250 for (i = 0; i < min_arg; i++)
252 Xex a = this.args[i];
253 bool isdirect = a is Xex.Const;
254 Name name = (isdirect
255 ? (Name) a.val : ((Xex.Varref) a).vari.name);
256 Variable var = domain.GetVar (name);
259 domain.Bind (var, args[i]);
261 domain.Bind (var, args[i].Eval (domain));
263 Console.Write ("calling (" + this);
264 foreach (Xex e in body)
265 result = e.Eval (domain);
266 Console.WriteLine (result);
268 domain.UnboundTo (current);
273 public override string ToString ()
275 string str = "(" + name;
276 foreach (Xex a in args)
283 internal abstract class Variable
285 public readonly Name name;
286 public readonly Name type;
289 public Variable (Name name, Name type, object value)
302 if (! ValueP (value))
303 throw new Exception ("Invalid value type: " + value);
308 public abstract bool ValueP (object value);
310 public override string ToString () { return name + "=" + val; }
313 internal class VarInt : Variable
320 public Range[] ranges;
322 public VarInt (Name name, object value) : base (name, Ninteger, value) { }
324 public override bool ValueP (object value)
328 if (! (value is int))
333 foreach (Range r in ranges)
334 if (i >= r.from && i <= r.to)
340 internal class VarStr : Variable
342 public string[] ranges;
344 public VarStr (Name name, object value) : base (name, Nstring, value) { }
346 public override bool ValueP (object value)
350 if (! (value is string))
354 str = (string) value;
355 foreach (string s in ranges)
362 internal class VarBool : Variable
364 public VarBool (Name name, object value)
365 : base (name, Nboolean, value) { }
367 public override bool ValueP (object value)
369 if (! (value is bool))
375 internal class VarMisc : Variable
377 public VarMisc (Name name, object value) : base (name, Nobject, value) { }
379 public override bool ValueP (object value)
385 internal class Bindings
387 private Variable vari;
388 private object old_value;
389 private Bindings next;
391 private Bindings (Variable vari, object value)
397 public static Bindings Bind (Bindings bindings,
398 Variable vari, object value)
400 Bindings b = new Bindings (vari, vari.val);
402 b.vari.Value = value;
407 internal Bindings UnboundTo (Bindings boundary)
409 for (Bindings b = this; b != boundary; b = b.next)
410 vari.val = b.old_value;
414 public override string ToString ()
416 string str = "(bindings";
417 for (Bindings b = this; b != null; b = b.next)
424 internal class ThrowException : Exception
429 public ThrowException (Name tag, object value) : base ()
439 public object context;
441 internal Dictionary<Name, Function> functions;
442 internal Dictionary<Name, Variable> variables;
443 internal Bindings bindings;
447 functions = new Dictionary<Name, Function> ();
448 variables = new Dictionary<Name, Variable> ();
451 public Domain (object context) : this (basic, context)
455 public Domain (Domain parent, object context)
457 functions = new Dictionary<Name, Function> (parent.functions);
458 variables = new Dictionary<Name, Variable> (parent.variables);
459 this.context = context;
462 internal void Bind (Variable vari, object value)
464 bindings = Bindings.Bind (bindings, vari, value);
465 Console.WriteLine ("binding " + vari);
468 internal void UnboundTo (Bindings boundary)
470 if (bindings != null)
471 bindings = bindings.UnboundTo (boundary);
474 public void DefSubr (Builtin builtin, string str,
475 int min_arg, int max_arg)
479 = new Function.Subroutine (builtin, name, min_arg, max_arg);
482 public void DefSpecial (Builtin builtin, string str,
483 int min_arg, int max_arg)
487 = new Function.SpecialForm (builtin, name, min_arg, max_arg);
490 private static Name ParseHead (XmlNode node, out bool evaled,
491 out int min_arg, out int max_arg)
493 Name name = node.Attributes[Nfname].Value;
494 int nargs = 0, noptions = 0, nrest = 0;
497 for (n = node.FirstChild; n != null; n = n.NextSibling)
499 if (n.Name == Noptional || n.Name == Nrest)
503 if (n != null && n.Name == Noptional)
504 for (n = n.NextSibling; n != null; n = n.NextSibling)
510 if (n != null && n.Name == Nrest)
511 for (n = n.NextSibling; n != null; n = n.NextSibling)
514 max_arg = nargs + noptions + nrest;
520 internal Function.Lambda RegisterFunction (XmlNode node)
523 int min_arg, max_arg;
524 Name name = ParseHead (node, out evaled, out min_arg, out max_arg);
525 Function.Lambda lambda = new Function.Lambda (name, min_arg, max_arg);
527 functions[name] = lambda;
531 internal Function Defun (XmlNode node)
533 Name name = node.Attributes[Nfname].Value;
536 if (! functions.TryGetValue (name, out func))
537 func = RegisterFunction (node);
538 ((Function.Lambda) func).Setup (node, this);
542 public void Defvar (Name name, XmlNode node)
546 if (node.Name == Ndescription)
547 node = node.NextSibling;
550 Name type = node.Name;
551 XmlNodeList range_list = null;
554 node = node.NextSibling;
557 range_list = node.ChildNodes;
558 nranges = range_list.Count;
561 if (type == Ninteger)
563 VarInt vi = new VarInt (name, parse_integer (val));
564 if (range_list != null)
566 vi.ranges = new VarInt.Range[nranges];
568 for (int i = 0; i < nranges; i++)
570 XmlNode n = range_list[i];
572 if (n.Name == Nrange)
575 parse_integer (n.FirstChild.Value);
577 parse_integer (n.LastChild.Value);
581 int num = parse_integer (n.Value);
582 vi.ranges[i].from = vi.ranges[i].to = num;
588 else if (type == Nstring)
590 VarStr vs = new VarStr (name, val);
591 if (range_list != null)
592 vs.ranges = new string[nranges];
593 for (int i = 0; i < nranges; i++)
594 vs.ranges[i] = range_list[i].Value;
597 else if (type == Nboolean)
599 vari = new VarBool (name, val == "true");
602 throw new Exception ("Unknown type: " + type);
605 vari = new VarMisc (name, null);
606 variables[name] = vari;
609 internal Function GetFunc (Name name)
613 if (! functions.TryGetValue (name, out func))
614 throw new Exception ("Unknown function: " + name);
618 public bool CopyFunc (Domain domain, Name name)
620 Function func = GetFunc (name);
622 domain.functions[name] = func;
626 public void CopyFunc (Domain domain)
628 foreach (KeyValuePair<Name, Function> kv in functions)
629 domain.functions[kv.Key] = kv.Value;
632 internal Variable GetVar (Name name)
636 if (! variables.TryGetValue (name, out vari))
637 variables[name] = vari = new VarMisc (name, null);
641 internal Variable GetVar (Xex e)
643 if (! (e.val is Name))
644 throw new Exception ("Not a symbol" + e.val);
645 return GetVar ((Name) e.val);
648 public override string ToString ()
650 string str = "<(functions";
651 foreach (KeyValuePair<Name, Function> kv in functions)
653 str += ") (variabls";
654 foreach (KeyValuePair<Name, Variable> kv in variables)
657 if (bindings != null)
658 str += " " + bindings;
660 str += " (" + context + ")";
666 public delegate object Builtin (Xex[] args, Domain domain);
668 private static Domain basic = new Domain ();
670 internal static Function Fprogn;
674 basic.DefSubr (set_value, "set", 2, 2);
675 basic.DefSubr (set_value, "=", 2, 2);
676 basic.DefSubr (and, "and", 1, -1);
677 basic.DefSubr (and, "&&", 1, -1);
678 basic.DefSubr (or, "or", 1, -1);
679 basic.DefSubr (or, "||", 1, -1);
680 basic.DefSubr (not, "not", 1, 1);
681 basic.DefSubr (not, "!", 1, 1);
682 basic.DefSubr (add, "add", 2, -1);
683 basic.DefSubr (add, "+", 2, -1);
684 basic.DefSubr (mul, "mul", 2, -1);
685 basic.DefSubr (mul, "*", 2, -1);
686 basic.DefSubr (sub, "sub", 1, -1);
687 basic.DefSubr (sub, "-", 1, -1);
688 basic.DefSubr (div, "div", 2, -1);
689 basic.DefSubr (div, "/", 2, -1);
690 basic.DefSubr (mod, "mod", 2, 2);
691 basic.DefSubr (mod, "%", 2, 2);
692 basic.DefSubr (logior, "logior", 2, -1);
693 basic.DefSubr (logior, "|", 2, -1);
694 basic.DefSubr (logand, "logand", 2, -1);
695 basic.DefSubr (logand, "&", 2, -1);
696 basic.DefSubr (add_set, "add-set", 2, -1);
697 basic.DefSubr (add_set, "+=", 2, -1);
698 basic.DefSubr (mul_set, "mul-set", 2, -1);
699 basic.DefSubr (mul_set, "*=", 2, -1);
700 basic.DefSubr (sub_set, "sub-set", 2, -1);
701 basic.DefSubr (sub_set, "-=", 2, -1);
702 basic.DefSubr (div_set, "div-set", 2, -1);
703 basic.DefSubr (div_set, "/=", 2, -1);
704 basic.DefSubr (mod_set, "mod-set", 2, 2);
705 basic.DefSubr (mod_set, "%=", 2, 2);
706 basic.DefSubr (logior_set, "logior-set", 2, -1);
707 basic.DefSubr (logior_set, "|=", 2, -1);
708 basic.DefSubr (logand_set, "logand-set", 2, -1);
709 basic.DefSubr (logand_set, "&=", 2, -1);
710 basic.DefSubr (lsh, "lsh", 2, 2);
711 basic.DefSubr (lsh, "<<", 2, 2);
712 basic.DefSubr (rsh, "rsh", 2, 2);
713 basic.DefSubr (rsh, ">>", 2, 2);
714 basic.DefSubr (lsh_set, "lsh-set", 2, 2);
715 basic.DefSubr (lsh_set, "<<=", 2, 2);
716 basic.DefSubr (rsh_set, "rsh-set", 2, 2);
717 basic.DefSubr (rsh_set, ">>=", 2, 2);
718 basic.DefSubr (eq, "eq", 2, -1);
719 basic.DefSubr (eq, "==", 2, -1);
720 basic.DefSubr (noteq, "noteq", 2, 2);
721 basic.DefSubr (noteq, "!=", 2, 2);
722 basic.DefSubr (less_than, "lt", 2, -1);
723 basic.DefSubr (less_than, "<", 2, -1);
724 basic.DefSubr (less_eq, "le", 2, -1);
725 basic.DefSubr (less_eq, "<=", 2, -1);
726 basic.DefSubr (greater_than, "gt", 2, -1);
727 basic.DefSubr (greater_than, ">", 2, -1);
728 basic.DefSubr (greater_eq, "ge", 2, -1);
729 basic.DefSubr (greater_eq, ">=", 2, -1);
730 basic.DefSubr (eval_clause, "eval", 1, 1);
731 basic.DefSpecial (progn_clause, "progn", 0, -1);
732 basic.DefSpecial (progn_clause, "expr", 0, -1);
733 basic.DefSpecial (if_clause, "if", 2, -1);
734 basic.DefSpecial (when_clause, "when", 1, -1);
735 basic.DefSpecial (while_clause, "while", 1, -1);
737 Fprogn = basic.GetFunc (Nprogn);
740 private static bool is_true (object val)
742 return (val is bool ? (bool) val
743 : val is int ? (int) val == 0
747 private static object set_value (Xex[] args, Domain domain)
749 Variable vari = domain.GetVar (args[0]);
751 vari.Value = args[1].val;
755 private static object and (Xex[] args, Domain domain)
757 foreach (Xex arg in args)
758 if (! is_true (arg.val))
763 private static object or (Xex[] args, Domain domain)
765 foreach (Xex arg in args)
766 if (is_true (arg.val))
771 private static object not (Xex[] args, Domain domain)
773 return ! is_true (args[0].val);
776 private static object add (Xex[] args, Domain domain)
779 foreach (Xex e in args)
784 private static object mul (Xex[] args, Domain domain)
787 foreach (Xex e in args)
792 private static object sub (Xex[] args, Domain domain)
794 int n = (int) args[0].val;
795 if (args.Length == 1)
797 for (int i = 1; i < args.Length; i++)
798 n -= (int) args[i].val;
802 private static object div (Xex[] args, Domain domain)
804 int n = (int) args[0].val;
805 for (int i = 1; i < args.Length; i++)
806 n /= (int) args[i].val;
810 private static object mod (Xex[] args, Domain domain)
812 return ((int) args[0].val % (int) args[1].val);
815 private static object logior (Xex[] args, Domain domain)
818 foreach (Xex e in args)
823 private static object logand (Xex[] args, Domain domain)
825 int n = (int) args[0].val;
826 for (int i = 1; i < args.Length; i++)
827 n &= (int) args[i].val;
831 private static object add_set (Xex[] args, Domain domain)
833 Variable vari = domain.GetVar (args[0]);
834 int n = (int) vari.val;
836 for (int i = 1; i < args.Length; i++)
837 n += (int) args[i].val;
842 private static object mul_set (Xex[] args, Domain domain)
844 Variable vari = domain.GetVar (args[0]);
845 int n = (int) vari.val;
847 for (int i = 1; i < args.Length; i++)
848 n *= (int) args[i].val;
853 private static object sub_set (Xex[] args, Domain domain)
855 Variable vari = domain.GetVar (args[0]);
856 int n = (int) vari.val;
858 for (int i = 1; i < args.Length; i++)
859 n -= (int) args[i].val;
864 private static object div_set (Xex[] args, Domain domain)
866 Variable vari = domain.GetVar (args[0]);
867 int n = (int) vari.val;
869 for (int i = 1; i < args.Length; i++)
870 n /= (int) args[i].val;
875 private static object mod_set (Xex[] args, Domain domain)
877 Variable vari = domain.GetVar (args[0]);
878 int n = (int) vari.val;
880 for (int i = 1; i < args.Length; i++)
881 n %= (int) args[i].val;
886 private static object logior_set (Xex[] args, Domain domain)
888 Variable vari = domain.GetVar (args[0]);
889 int n = (int) vari.val;
891 for (int i = 1; i < args.Length; i++)
892 n |= (int) args[i].val;
897 private static object logand_set (Xex[] args, Domain domain)
899 Variable vari = domain.GetVar (args[0]);
900 int n = (int) vari.val;
902 for (int i = 1; i < args.Length; i++)
903 n &= (int) args[i].val;
908 private static object lsh (Xex[] args, Domain domain)
910 return (int) args[0].val << (int) args[1].val;
913 private static object lsh_set (Xex[] args, Domain domain)
915 Variable vari = domain.GetVar (args[0]);
916 int n = (int) vari.val;
918 n <<= (int) args[1].val;
923 private static object rsh (Xex[] args, Domain domain)
925 return (int) args[0].val >> (int) args[1].val;
928 private static object rsh_set (Xex[] args, Domain domain)
930 Variable vari = domain.GetVar (args[0]);
931 int n = (int) vari.val;
933 n >>= (int) args[1].val;
938 private static object eq (Xex[] args, Domain domain)
940 int n = (int) args[0].val;
942 for (int i = 1; i < args.Length; i++)
943 if (n != (int) args[i].val)
948 private static object noteq (Xex[] args, Domain domain)
950 return ((int) args[0].val != (int) args[1].val);
953 private static object less_than (Xex[] args, Domain domain)
955 int n = (int) args[0].val;
957 for (int i = 1; i < args.Length; i++)
959 int n1 = (int) args[i].val;
967 private static object less_eq (Xex[] args, Domain domain)
969 int n = (int) args[0].val;
970 for (int i = 1; i < args.Length; i++)
972 int n1 = (int) args[i].val;
980 private static object greater_than (Xex[] args, Domain domain)
982 int n = (int) args[0].val;
983 for (int i = 1; i < args.Length; i++)
985 int n1 = (int) args[i].val;
993 private static object greater_eq (Xex[] args, Domain domain)
995 int n = (int) args[0].val;
996 for (int i = 1; i < args.Length; i++)
998 int n1 = (int) args[i].val;
1006 private static object eval_clause (Xex[] args, Domain domain)
1008 return ((Xex) args[0].val).Eval (domain);
1011 private static object progn_clause (Xex[] args, Domain domain)
1013 object result = true;
1015 foreach (Xex e in args)
1016 result = e.Eval (domain);
1020 private static object if_clause (Xex[] args, Domain domain)
1024 if (is_true (args[0].Eval (domain)))
1025 result = args[1].Eval (domain);
1029 for (int i = 2; i < args.Length; i++)
1030 result = args[i].Eval (domain);
1035 private static object when_clause (Xex[] args, Domain domain)
1037 if (! is_true (args[0].Eval (domain)))
1040 object result = true;
1041 for (int i = 1; i < args.Length; i++)
1042 result = args[i].Eval (domain);
1046 private static object while_clause (Xex[] args, Domain domain)
1048 while (is_true (args[0].Eval (domain)))
1049 for (int i = 1; i < args.Length; i++)
1050 args[i].Eval (domain);
1054 // FUNCALL: function != null
1055 // VARREF: function == null, args[0] = DIRECT-SYMBOL
1056 // DIRECT: function == null, args == null
1059 public abstract object Eval (Domain domain);
1060 public object Val { get { return val; } }
1062 private class Funcall : Xex
1064 internal Function func;
1065 internal Xex[] args;
1067 public Funcall (Function func, Xex[] args)
1073 public override object Eval (Domain domain)
1075 val = func.Call (args, domain);
1079 public override string ToString ()
1081 string str = "(" + func.name;
1083 foreach (Xex e in args)
1084 str += " " + e.ToString ();
1089 private class Varref : Xex
1091 internal Variable vari;
1093 public Varref (Variable vari)
1098 public override object Eval (Domain domain)
1104 public override string ToString ()
1106 return "$" + vari.name + "/" + vari.val;
1110 private class Const : Xex
1112 public Const (object val)
1117 public override object Eval (Domain domain)
1122 public override string ToString ()
1124 return val.ToString ();
1128 internal static int parse_integer (string str)
1130 int len = str.Length;
1131 bool negative = false;
1134 return (len == 0 ? 0 : str[0] - '0');
1139 if (c == '0' && str[1] == 'x')
1142 for (int idx = 2; idx < len; idx++)
1148 i = i * 16 + (c - '0');
1152 i = i * 16 + (c - 'A');
1156 i = i * 16 + (c - 'a');
1165 for (int idx = 1; idx < len; idx++)
1168 if (c < '0' || c > '9')
1170 i = i * 10 + (c - '0');
1172 return negative ? - i : i;
1175 private static int pre_parse (XmlNodeList nlist, Domain domain)
1178 foreach (XmlNode node in nlist)
1180 if (node.Name == Ndefun)
1181 domain.RegisterFunction (node);
1182 else if (node.Name == Ndefvar)
1183 domain.Defvar ((Name) node.Attributes[0].Value, node.FirstChild);
1190 private static void post_parse (XmlNodeList nlist, Xex[] args,
1193 for (int i = 0, j = 0; i < nlist.Count; i++)
1195 XmlNode node = nlist[i];
1197 if (node.Name == Ndefun)
1198 domain.Defun (node);
1199 else if (node.Name != Ndefvar)
1200 args[j++] = New (node, domain);
1204 public static Xex New (string url, Domain domain)
1206 XmlDocument doc = new XmlDocument (Name.Table);
1209 using (XmlTextReader reader = new XmlTextReader (url, Name.Table))
1213 } while (reader.NodeType != XmlNodeType.None
1214 && (reader.NodeType != XmlNodeType.Element
1215 || Nexpr != reader.Name));
1216 if (reader.NodeType == XmlNodeType.None)
1217 throw new Exception ("Node <expr> not found");
1218 node = doc.ReadNode (reader);
1221 return New (node, domain);
1224 // EXPR = SYMBOL | MTEXT | INTEGER | FUNCALL | PROGN
1225 // FUNCALL = '(' SYMBOL EXPR* ')'
1226 // PROGN = '(' EXPR * ')'
1227 public static Xex New (XmlNode node, Domain domain)
1229 Name name = node.Name;
1231 if (name == Nvariable)
1233 Variable vari = domain.GetVar ((Name) node.Attributes[0].Value);
1234 xex = new Xex.Varref (vari);
1236 else if (name == Ninteger)
1237 xex = new Xex.Const (parse_integer (node.InnerText));
1238 else if (name == Nstring)
1239 xex = new Xex.Const (node.InnerText);
1240 else if (name == Nsymbol)
1241 xex = new Xex.Const ((Name) node.InnerText);
1242 else if (name == Nboolean)
1243 xex = new Xex.Const (node.InnerText == "true");
1244 else if (name == Nlist)
1246 List<Xex> list = new List<Xex> ();
1247 for (XmlNode n = node.FirstChild; n != null; n = n.NextSibling)
1248 list.Add (New (n, domain));
1249 xex = new Xex.Const (list);
1253 if (name == Nfuncall)
1254 name = node.Attributes[0].Value;
1255 Function func = domain.GetFunc (name);
1257 XmlNodeList nlist = node.ChildNodes;
1258 int nargs = nlist.Count;
1260 if (nargs < func.min_arg
1261 || (func.max_arg >= 0 && nargs > func.max_arg))
1262 throw new Exception ("Invalid number of arguments to: "
1263 + name + " " + nargs);
1264 nargs = pre_parse (nlist, domain);
1265 Xex[] args = new Xex[nargs];
1266 post_parse (nlist, args, domain);
1267 xex = new Xex.Funcall (func, args);