2 using System.Collections;
3 using System.Collections.Generic;
7 namespace System.Xml.Expression
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 bool Equals (Name name)
54 return Object.ReferenceEquals (this.name, name.name);
57 public override bool Equals (object obj)
59 return Object.ReferenceEquals (this.name, obj);
62 public override int GetHashCode ()
64 return name.GetHashCode ();
67 public static NameTable Table { get { return nt; } }
69 public override string ToString () { return name; }
72 private static Name Nexpr = "expr";
73 private static Name Ntype = "type";
74 private static Name Nargs = "args";
76 private static Name Ninteger = "integer";
77 private static Name Nstring = "string";
78 private static Name Nboolean = "boolean";
79 private static Name Nsymbol = "symbol";
80 private static Name Nlist = "list";
81 private static Name Nobject = "object";
83 private static Name Ndefun = "defun";
84 private static Name Ndefmacro = "defmacro";
85 private static Name Ndefvar = "defvar";
86 private static Name Nconst = "const";
87 private static Name Nvariable = "variable";
88 private static Name Ndescription = "description";
89 private static Name Npossible_value = "possible-value";
91 private static Name Nfuncall = "funcall";
92 private static Name Nmname = "mname";
93 private static Name Nprogn = "progn";
95 internal class Function
99 internal Variable[] args;
102 public Lambda (XmlNode node, Domain domain)
107 public void Set (XmlNode node, Domain domain)
109 XmlNodeList body = node.ChildNodes;
112 if (Nargs == body[0].Name)
114 XmlNodeList args = body[0].ChildNodes;
115 if (this.args == null)
116 this.args = new Name[args.Count];
117 for (int i = 0; i < args.Count; i++)
118 this.args[i] = args[i].InnerText;
121 else if (this.args == null)
122 this.args = new Name[0];
123 if (this.body == null)
124 this.body = new Xex[body.Count - idx];
125 for (int i = 0; idx < body.Count; i++, idx++)
126 this.body[i] = new Xex (body[idx], domain);
130 public readonly Name name;
131 public Builtin builtin;
132 public int min_arg, max_arg;
133 internal Lambda lambda;
134 public bool specialp = false;
136 public Function (Name name, Builtin builtin,
137 int min_arg, int max_arg, bool specialp)
140 this.builtin = builtin;
141 this.min_arg = min_arg;
142 this.max_arg = max_arg;
143 this.specialp = specialp;
146 internal Function (Name name, XmlNode node, Domain domain)
149 lambda = new Lambda (node, domain);
150 this.min_arg = this.max_arg = lambda.args.Length;
153 internal Function (Name name, int nargs, bool specialp)
156 this.min_arg = this.max_arg = nargs;
159 public object Call (Xex[] args, Domain domain)
161 Bindings current = domain.bindings;
162 object result = false;
164 Console.Write ("calling (" + this + "(");
167 foreach (Xex e in args)
169 Console.WriteLine (")");
171 return builtin (args, domain);
174 for (int i = 0; i < args.Length; i++)
175 domain.Bind (bindings, lambda.args[i], args[i].val);
176 foreach (Xex e in lambda.body)
178 result = e.Eval (domain);
179 Console.WriteLine (e.ToString () + "=>" + result);
182 Console.WriteLine (")");
183 domain.UnboundTo (current);
188 public override string ToString ()
194 internal abstract class Variable
196 public readonly Name name;
197 public readonly Name type;
200 public Variable (Name name, Name type, object value)
212 if (! ValueP (value))
213 throw new Exception ("Invalid value type: " + value);
218 public abstract bool ValueP (object value);
220 public override string ToString () { return name + "(" + type + ")"; }
223 internal class VarInt : Variable
230 public Range[] ranges;
232 public VarInt (Name name, int value) : base (name, Ninteger, value) { }
234 public override bool ValueP (object value)
238 if (! (value is int))
243 foreach (Range r in ranges)
244 if (i >= r.from && i <= r.to)
250 internal class VarStr : Variable
252 public string[] ranges;
254 public VarStr (Name name, string value) : base (name, Nstring, value) { }
256 public override bool ValueP (object value)
260 if (! (value is string))
264 str = (string) value;
265 foreach (string s in ranges)
272 internal class VarBool : Variable
274 public VarBool (Name name, bool value) : base (name, Nboolean, value) { }
276 public override bool ValueP (object value)
278 return value is bool;
282 internal class VarMisc : Variable
284 public VarMisc (Name name, object value) : base (name, Nobject, value) { }
286 public override bool ValueP (object value)
292 internal class Bindings
294 private Variable vari;
295 private object old_value;
296 private Bindings next;
298 private Bindings (Variable vari, object value)
304 public static Bindings Bind (Bindings bindings,
305 Variable vari, object value)
307 Bindings b = new Bindings (vari, vari.val);
309 b.vari.Value = value;
314 internal Bindings UnboundTo (Bindings boundary)
316 for (Bindings b = this; b != boundary; b = b.next)
317 vari.val = b.old_value;
321 public override string ToString ()
323 string str = "(bindings";
324 for (Bindings b = this; b != null; b = b.next)
331 internal class ThrowException : Exception
336 public ThrowException (Name tag, object value) : base ()
346 private Domain parent;
347 public object context;
349 internal Dictionary<Name, Function> functions
350 = new Dictionary<Name, Function> ();
351 internal Dictionary<Name, Variable> variables
352 = new Dictionary<Name, Variable> ();
353 internal Bindings bindings;
355 internal Domain () { }
357 public Domain (object context) : this (basic, context)
361 public Domain (Domain parent, object context)
363 this.parent = parent;
364 this.context = context;
367 internal void Bind (Variable vari, object value)
369 bindings = Bindings.Bind (bindings, vari, value);
372 internal void UnboundTo (Bindings boundary)
374 if (boundary != null)
375 bindings = bindings.UnboundTo (boundary);
378 public void Defun (Name name, Builtin builtin, int min_arg, int max_arg)
380 Defun (name, builtin, min_arg, max_arg, false);
383 public void Defun (Name name, Builtin builtin, int min_arg, int max_arg,
388 if (functions.TryGetValue (name, out func))
390 if (func.min_arg < min_arg || func.max_arg > max_arg)
391 throw new Exception ("Incompatible argument numbers to override: "
393 func.builtin = builtin;
395 func.min_arg = min_arg;
396 func.max_arg = max_arg;
397 func.specialp = specialp;
402 = new Function (name, builtin, min_arg, max_arg, specialp);
406 public void Defun (XmlNode node)
408 Name name = node.Attributes[0].Value;
411 if (functions.TryGetValue (name, out func))
413 XmlNode args = node.FirstChild;
414 int nargs = args.Name == Nargs ? args.ChildNodes.Count : 0;
416 if (func.min_arg < nargs || func.max_arg > nargs)
417 throw new Exception ("Incompatible argument numbers to override: "
419 if (func.lambda == null)
420 func.lambda = new Function.Lambda (node, this);
422 func.lambda.Set (node, this);
427 func = new Function (name, node, this);
428 functions[name] = func;
432 public void Defun (Name name, int nargs, bool specialp)
436 if (functions.TryGetValue (name, out func))
438 if (func.min_arg < nargs || func.max_arg > nargs)
439 throw new Exception ("Incompatible argument numbers to override: "
441 func.min_arg = func.max_arg = nargs;
442 func.specialp = specialp;
447 func = new Function (name, nargs, specialp);
448 functions[name] = func;
452 public void Defvar (Name name, XmlNode node)
456 if (node.Name == Ndescription)
457 node = node.NextSibling;
458 if (node.Name == Nconst)
460 Name type = (Name) node.Attributes[Ntype].Value;
461 string val = node.Value;
462 XmlNodeList range_list = null;
465 node = node.NextSibling;
466 if (node.Name == Npossible_value)
468 range_list = node.ChildNodes;
469 nranges = range_list.Count;
472 if (type == Ninteger)
474 VarInt vi = new VarInt (name, parse_integer (val));
475 if (range_list != null)
477 vi.ranges = new VarInt.Range[nranges];
479 for (int i = 0; i < nranges; i++)
481 XmlNode n = range_list[i];
483 if (n.Name == Nconst)
485 int num = parse_integer (n.Value);
486 vi.ranges[i].from = vi.ranges[i].to = num;
488 else // range_list[i].Name == "range"
491 parse_integer (n.FirstChild.Value);
493 parse_integer (n.LastChild.Value);
499 else if (type == Nstring)
501 VarStr vs = new VarStr (name, val);
502 if (range_list != null)
503 vs.ranges = new string[nranges];
504 for (int i = 0; i < nranges; i++)
505 vs.ranges[i] = range_list[i].Value;
508 else if (type == Nboolean)
510 vari = new VarBool (name, val == "true");
513 throw new Exception ("Unknown type: " + type);
516 vari = new VarMisc (name, null);
517 variables[name] = vari;
520 internal Function GetFunc (Name name)
524 if (! functions.TryGetValue (name, out func))
527 return parent.GetFunc (name);
528 throw new Exception ("Unknown function: " + name);
533 public bool CopyFunc (Domain domain, Name name)
535 Function func = GetFunc (name);
537 domain.functions[name] = func;
541 public void CopyFunc (Domain domain)
543 foreach (KeyValuePair<Name, Function> kv in functions)
544 domain.functions[kv.Key] = kv.Value;
547 internal Variable GetVar (Name name)
551 if (! variables.TryGetValue (name, out vari))
552 variables[name] = vari = new VarMisc (name, null);
556 internal Variable GetVar (Xex e)
558 if (! (e.val is Name))
559 throw new Exception ("Not a symbol" + e.val);
560 return GetVar ((Name) e.val);
563 public override string ToString ()
565 string str = "<(functions";
566 foreach (KeyValuePair<Name, Function> kv in functions)
568 str += ") (variabls";
569 foreach (KeyValuePair<Name, Variable> kv in variables)
572 if (bindings != null)
573 str += " " + bindings;
575 str += " (" + context + ")";
581 public delegate object Builtin (Xex[] args, Domain domain);
583 private static Domain basic = new Domain ();
585 internal static Function Fprogn;
589 basic.Defun ("set", set_value, 2, 2, false);
590 basic.Defun ("=", set_value, 2, 2, false);
591 basic.Defun ("and", and, 1, -1, false);
592 basic.Defun ("&&", and, 1, -1, false);
593 basic.Defun ("or", or, 1, -1, false);
594 basic.Defun ("||", or, 1, -1, false);
595 basic.Defun ("not", not, 1, 1, false);
596 basic.Defun ("!", not, 1, 1, false);
597 basic.Defun ("add", add, 2, -1, false);
598 basic.Defun ("+", add, 2, -1, false);
599 basic.Defun ("mul", mul, 2, -1, false);
600 basic.Defun ("*", mul, 2, -1, false);
601 basic.Defun ("sub", sub, 1, -1, false);
602 basic.Defun ("-", sub, 1, -1, false);
603 basic.Defun ("div", div, 2, -1, false);
604 basic.Defun ("/", div, 2, -1, false);
605 basic.Defun ("mod", mod, 2, 2, false);
606 basic.Defun ("%", mod, 2, 2, false);
607 basic.Defun ("logior", logior, 2, -1, false);
608 basic.Defun ("|", logior, 2, -1, false);
609 basic.Defun ("logand", logand, 2, -1, false);
610 basic.Defun ("&", logand, 2, -1, false);
611 basic.Defun ("add-set", add_set, 2, -1, true);
612 basic.Defun ("+=", add_set, 2, -1, true);
613 basic.Defun ("mul-set", mul_set, 2, -1, true);
614 basic.Defun ("*=", mul_set, 2, -1, true);
615 basic.Defun ("sub-set", sub_set, 2, -1, true);
616 basic.Defun ("-=", sub_set, 2, -1, true);
617 basic.Defun ("div-set", div_set, 2, -1, true);
618 basic.Defun ("/=", div_set, 2, -1, true);
619 basic.Defun ("mod-set", mod_set, 2, 2, true);
620 basic.Defun ("%=", mod_set, 2, 2, true);
621 basic.Defun ("logior-set", logior_set, 2, -1, true);
622 basic.Defun ("|=", logior_set, 2, -1, true);
623 basic.Defun ("logand-set", logand_set, 2, -1, true);
624 basic.Defun ("&=", logand_set, 2, -1, true);
625 basic.Defun ("lsh", lsh, 2, 2, false);
626 basic.Defun ("<<", lsh, 2, 2, false);
627 basic.Defun ("rsh", rsh, 2, 2, false);
628 basic.Defun (">>", rsh, 2, 2, false);
629 basic.Defun ("lsh-set", lsh_set, 2, 2, true);
630 basic.Defun ("<<=", lsh_set, 2, 2, true);
631 basic.Defun ("rsh-set", rsh_set, 2, 2, true);
632 basic.Defun (">>=", rsh_set, 2, 2, true);
633 basic.Defun ("eq", eq, 2, -1, false);
634 basic.Defun ("==", eq, 2, -1, false);
635 basic.Defun ("noteq", noteq, 2, 2, false);
636 basic.Defun ("!=", noteq, 2, 2, false);
637 basic.Defun ("lt", less_than, 2, -1, false);
638 basic.Defun ("<", less_than, 2, -1, false);
639 basic.Defun ("le", less_eq, 2, -1, false);
640 basic.Defun ("<=", less_eq, 2, -1, false);
641 basic.Defun ("gt", greater_than, 2, -1, false);
642 basic.Defun (">", greater_than, 2, -1, false);
643 basic.Defun ("ge", greater_eq, 2, -1, false);
644 basic.Defun (">=", greater_eq, 2, -1, false);
645 basic.Defun ("progn", progn_clause, 0, -1, true);
646 basic.Defun ("expr", progn_clause, 0, -1, true);
647 basic.Defun ("if", if_clause, 2, -1, true);
648 basic.Defun ("when", when_clause, 1, -1, true);
649 basic.Defun ("while", while_clause, 1, -1, true);
651 Fprogn = basic.GetFunc (Nprogn);
654 private static bool is_true (object val)
656 return (val is bool ? (bool) val
657 : val is int ? (int) val == 0
661 private static object set_value (Xex[] args, Domain domain)
663 Variable vari = domain.GetVar (args[0]);
665 vari.Value = args[1].val;
669 private static object and (Xex[] args, Domain domain)
671 foreach (Xex arg in args)
672 if (! is_true (arg.val))
677 private static object or (Xex[] args, Domain domain)
679 foreach (Xex arg in args)
680 if (is_true (arg.val))
685 private static object not (Xex[] args, Domain domain)
687 return ! is_true (args[0].val);
690 private static object add (Xex[] args, Domain domain)
693 foreach (Xex e in args)
698 private static object mul (Xex[] args, Domain domain)
701 foreach (Xex e in args)
706 private static object sub (Xex[] args, Domain domain)
708 int n = (int) args[0].val;
709 if (args.Length == 1)
711 for (int i = 1; i < args.Length; i++)
712 n -= (int) args[i].val;
716 private static object div (Xex[] args, Domain domain)
718 int n = (int) args[0].val;
719 for (int i = 1; i < args.Length; i++)
720 n /= (int) args[i].val;
724 private static object mod (Xex[] args, Domain domain)
726 return ((int) args[0].val % (int) args[1].val);
729 private static object logior (Xex[] args, Domain domain)
732 foreach (Xex e in args)
737 private static object logand (Xex[] args, Domain domain)
739 int n = (int) args[0].val;
740 for (int i = 1; i < args.Length; i++)
741 n &= (int) args[i].val;
745 private static object add_set (Xex[] args, Domain domain)
747 Variable vari = domain.GetVar (args[0]);
748 int n = (int) vari.val;
750 for (int i = 1; i < args.Length; i++)
751 n += (int) args[i].val;
756 private static object mul_set (Xex[] args, Domain domain)
758 Variable vari = domain.GetVar (args[0]);
759 int n = (int) vari.val;
761 for (int i = 1; i < args.Length; i++)
762 n *= (int) args[i].val;
767 private static object sub_set (Xex[] args, Domain domain)
769 Variable vari = domain.GetVar (args[0]);
770 int n = (int) vari.val;
772 for (int i = 1; i < args.Length; i++)
773 n -= (int) args[i].val;
778 private static object div_set (Xex[] args, Domain domain)
780 Variable vari = domain.GetVar (args[0]);
781 int n = (int) vari.val;
783 for (int i = 1; i < args.Length; i++)
784 n /= (int) args[i].val;
789 private static object mod_set (Xex[] args, Domain domain)
791 Variable vari = domain.GetVar (args[0]);
792 int n = (int) vari.val;
794 for (int i = 1; i < args.Length; i++)
795 n %= (int) args[i].val;
800 private static object logior_set (Xex[] args, Domain domain)
802 Variable vari = domain.GetVar (args[0]);
803 int n = (int) vari.val;
805 for (int i = 1; i < args.Length; i++)
806 n |= (int) args[i].val;
811 private static object logand_set (Xex[] args, Domain domain)
813 Variable vari = domain.GetVar (args[0]);
814 int n = (int) vari.val;
816 for (int i = 1; i < args.Length; i++)
817 n &= (int) args[i].val;
822 private static object lsh (Xex[] args, Domain domain)
824 return (int) args[0].val << (int) args[1].val;
827 private static object lsh_set (Xex[] args, Domain domain)
829 Variable vari = domain.GetVar (args[0]);
830 int n = (int) vari.val;
832 n <<= (int) args[1].val;
837 private static object rsh (Xex[] args, Domain domain)
839 return (int) args[0].val >> (int) args[1].val;
842 private static object rsh_set (Xex[] args, Domain domain)
844 Variable vari = domain.GetVar (args[0]);
845 int n = (int) vari.val;
847 n >>= (int) args[1].val;
852 private static object eq (Xex[] args, Domain domain)
854 int n = (int) args[0].val;
856 for (int i = 1; i < args.Length; i++)
857 if (n != (int) args[i].val)
862 private static object noteq (Xex[] args, Domain domain)
864 return ((int) args[0].val != (int) args[1].val);
867 private static object less_than (Xex[] args, Domain domain)
869 int n = (int) args[0].val;
871 for (int i = 1; i < args.Length; i++)
873 int n1 = (int) args[i].val;
881 private static object less_eq (Xex[] args, Domain domain)
883 int n = (int) args[0].val;
884 for (int i = 1; i < args.Length; i++)
886 int n1 = (int) args[i].val;
894 private static object greater_than (Xex[] args, Domain domain)
896 int n = (int) args[0].val;
897 for (int i = 1; i < args.Length; i++)
899 int n1 = (int) args[i].val;
907 private static object greater_eq (Xex[] args, Domain domain)
909 int n = (int) args[0].val;
910 for (int i = 1; i < args.Length; i++)
912 int n1 = (int) args[i].val;
920 private static object progn_clause (Xex[] args, Domain domain)
922 object result = true;
924 foreach (Xex e in args)
925 result = e.Eval (domain);
929 private static object if_clause (Xex[] args, Domain domain)
933 if (is_true (args[0].Eval (domain)))
934 result = args[1].Eval (domain);
938 for (int i = 2; i < args.Length; i++)
939 result = args[i].Eval (domain);
944 private static object when_clause (Xex[] args, Domain domain)
946 if (! is_true (args[0].Eval (domain)))
949 object result = true;
950 for (int i = 1; i < args.Length; i++)
951 result = args[i].Eval (domain);
955 private static object while_clause (Xex[] args, Domain domain)
957 while (is_true (args[0].Eval (domain)))
958 for (int i = 1; i < args.Length; i++)
959 args[i].Eval (domain);
963 // FUNCALL: function != null
964 // VARREF: function == null, args[0] = DIRECT-SYMBOL
965 // DIRECT: function == null, args == null
967 private Function function;
971 public Xex[] Args { get { return args; } }
972 public object Val { get { return val; } }
976 private Xex (object val)
981 private static Xex macro_expand (Xex[] bindings, Name[] args, Xex e)
985 if (e.function != null)
988 xex.function = e.function;
989 xex.args = new Xex[e.args.Length];
990 for (int i = e.args.Length - 1; i >= 0; i--)
991 xex.args[i] = macro_expand (bindings, args, e.args[i]);
993 else if (e.args != null)
996 Name name = (Name) e.args[0].val;
997 for (int i = args.Length - 1; i >= 0; i--)
1000 xex.function = null;
1001 xex.args = new Xex[1];
1002 xex.args[0] = e.args[0];
1011 internal static int parse_integer (string str)
1013 int len = str.Length;
1014 bool negative = false;
1017 return (len == 0 ? 0 : str[0] - '0');
1022 if (c == '0' && str[1] == 'x')
1025 for (int idx = 2; idx < len; idx++)
1031 i = i * 16 + (c - '0');
1035 i = i * 16 + (c - 'A');
1039 i = i * 16 + (c - 'a');
1048 for (int idx = 1; idx < len; idx++)
1051 if (c < '0' || c > '9')
1053 i = i * 10 + (c - '0');
1055 return negative ? - i : i;
1058 private int pre_parse (XmlNodeList nlist, Domain domain)
1061 foreach (XmlNode node in nlist)
1063 if (node.Name == Ndefun)
1065 XmlNode n = node.FirstChild;
1066 domain.Defun ((Name) node.Attributes[0].Value,
1067 n.Name == Nargs ? n.ChildNodes.Count : 0, false);
1069 else if (node.Name == Ndefmacro)
1071 XmlNode n = node.FirstChild;
1072 domain.Defun ((Name) node.Attributes[0].Value,
1073 n.Name == Nargs ? n.ChildNodes.Count : 0, true);
1075 else if (node.Name == Ndefvar)
1077 domain.Defvar ((Name) node.Attributes[0].Value, node.FirstChild);
1085 private void post_parse (XmlNodeList nlist, Domain domain)
1087 for (int i = 0, j = 0; i < nlist.Count; i++)
1089 XmlNode node = nlist[i];
1091 if (node.Name == Ndefun)
1092 domain.Defun (node);
1093 else if (node.Name == Ndefmacro)
1094 domain.Defun (node);
1095 else if (node.Name != Ndefvar)
1096 args[j++] = new Xex (node, domain);
1100 private void Setup (XmlNode node, Domain domain)
1102 Name name = node.Name;
1106 Name type = node.Attributes[Ntype].Value;
1108 if (type == Ninteger)
1109 val = parse_integer (node.InnerText);
1110 else if (type == Nstring)
1111 val = node.InnerText;
1112 else if (type == Nsymbol)
1113 val = (Name) node.InnerText;
1114 else if (type == Nboolean)
1115 val = node.InnerText == "true";
1116 else if (type == Nlist)
1118 List<Xex> list = new List<Xex> ();
1119 for (XmlNode n = node.FirstChild; n != null; n = n.NextSibling)
1120 list.Add (new Xex (n, domain));
1124 throw new Exception ("Unknown type: " + type);
1126 else if (name == Nvariable)
1129 args[0] = new Xex ((Name) node.Attributes[0].Value);
1133 bool is_macro = false;
1135 if (name == Nfuncall)
1137 name = node.Attributes[0].Value;
1138 if (Nmname == node.Attributes[0].Name)
1142 function = domain.GetFunc (name);
1144 XmlNodeList nlist = node.ChildNodes;
1145 int nargs = nlist.Count;
1147 if (nargs < function.min_arg
1148 || (function.max_arg >= 0 && nargs > function.max_arg))
1149 throw new Exception ("Invalid number of arguments to: "
1150 + name + " " + nargs);
1151 nargs = pre_parse (nlist, domain);
1152 args = new Xex[nargs];
1153 post_parse (nlist, domain);
1157 Function.Lambda lambda = function.lambda;
1158 Xex[] body = lambda.body;
1159 int len = body.Length;
1160 Xex[] newargs = new Xex[len];
1162 for (int i = 0; i < len; i++)
1163 newargs[i] = macro_expand (args, lambda.args, body[i]);
1170 public Xex (string url, Domain domain)
1172 XmlDocument doc = new XmlDocument (Name.Table);
1175 using (XmlTextReader reader = new XmlTextReader (url, Name.Table))
1179 } while (reader.NodeType != XmlNodeType.None
1180 && (reader.NodeType != XmlNodeType.Element
1181 || Nexpr != reader.Name));
1182 if (reader.NodeType == XmlNodeType.None)
1183 throw new Exception ("Node <expr> not found");
1184 node = doc.ReadNode (reader);
1187 Setup (node, domain);
1191 // EXPR = SYMBOL | MTEXT | INTEGER | FUNCALL | PROGN
1192 // FUNCALL = '(' SYMBOL EXPR* ')'
1193 // PROGN = '(' EXPR * ')'
1194 public Xex (XmlNode node, Domain domain)
1196 Setup (node, domain);
1199 public object Eval (Domain domain)
1201 if (function == null)
1205 Variable vari = domain.GetVar ((Name) args[0].val);
1211 val = function.Call (args, domain);
1215 public override string ToString ()
1219 if (function != null)
1221 str = "(" + function.name;
1223 foreach (Xex e in args)
1224 str += " " + e.ToString ();
1227 else if (args != null)
1229 str = (Name) args[0].val;
1231 else if (val != null)
1234 str = "\"" + ((string) val) + "\"";
1236 str = val.ToString ();