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 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";
83 private static Name Ntype = "type";
85 private static Name Ninteger = "integer";
86 private static Name Nstring = "string";
87 private static Name Nboolean = "boolean";
88 private static Name Nsymbol = "symbol";
89 private static Name Nlist = "list";
90 private static Name Nobject = "object";
92 private static Name Ndefun = "defun";
93 private static Name Nfname = "fname";
94 private static Name Nargs = "args";
95 private static Name Noptional = "optional";
96 private static Name Nrest = "rest";
97 private static Name Nbody = "body";
99 private static Name Ndefvar = "defvar";
100 private static Name Nconst = "const";
101 private static Name Nvariable = "variable";
102 private static Name Ndescription = "description";
103 private static Name Npossible_value = "possible-value";
105 private static Name Nfuncall = "funcall";
106 private static Name Nprogn = "progn";
108 internal class Function
110 internal class Lambda
115 public void SetArgs (XmlNode node, int nargs, Domain domain)
117 args = new Xex[nargs];
118 node = node.FirstChild;
119 for (int i = 0; i < nargs; node = node.NextSibling)
120 if (node.Name != Noptional && node.Name != Nrest)
121 args[i++] = new Xex (node, domain);
124 public void SetBody (XmlNode node, Domain domain)
126 XmlNodeList nlist = node.ChildNodes;
128 body = new Xex[nlist.Count];
129 for (int i = 0; i < nlist.Count; i++)
130 body[i] = new Xex (nlist[i], domain);
134 public readonly Name name;
135 public Builtin builtin;
136 public int min_arg, max_arg;
137 internal Lambda lambda;
138 public bool specialp = false;
140 public Function (Name name, Builtin builtin,
141 int min_arg, int max_arg, bool specialp)
144 this.builtin = builtin;
145 this.min_arg = min_arg;
146 this.max_arg = max_arg;
147 this.specialp = specialp;
150 public Function (Name name, int min_arg, int max_arg)
153 this.min_arg = min_arg;
154 this.max_arg = max_arg;
157 public void Setup (XmlNode node, Domain domain)
159 lambda = new Lambda ();
160 node = node.FirstChild;
161 if (node.Name == Nargs)
163 lambda.SetArgs (node, max_arg, domain);
164 node = node.NextSibling;
166 if (node.Name == Nbody)
167 lambda.SetBody (node, domain);
170 public static Name ParseHead (XmlNode node,
171 out int min_arg, out int max_arg)
173 Name name = node.Attributes[Nfname].Value;
174 int nargs = 0, noptions = 0, nrest = 0;
177 for (n = node.FirstChild; n != null; n = n.NextSibling)
179 if (n.Name == Noptional || n.Name == Nrest)
183 if (n != null && n.Name == Noptional)
184 for (n = n.NextSibling; n != null; n = n.NextSibling)
190 if (n != null && n.Name == Nrest)
191 for (n = n.NextSibling; n != null; n = n.NextSibling)
194 max_arg = nargs + noptions + nrest;
200 public object Call (Xex[] args, Domain domain)
202 Bindings current = domain.bindings;
203 object result = false;
205 Console.Write ("calling (" + this);
207 foreach (Xex e in args)
208 Console.Write (" " + e);
209 Console.Write (") => ");
213 foreach (Xex a in args)
214 if (a.Eval (domain) == null)
215 throw new Exception (a + ":evaled to null");
216 result = builtin (args, domain);
217 Console.WriteLine (result);
222 for (i = 0; i < min_arg; i++)
224 Xex a = lambda.args[i];
225 bool isdirect = a.args == null;
226 Name name = isdirect ? (Name) a.val : (Name) a.args[0].val;
227 Variable var = new VarMisc (name, null);
229 domain.variables[name] = var;
231 domain.Bind (var, args[i]);
233 domain.Bind (var, args[i].Eval (domain));
235 foreach (Xex e in lambda.body)
236 result = e.Eval (domain);
237 Console.WriteLine (result);
239 domain.UnboundTo (current);
244 public override string ToString ()
253 foreach (Xex a in lambda.args)
261 internal abstract class Variable
263 public readonly Name name;
264 public readonly Name type;
267 public Variable (Name name, Name type, object value)
280 if (! ValueP (value))
281 throw new Exception ("Invalid value type: " + value);
286 public abstract bool ValueP (object value);
288 public override string ToString () { return name + "=" + val; }
291 internal class VarInt : Variable
298 public Range[] ranges;
300 public VarInt (Name name, object value) : base (name, Ninteger, value) { }
302 public override bool ValueP (object value)
306 if (! (value is int))
311 foreach (Range r in ranges)
312 if (i >= r.from && i <= r.to)
318 internal class VarStr : Variable
320 public string[] ranges;
322 public VarStr (Name name, object value) : base (name, Nstring, value) { }
324 public override bool ValueP (object value)
328 if (! (value is string))
332 str = (string) value;
333 foreach (string s in ranges)
340 internal class VarBool : Variable
342 public VarBool (Name name, object value)
343 : base (name, Nboolean, value) { }
345 public override bool ValueP (object value)
347 if (! (value is bool))
353 internal class VarMisc : Variable
355 public VarMisc (Name name, object value) : base (name, Nobject, value) { }
357 public override bool ValueP (object value)
363 internal class Bindings
365 private Variable vari;
366 private object old_value;
367 private Bindings next;
369 private Bindings (Variable vari, object value)
375 public static Bindings Bind (Bindings bindings,
376 Variable vari, object value)
378 Bindings b = new Bindings (vari, vari.val);
380 b.vari.Value = value;
385 internal Bindings UnboundTo (Bindings boundary)
387 for (Bindings b = this; b != boundary; b = b.next)
388 vari.val = b.old_value;
392 public override string ToString ()
394 string str = "(bindings";
395 for (Bindings b = this; b != null; b = b.next)
402 internal class ThrowException : Exception
407 public ThrowException (Name tag, object value) : base ()
417 public object context;
419 internal Dictionary<Name, Function> functions;
420 internal Dictionary<Name, Variable> variables;
421 internal Bindings bindings;
425 functions = new Dictionary<Name, Function> ();
426 variables = new Dictionary<Name, Variable> ();
429 public Domain (object context) : this (basic, context)
433 public Domain (Domain parent, object context)
435 functions = new Dictionary<Name, Function> (parent.functions);
436 variables = new Dictionary<Name, Variable> (parent.variables);
437 this.context = context;
440 internal void Bind (Variable vari, object value)
442 bindings = Bindings.Bind (bindings, vari, value);
445 internal void UnboundTo (Bindings boundary)
447 if (bindings != null)
448 bindings = bindings.UnboundTo (boundary);
451 public void Defun (Name name, Builtin builtin, int min_arg, int max_arg)
453 Defun (name, builtin, min_arg, max_arg, false);
456 public void Defun (Name name, Builtin builtin,
457 int min_arg, int max_arg, bool specialp)
461 if (functions.TryGetValue (name, out func))
463 if (func.min_arg < min_arg || func.max_arg > max_arg)
464 throw new Exception ("Incompatible argument numbers to override: "
466 func.builtin = builtin;
468 func.min_arg = min_arg;
469 func.max_arg = max_arg;
470 func.specialp = specialp;
475 = new Function (name, builtin, min_arg, max_arg, specialp);
479 internal Function RegisterFunction (XmlNode node)
481 int min_arg, max_arg;
482 Name name = Function.ParseHead (node, out min_arg, out max_arg);
483 Function func = new Function (name, min_arg, max_arg);
485 functions[name] = func;
489 internal Function Defun (XmlNode node)
491 Name name = node.Attributes[Nfname].Value;
494 if (! functions.TryGetValue (name, out func))
495 func = RegisterFunction (node);
496 func.Setup (node, this);
500 public void Defvar (Name name, XmlNode node)
504 if (node.Name == Ndescription)
505 node = node.NextSibling;
506 if (node.Name == Nconst)
508 Name type = (Name) node.Attributes[Ntype].Value;
509 string val = node.Value;
510 XmlNodeList range_list = null;
513 node = node.NextSibling;
514 if (node.Name == Npossible_value)
516 range_list = node.ChildNodes;
517 nranges = range_list.Count;
520 if (type == Ninteger)
522 VarInt vi = new VarInt (name, parse_integer (val));
523 if (range_list != null)
525 vi.ranges = new VarInt.Range[nranges];
527 for (int i = 0; i < nranges; i++)
529 XmlNode n = range_list[i];
531 if (n.Name == Nconst)
533 int num = parse_integer (n.Value);
534 vi.ranges[i].from = vi.ranges[i].to = num;
536 else // range_list[i].Name == "range"
539 parse_integer (n.FirstChild.Value);
541 parse_integer (n.LastChild.Value);
547 else if (type == Nstring)
549 VarStr vs = new VarStr (name, val);
550 if (range_list != null)
551 vs.ranges = new string[nranges];
552 for (int i = 0; i < nranges; i++)
553 vs.ranges[i] = range_list[i].Value;
556 else if (type == Nboolean)
558 vari = new VarBool (name, val == "true");
561 throw new Exception ("Unknown type: " + type);
564 vari = new VarMisc (name, null);
565 variables[name] = vari;
568 internal Function GetFunc (Name name)
572 if (! functions.TryGetValue (name, out func))
573 throw new Exception ("Unknown function: " + name);
577 public bool CopyFunc (Domain domain, Name name)
579 Function func = GetFunc (name);
581 domain.functions[name] = func;
585 public void CopyFunc (Domain domain)
587 foreach (KeyValuePair<Name, Function> kv in functions)
588 domain.functions[kv.Key] = kv.Value;
591 internal Variable GetVar (Name name)
595 if (! variables.TryGetValue (name, out vari))
596 variables[name] = vari = new VarMisc (name, null);
600 internal Variable GetVar (Xex e)
602 if (! (e.val is Name))
603 throw new Exception ("Not a symbol" + e.val);
604 return GetVar ((Name) e.val);
607 public override string ToString ()
609 string str = "<(functions";
610 foreach (KeyValuePair<Name, Function> kv in functions)
612 str += ") (variabls";
613 foreach (KeyValuePair<Name, Variable> kv in variables)
616 if (bindings != null)
617 str += " " + bindings;
619 str += " (" + context + ")";
625 public delegate object Builtin (Xex[] args, Domain domain);
627 private static Domain basic = new Domain ();
629 internal static Function Fprogn;
633 basic.Defun ("set", set_value, 2, 2, false);
634 basic.Defun ("=", set_value, 2, 2, false);
635 basic.Defun ("and", and, 1, -1, false);
636 basic.Defun ("&&", and, 1, -1, false);
637 basic.Defun ("or", or, 1, -1, false);
638 basic.Defun ("||", or, 1, -1, false);
639 basic.Defun ("not", not, 1, 1, false);
640 basic.Defun ("!", not, 1, 1, false);
641 basic.Defun ("add", add, 2, -1, false);
642 basic.Defun ("+", add, 2, -1, false);
643 basic.Defun ("mul", mul, 2, -1, false);
644 basic.Defun ("*", mul, 2, -1, false);
645 basic.Defun ("sub", sub, 1, -1, false);
646 basic.Defun ("-", sub, 1, -1, false);
647 basic.Defun ("div", div, 2, -1, false);
648 basic.Defun ("/", div, 2, -1, false);
649 basic.Defun ("mod", mod, 2, 2, false);
650 basic.Defun ("%", mod, 2, 2, false);
651 basic.Defun ("logior", logior, 2, -1, false);
652 basic.Defun ("|", logior, 2, -1, false);
653 basic.Defun ("logand", logand, 2, -1, false);
654 basic.Defun ("&", logand, 2, -1, false);
655 basic.Defun ("add-set", add_set, 2, -1, true);
656 basic.Defun ("+=", add_set, 2, -1, true);
657 basic.Defun ("mul-set", mul_set, 2, -1, true);
658 basic.Defun ("*=", mul_set, 2, -1, true);
659 basic.Defun ("sub-set", sub_set, 2, -1, true);
660 basic.Defun ("-=", sub_set, 2, -1, true);
661 basic.Defun ("div-set", div_set, 2, -1, true);
662 basic.Defun ("/=", div_set, 2, -1, true);
663 basic.Defun ("mod-set", mod_set, 2, 2, true);
664 basic.Defun ("%=", mod_set, 2, 2, true);
665 basic.Defun ("logior-set", logior_set, 2, -1, true);
666 basic.Defun ("|=", logior_set, 2, -1, true);
667 basic.Defun ("logand-set", logand_set, 2, -1, true);
668 basic.Defun ("&=", logand_set, 2, -1, true);
669 basic.Defun ("lsh", lsh, 2, 2, false);
670 basic.Defun ("<<", lsh, 2, 2, false);
671 basic.Defun ("rsh", rsh, 2, 2, false);
672 basic.Defun (">>", rsh, 2, 2, false);
673 basic.Defun ("lsh-set", lsh_set, 2, 2, true);
674 basic.Defun ("<<=", lsh_set, 2, 2, true);
675 basic.Defun ("rsh-set", rsh_set, 2, 2, true);
676 basic.Defun (">>=", rsh_set, 2, 2, true);
677 basic.Defun ("eq", eq, 2, -1, false);
678 basic.Defun ("==", eq, 2, -1, false);
679 basic.Defun ("noteq", noteq, 2, 2, false);
680 basic.Defun ("!=", noteq, 2, 2, false);
681 basic.Defun ("lt", less_than, 2, -1, false);
682 basic.Defun ("<", less_than, 2, -1, false);
683 basic.Defun ("le", less_eq, 2, -1, false);
684 basic.Defun ("<=", less_eq, 2, -1, false);
685 basic.Defun ("gt", greater_than, 2, -1, false);
686 basic.Defun (">", greater_than, 2, -1, false);
687 basic.Defun ("ge", greater_eq, 2, -1, false);
688 basic.Defun (">=", greater_eq, 2, -1, false);
689 basic.Defun ("eval", eval_clause, 1, 1, true);
690 basic.Defun ("progn", progn_clause, 0, -1, true);
691 basic.Defun ("expr", progn_clause, 0, -1, true);
692 basic.Defun ("if", if_clause, 2, -1, true);
693 basic.Defun ("when", when_clause, 1, -1, true);
694 basic.Defun ("while", while_clause, 1, -1, true);
696 Fprogn = basic.GetFunc (Nprogn);
699 private static bool is_true (object val)
701 return (val is bool ? (bool) val
702 : val is int ? (int) val == 0
706 private static object set_value (Xex[] args, Domain domain)
708 Variable vari = domain.GetVar (args[0]);
710 vari.Value = args[1].val;
714 private static object and (Xex[] args, Domain domain)
716 foreach (Xex arg in args)
717 if (! is_true (arg.val))
722 private static object or (Xex[] args, Domain domain)
724 foreach (Xex arg in args)
725 if (is_true (arg.val))
730 private static object not (Xex[] args, Domain domain)
732 return ! is_true (args[0].val);
735 private static object add (Xex[] args, Domain domain)
738 foreach (Xex e in args)
743 private static object mul (Xex[] args, Domain domain)
746 foreach (Xex e in args)
751 private static object sub (Xex[] args, Domain domain)
753 int n = (int) args[0].val;
754 if (args.Length == 1)
756 for (int i = 1; i < args.Length; i++)
757 n -= (int) args[i].val;
761 private static object div (Xex[] args, Domain domain)
763 int n = (int) args[0].val;
764 for (int i = 1; i < args.Length; i++)
765 n /= (int) args[i].val;
769 private static object mod (Xex[] args, Domain domain)
771 return ((int) args[0].val % (int) args[1].val);
774 private static object logior (Xex[] args, Domain domain)
777 foreach (Xex e in args)
782 private static object logand (Xex[] args, Domain domain)
784 int n = (int) args[0].val;
785 for (int i = 1; i < args.Length; i++)
786 n &= (int) args[i].val;
790 private static object add_set (Xex[] args, Domain domain)
792 Variable vari = domain.GetVar (args[0]);
793 int n = (int) vari.val;
795 for (int i = 1; i < args.Length; i++)
796 n += (int) args[i].val;
801 private static object mul_set (Xex[] args, Domain domain)
803 Variable vari = domain.GetVar (args[0]);
804 int n = (int) vari.val;
806 for (int i = 1; i < args.Length; i++)
807 n *= (int) args[i].val;
812 private static object sub_set (Xex[] args, Domain domain)
814 Variable vari = domain.GetVar (args[0]);
815 int n = (int) vari.val;
817 for (int i = 1; i < args.Length; i++)
818 n -= (int) args[i].val;
823 private static object div_set (Xex[] args, Domain domain)
825 Variable vari = domain.GetVar (args[0]);
826 int n = (int) vari.val;
828 for (int i = 1; i < args.Length; i++)
829 n /= (int) args[i].val;
834 private static object mod_set (Xex[] args, Domain domain)
836 Variable vari = domain.GetVar (args[0]);
837 int n = (int) vari.val;
839 for (int i = 1; i < args.Length; i++)
840 n %= (int) args[i].val;
845 private static object logior_set (Xex[] args, Domain domain)
847 Variable vari = domain.GetVar (args[0]);
848 int n = (int) vari.val;
850 for (int i = 1; i < args.Length; i++)
851 n |= (int) args[i].val;
856 private static object logand_set (Xex[] args, Domain domain)
858 Variable vari = domain.GetVar (args[0]);
859 int n = (int) vari.val;
861 for (int i = 1; i < args.Length; i++)
862 n &= (int) args[i].val;
867 private static object lsh (Xex[] args, Domain domain)
869 return (int) args[0].val << (int) args[1].val;
872 private static object lsh_set (Xex[] args, Domain domain)
874 Variable vari = domain.GetVar (args[0]);
875 int n = (int) vari.val;
877 n <<= (int) args[1].val;
882 private static object rsh (Xex[] args, Domain domain)
884 return (int) args[0].val >> (int) args[1].val;
887 private static object rsh_set (Xex[] args, Domain domain)
889 Variable vari = domain.GetVar (args[0]);
890 int n = (int) vari.val;
892 n >>= (int) args[1].val;
897 private static object eq (Xex[] args, Domain domain)
899 int n = (int) args[0].val;
901 for (int i = 1; i < args.Length; i++)
902 if (n != (int) args[i].val)
907 private static object noteq (Xex[] args, Domain domain)
909 return ((int) args[0].val != (int) args[1].val);
912 private static object less_than (Xex[] args, Domain domain)
914 int n = (int) args[0].val;
916 for (int i = 1; i < args.Length; i++)
918 int n1 = (int) args[i].val;
926 private static object less_eq (Xex[] args, Domain domain)
928 int n = (int) args[0].val;
929 for (int i = 1; i < args.Length; i++)
931 int n1 = (int) args[i].val;
939 private static object greater_than (Xex[] args, Domain domain)
941 int n = (int) args[0].val;
942 for (int i = 1; i < args.Length; i++)
944 int n1 = (int) args[i].val;
952 private static object greater_eq (Xex[] args, Domain domain)
954 int n = (int) args[0].val;
955 for (int i = 1; i < args.Length; i++)
957 int n1 = (int) args[i].val;
965 private static object eval_clause (Xex[] args, Domain domain)
967 return args[0].Eval (domain);
970 private static object progn_clause (Xex[] args, Domain domain)
972 object result = true;
974 foreach (Xex e in args)
975 result = e.Eval (domain);
979 private static object if_clause (Xex[] args, Domain domain)
983 if (is_true (args[0].Eval (domain)))
984 result = args[1].Eval (domain);
988 for (int i = 2; i < args.Length; i++)
989 result = args[i].Eval (domain);
994 private static object when_clause (Xex[] args, Domain domain)
996 if (! is_true (args[0].Eval (domain)))
999 object result = true;
1000 for (int i = 1; i < args.Length; i++)
1001 result = args[i].Eval (domain);
1005 private static object while_clause (Xex[] args, Domain domain)
1007 while (is_true (args[0].Eval (domain)))
1008 for (int i = 1; i < args.Length; i++)
1009 args[i].Eval (domain);
1013 // FUNCALL: function != null
1014 // VARREF: function == null, args[0] = DIRECT-SYMBOL
1015 // DIRECT: function == null, args == null
1017 private Function function;
1021 public Xex[] Args { get { return args; } }
1022 public object Val { get { return val; } }
1026 private Xex (object val)
1031 internal static int parse_integer (string str)
1033 int len = str.Length;
1034 bool negative = false;
1037 return (len == 0 ? 0 : str[0] - '0');
1042 if (c == '0' && str[1] == 'x')
1045 for (int idx = 2; idx < len; idx++)
1051 i = i * 16 + (c - '0');
1055 i = i * 16 + (c - 'A');
1059 i = i * 16 + (c - 'a');
1068 for (int idx = 1; idx < len; idx++)
1071 if (c < '0' || c > '9')
1073 i = i * 10 + (c - '0');
1075 return negative ? - i : i;
1078 private int pre_parse (XmlNodeList nlist, Domain domain)
1081 foreach (XmlNode node in nlist)
1083 if (node.Name == Ndefun)
1084 domain.RegisterFunction (node);
1085 else if (node.Name == Ndefvar)
1086 domain.Defvar ((Name) node.Attributes[0].Value, node.FirstChild);
1093 private void post_parse (XmlNodeList nlist, Domain domain)
1095 for (int i = 0, j = 0; i < nlist.Count; i++)
1097 XmlNode node = nlist[i];
1099 if (node.Name == Ndefun)
1100 domain.Defun (node);
1101 else if (node.Name != Ndefvar)
1102 args[j++] = new Xex (node, domain);
1106 private void Setup (XmlNode node, Domain domain)
1108 Name name = node.Name;
1112 Name type = node.Attributes[Ntype].Value;
1114 if (type == Ninteger)
1115 val = parse_integer (node.InnerText);
1116 else if (type == Nstring)
1117 val = node.InnerText;
1118 else if (type == Nsymbol)
1119 val = (Name) node.InnerText;
1120 else if (type == Nboolean)
1121 val = node.InnerText == "true";
1122 else if (type == Nlist)
1124 List<Xex> list = new List<Xex> ();
1125 for (XmlNode n = node.FirstChild; n != null; n = n.NextSibling)
1126 list.Add (new Xex (n, domain));
1130 throw new Exception ("Unknown type: " + type);
1132 else if (name == Nvariable)
1135 args[0] = new Xex ((Name) node.Attributes[0].Value);
1139 if (name == Nfuncall)
1140 name = node.Attributes[0].Value;
1141 function = domain.GetFunc (name);
1143 XmlNodeList nlist = node.ChildNodes;
1144 int nargs = nlist.Count;
1146 if (nargs < function.min_arg
1147 || (function.max_arg >= 0 && nargs > function.max_arg))
1148 throw new Exception ("Invalid number of arguments to: "
1149 + name + " " + nargs);
1150 nargs = pre_parse (nlist, domain);
1151 args = new Xex[nargs];
1152 post_parse (nlist, domain);
1156 public Xex (string url, Domain domain)
1158 XmlDocument doc = new XmlDocument (Name.Table);
1161 using (XmlTextReader reader = new XmlTextReader (url, Name.Table))
1165 } while (reader.NodeType != XmlNodeType.None
1166 && (reader.NodeType != XmlNodeType.Element
1167 || Nexpr != reader.Name));
1168 if (reader.NodeType == XmlNodeType.None)
1169 throw new Exception ("Node <expr> not found");
1170 node = doc.ReadNode (reader);
1173 Setup (node, domain);
1176 // EXPR = SYMBOL | MTEXT | INTEGER | FUNCALL | PROGN
1177 // FUNCALL = '(' SYMBOL EXPR* ')'
1178 // PROGN = '(' EXPR * ')'
1179 public Xex (XmlNode node, Domain domain)
1181 Setup (node, domain);
1184 public object Eval (Domain domain)
1186 if (function == null)
1190 Variable vari = domain.GetVar ((Name) args[0].val);
1196 val = function.Call (args, domain);
1200 public override string ToString ()
1204 if (function != null)
1206 str = "(" + function.name;
1208 foreach (Xex e in args)
1209 str += " " + e.ToString ();
1212 else if (args != null)
1214 str = (Name) args[0].val;
1216 else if (val != null)
1219 str = "\"" + ((string) val) + "\"";
1221 str = val.ToString ();