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 ("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 ()
250 internal abstract class Variable
252 public readonly Name name;
253 public readonly Name type;
256 public Variable (Name name, Name type, object value)
269 if (! ValueP (value))
270 throw new Exception ("Invalid value type: " + value);
275 public abstract bool ValueP (object value);
277 public override string ToString () { return name + "(" + type + ")"; }
280 internal class VarInt : Variable
287 public Range[] ranges;
289 public VarInt (Name name, object value) : base (name, Ninteger, value) { }
291 public override bool ValueP (object value)
295 if (! (value is int))
300 foreach (Range r in ranges)
301 if (i >= r.from && i <= r.to)
307 internal class VarStr : Variable
309 public string[] ranges;
311 public VarStr (Name name, object value) : base (name, Nstring, value) { }
313 public override bool ValueP (object value)
317 if (! (value is string))
321 str = (string) value;
322 foreach (string s in ranges)
329 internal class VarBool : Variable
331 public VarBool (Name name, object value)
332 : base (name, Nboolean, value) { }
334 public override bool ValueP (object value)
336 if (! (value is bool))
342 internal class VarMisc : Variable
344 public VarMisc (Name name, object value) : base (name, Nobject, value) { }
346 public override bool ValueP (object value)
352 internal class Bindings
354 private Variable vari;
355 private object old_value;
356 private Bindings next;
358 private Bindings (Variable vari, object value)
364 public static Bindings Bind (Bindings bindings,
365 Variable vari, object value)
367 Bindings b = new Bindings (vari, vari.val);
369 b.vari.Value = value;
374 internal Bindings UnboundTo (Bindings boundary)
376 for (Bindings b = this; b != boundary; b = b.next)
377 vari.val = b.old_value;
381 public override string ToString ()
383 string str = "(bindings";
384 for (Bindings b = this; b != null; b = b.next)
391 internal class ThrowException : Exception
396 public ThrowException (Name tag, object value) : base ()
406 public object context;
408 internal Dictionary<Name, Function> functions;
409 internal Dictionary<Name, Variable> variables;
410 internal Bindings bindings;
414 functions = new Dictionary<Name, Function> ();
415 variables = new Dictionary<Name, Variable> ();
418 public Domain (object context) : this (basic, context)
422 public Domain (Domain parent, object context)
424 functions = new Dictionary<Name, Function> (parent.functions);
425 variables = new Dictionary<Name, Variable> (parent.variables);
426 this.context = context;
429 internal void Bind (Variable vari, object value)
431 bindings = Bindings.Bind (bindings, vari, value);
434 internal void UnboundTo (Bindings boundary)
436 if (bindings != null)
437 bindings = bindings.UnboundTo (boundary);
440 public void Defun (Name name, Builtin builtin, int min_arg, int max_arg)
442 Defun (name, builtin, min_arg, max_arg, false);
445 public void Defun (Name name, Builtin builtin,
446 int min_arg, int max_arg, bool specialp)
450 if (functions.TryGetValue (name, out func))
452 if (func.min_arg < min_arg || func.max_arg > max_arg)
453 throw new Exception ("Incompatible argument numbers to override: "
455 func.builtin = builtin;
457 func.min_arg = min_arg;
458 func.max_arg = max_arg;
459 func.specialp = specialp;
464 = new Function (name, builtin, min_arg, max_arg, specialp);
468 internal Function RegisterFunction (XmlNode node)
470 int min_arg, max_arg;
471 Name name = Function.ParseHead (node, out min_arg, out max_arg);
472 Function func = new Function (name, min_arg, max_arg);
474 functions[name] = func;
478 internal Function Defun (XmlNode node)
480 Name name = node.Attributes[Nfname].Value;
483 if (! functions.TryGetValue (name, out func))
484 func = RegisterFunction (node);
485 func.Setup (node, this);
489 public void Defvar (Name name, XmlNode node)
493 if (node.Name == Ndescription)
494 node = node.NextSibling;
495 if (node.Name == Nconst)
497 Name type = (Name) node.Attributes[Ntype].Value;
498 string val = node.Value;
499 XmlNodeList range_list = null;
502 node = node.NextSibling;
503 if (node.Name == Npossible_value)
505 range_list = node.ChildNodes;
506 nranges = range_list.Count;
509 if (type == Ninteger)
511 VarInt vi = new VarInt (name, parse_integer (val));
512 if (range_list != null)
514 vi.ranges = new VarInt.Range[nranges];
516 for (int i = 0; i < nranges; i++)
518 XmlNode n = range_list[i];
520 if (n.Name == Nconst)
522 int num = parse_integer (n.Value);
523 vi.ranges[i].from = vi.ranges[i].to = num;
525 else // range_list[i].Name == "range"
528 parse_integer (n.FirstChild.Value);
530 parse_integer (n.LastChild.Value);
536 else if (type == Nstring)
538 VarStr vs = new VarStr (name, val);
539 if (range_list != null)
540 vs.ranges = new string[nranges];
541 for (int i = 0; i < nranges; i++)
542 vs.ranges[i] = range_list[i].Value;
545 else if (type == Nboolean)
547 vari = new VarBool (name, val == "true");
550 throw new Exception ("Unknown type: " + type);
553 vari = new VarMisc (name, null);
554 variables[name] = vari;
557 internal Function GetFunc (Name name)
561 if (! functions.TryGetValue (name, out func))
562 throw new Exception ("Unknown function: " + name);
566 public bool CopyFunc (Domain domain, Name name)
568 Function func = GetFunc (name);
570 domain.functions[name] = func;
574 public void CopyFunc (Domain domain)
576 foreach (KeyValuePair<Name, Function> kv in functions)
577 domain.functions[kv.Key] = kv.Value;
580 internal Variable GetVar (Name name)
584 if (! variables.TryGetValue (name, out vari))
585 variables[name] = vari = new VarMisc (name, null);
589 internal Variable GetVar (Xex e)
591 if (! (e.val is Name))
592 throw new Exception ("Not a symbol" + e.val);
593 return GetVar ((Name) e.val);
596 public override string ToString ()
598 string str = "<(functions";
599 foreach (KeyValuePair<Name, Function> kv in functions)
601 str += ") (variabls";
602 foreach (KeyValuePair<Name, Variable> kv in variables)
605 if (bindings != null)
606 str += " " + bindings;
608 str += " (" + context + ")";
614 public delegate object Builtin (Xex[] args, Domain domain);
616 private static Domain basic = new Domain ();
618 internal static Function Fprogn;
622 basic.Defun ("set", set_value, 2, 2, false);
623 basic.Defun ("=", set_value, 2, 2, false);
624 basic.Defun ("and", and, 1, -1, false);
625 basic.Defun ("&&", and, 1, -1, false);
626 basic.Defun ("or", or, 1, -1, false);
627 basic.Defun ("||", or, 1, -1, false);
628 basic.Defun ("not", not, 1, 1, false);
629 basic.Defun ("!", not, 1, 1, false);
630 basic.Defun ("add", add, 2, -1, false);
631 basic.Defun ("+", add, 2, -1, false);
632 basic.Defun ("mul", mul, 2, -1, false);
633 basic.Defun ("*", mul, 2, -1, false);
634 basic.Defun ("sub", sub, 1, -1, false);
635 basic.Defun ("-", sub, 1, -1, false);
636 basic.Defun ("div", div, 2, -1, false);
637 basic.Defun ("/", div, 2, -1, false);
638 basic.Defun ("mod", mod, 2, 2, false);
639 basic.Defun ("%", mod, 2, 2, false);
640 basic.Defun ("logior", logior, 2, -1, false);
641 basic.Defun ("|", logior, 2, -1, false);
642 basic.Defun ("logand", logand, 2, -1, false);
643 basic.Defun ("&", logand, 2, -1, false);
644 basic.Defun ("add-set", add_set, 2, -1, true);
645 basic.Defun ("+=", add_set, 2, -1, true);
646 basic.Defun ("mul-set", mul_set, 2, -1, true);
647 basic.Defun ("*=", mul_set, 2, -1, true);
648 basic.Defun ("sub-set", sub_set, 2, -1, true);
649 basic.Defun ("-=", sub_set, 2, -1, true);
650 basic.Defun ("div-set", div_set, 2, -1, true);
651 basic.Defun ("/=", div_set, 2, -1, true);
652 basic.Defun ("mod-set", mod_set, 2, 2, true);
653 basic.Defun ("%=", mod_set, 2, 2, true);
654 basic.Defun ("logior-set", logior_set, 2, -1, true);
655 basic.Defun ("|=", logior_set, 2, -1, true);
656 basic.Defun ("logand-set", logand_set, 2, -1, true);
657 basic.Defun ("&=", logand_set, 2, -1, true);
658 basic.Defun ("lsh", lsh, 2, 2, false);
659 basic.Defun ("<<", lsh, 2, 2, false);
660 basic.Defun ("rsh", rsh, 2, 2, false);
661 basic.Defun (">>", rsh, 2, 2, false);
662 basic.Defun ("lsh-set", lsh_set, 2, 2, true);
663 basic.Defun ("<<=", lsh_set, 2, 2, true);
664 basic.Defun ("rsh-set", rsh_set, 2, 2, true);
665 basic.Defun (">>=", rsh_set, 2, 2, true);
666 basic.Defun ("eq", eq, 2, -1, false);
667 basic.Defun ("==", eq, 2, -1, false);
668 basic.Defun ("noteq", noteq, 2, 2, false);
669 basic.Defun ("!=", noteq, 2, 2, false);
670 basic.Defun ("lt", less_than, 2, -1, false);
671 basic.Defun ("<", less_than, 2, -1, false);
672 basic.Defun ("le", less_eq, 2, -1, false);
673 basic.Defun ("<=", less_eq, 2, -1, false);
674 basic.Defun ("gt", greater_than, 2, -1, false);
675 basic.Defun (">", greater_than, 2, -1, false);
676 basic.Defun ("ge", greater_eq, 2, -1, false);
677 basic.Defun (">=", greater_eq, 2, -1, false);
678 basic.Defun ("eval", eval_clause, 1, 1, true);
679 basic.Defun ("progn", progn_clause, 0, -1, true);
680 basic.Defun ("expr", progn_clause, 0, -1, true);
681 basic.Defun ("if", if_clause, 2, -1, true);
682 basic.Defun ("when", when_clause, 1, -1, true);
683 basic.Defun ("while", while_clause, 1, -1, true);
685 Fprogn = basic.GetFunc (Nprogn);
688 private static bool is_true (object val)
690 return (val is bool ? (bool) val
691 : val is int ? (int) val == 0
695 private static object set_value (Xex[] args, Domain domain)
697 Variable vari = domain.GetVar (args[0]);
699 vari.Value = args[1].val;
703 private static object and (Xex[] args, Domain domain)
705 foreach (Xex arg in args)
706 if (! is_true (arg.val))
711 private static object or (Xex[] args, Domain domain)
713 foreach (Xex arg in args)
714 if (is_true (arg.val))
719 private static object not (Xex[] args, Domain domain)
721 return ! is_true (args[0].val);
724 private static object add (Xex[] args, Domain domain)
727 foreach (Xex e in args)
732 private static object mul (Xex[] args, Domain domain)
735 foreach (Xex e in args)
740 private static object sub (Xex[] args, Domain domain)
742 int n = (int) args[0].val;
743 if (args.Length == 1)
745 for (int i = 1; i < args.Length; i++)
746 n -= (int) args[i].val;
750 private static object div (Xex[] args, Domain domain)
752 int n = (int) args[0].val;
753 for (int i = 1; i < args.Length; i++)
754 n /= (int) args[i].val;
758 private static object mod (Xex[] args, Domain domain)
760 return ((int) args[0].val % (int) args[1].val);
763 private static object logior (Xex[] args, Domain domain)
766 foreach (Xex e in args)
771 private static object logand (Xex[] args, Domain domain)
773 int n = (int) args[0].val;
774 for (int i = 1; i < args.Length; i++)
775 n &= (int) args[i].val;
779 private static object add_set (Xex[] args, Domain domain)
781 Variable vari = domain.GetVar (args[0]);
782 int n = (int) vari.val;
784 for (int i = 1; i < args.Length; i++)
785 n += (int) args[i].val;
790 private static object mul_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 sub_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 div_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 mod_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 logior_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 logand_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 lsh (Xex[] args, Domain domain)
858 return (int) args[0].val << (int) args[1].val;
861 private static object lsh_set (Xex[] args, Domain domain)
863 Variable vari = domain.GetVar (args[0]);
864 int n = (int) vari.val;
866 n <<= (int) args[1].val;
871 private static object rsh (Xex[] args, Domain domain)
873 return (int) args[0].val >> (int) args[1].val;
876 private static object rsh_set (Xex[] args, Domain domain)
878 Variable vari = domain.GetVar (args[0]);
879 int n = (int) vari.val;
881 n >>= (int) args[1].val;
886 private static object eq (Xex[] args, Domain domain)
888 int n = (int) args[0].val;
890 for (int i = 1; i < args.Length; i++)
891 if (n != (int) args[i].val)
896 private static object noteq (Xex[] args, Domain domain)
898 return ((int) args[0].val != (int) args[1].val);
901 private static object less_than (Xex[] args, Domain domain)
903 int n = (int) args[0].val;
905 for (int i = 1; i < args.Length; i++)
907 int n1 = (int) args[i].val;
915 private static object less_eq (Xex[] args, Domain domain)
917 int n = (int) args[0].val;
918 for (int i = 1; i < args.Length; i++)
920 int n1 = (int) args[i].val;
928 private static object greater_than (Xex[] args, Domain domain)
930 int n = (int) args[0].val;
931 for (int i = 1; i < args.Length; i++)
933 int n1 = (int) args[i].val;
941 private static object greater_eq (Xex[] args, Domain domain)
943 int n = (int) args[0].val;
944 for (int i = 1; i < args.Length; i++)
946 int n1 = (int) args[i].val;
954 private static object eval_clause (Xex[] args, Domain domain)
956 return args[0].Eval (domain);
959 private static object progn_clause (Xex[] args, Domain domain)
961 object result = true;
963 foreach (Xex e in args)
964 result = e.Eval (domain);
968 private static object if_clause (Xex[] args, Domain domain)
972 if (is_true (args[0].Eval (domain)))
973 result = args[1].Eval (domain);
977 for (int i = 2; i < args.Length; i++)
978 result = args[i].Eval (domain);
983 private static object when_clause (Xex[] args, Domain domain)
985 if (! is_true (args[0].Eval (domain)))
988 object result = true;
989 for (int i = 1; i < args.Length; i++)
990 result = args[i].Eval (domain);
994 private static object while_clause (Xex[] args, Domain domain)
996 while (is_true (args[0].Eval (domain)))
997 for (int i = 1; i < args.Length; i++)
998 args[i].Eval (domain);
1002 // FUNCALL: function != null
1003 // VARREF: function == null, args[0] = DIRECT-SYMBOL
1004 // DIRECT: function == null, args == null
1006 private Function function;
1010 public Xex[] Args { get { return args; } }
1011 public object Val { get { return val; } }
1015 private Xex (object val)
1020 internal static int parse_integer (string str)
1022 int len = str.Length;
1023 bool negative = false;
1026 return (len == 0 ? 0 : str[0] - '0');
1031 if (c == '0' && str[1] == 'x')
1034 for (int idx = 2; idx < len; idx++)
1040 i = i * 16 + (c - '0');
1044 i = i * 16 + (c - 'A');
1048 i = i * 16 + (c - 'a');
1057 for (int idx = 1; idx < len; idx++)
1060 if (c < '0' || c > '9')
1062 i = i * 10 + (c - '0');
1064 return negative ? - i : i;
1067 private int pre_parse (XmlNodeList nlist, Domain domain)
1070 foreach (XmlNode node in nlist)
1072 if (node.Name == Ndefun)
1073 domain.RegisterFunction (node);
1074 else if (node.Name == Ndefvar)
1075 domain.Defvar ((Name) node.Attributes[0].Value, node.FirstChild);
1082 private void post_parse (XmlNodeList nlist, Domain domain)
1084 for (int i = 0, j = 0; i < nlist.Count; i++)
1086 XmlNode node = nlist[i];
1088 if (node.Name == Ndefun)
1089 domain.Defun (node);
1090 else if (node.Name != Ndefvar)
1091 args[j++] = new Xex (node, domain);
1095 private void Setup (XmlNode node, Domain domain)
1097 Name name = node.Name;
1101 Name type = node.Attributes[Ntype].Value;
1103 if (type == Ninteger)
1104 val = parse_integer (node.InnerText);
1105 else if (type == Nstring)
1106 val = node.InnerText;
1107 else if (type == Nsymbol)
1108 val = (Name) node.InnerText;
1109 else if (type == Nboolean)
1110 val = node.InnerText == "true";
1111 else if (type == Nlist)
1113 List<Xex> list = new List<Xex> ();
1114 for (XmlNode n = node.FirstChild; n != null; n = n.NextSibling)
1115 list.Add (new Xex (n, domain));
1119 throw new Exception ("Unknown type: " + type);
1121 else if (name == Nvariable)
1124 args[0] = new Xex ((Name) node.Attributes[0].Value);
1128 if (name == Nfuncall)
1129 name = node.Attributes[0].Value;
1130 function = domain.GetFunc (name);
1132 XmlNodeList nlist = node.ChildNodes;
1133 int nargs = nlist.Count;
1135 if (nargs < function.min_arg
1136 || (function.max_arg >= 0 && nargs > function.max_arg))
1137 throw new Exception ("Invalid number of arguments to: "
1138 + name + " " + nargs);
1139 nargs = pre_parse (nlist, domain);
1140 args = new Xex[nargs];
1141 post_parse (nlist, domain);
1145 public Xex (string url, Domain domain)
1147 XmlDocument doc = new XmlDocument (Name.Table);
1150 using (XmlTextReader reader = new XmlTextReader (url, Name.Table))
1154 } while (reader.NodeType != XmlNodeType.None
1155 && (reader.NodeType != XmlNodeType.Element
1156 || Nexpr != reader.Name));
1157 if (reader.NodeType == XmlNodeType.None)
1158 throw new Exception ("Node <expr> not found");
1159 node = doc.ReadNode (reader);
1162 Setup (node, domain);
1165 // EXPR = SYMBOL | MTEXT | INTEGER | FUNCALL | PROGN
1166 // FUNCALL = '(' SYMBOL EXPR* ')'
1167 // PROGN = '(' EXPR * ')'
1168 public Xex (XmlNode node, Domain domain)
1170 Setup (node, domain);
1173 public object Eval (Domain domain)
1175 if (function == null)
1179 Variable vari = domain.GetVar ((Name) args[0].val);
1185 val = function.Call (args, domain);
1189 public override string ToString ()
1193 if (function != null)
1195 str = "(" + function.name;
1197 foreach (Xex e in args)
1198 str += " " + e.ToString ();
1201 else if (args != null)
1203 str = (Name) args[0].val;
1205 else if (val != null)
1208 str = "\"" + ((string) val) + "\"";
1210 str = val.ToString ();