namespace System.Xml.Expression
{
- public class Xex
+ public abstract class Xex
{
public struct Name : IEquatable<Name>
{
}
private static Name Nexpr = "expr";
- private static Name Ntype = "type";
+ private static Name Nfuncall = "funcall";
+ private static Name Nvariable = "variable";
private static Name Ninteger = "integer";
private static Name Nstring = "string";
private static Name Nboolean = "boolean";
private static Name Nbody = "body";
private static Name Ndefvar = "defvar";
- private static Name Nconst = "const";
- private static Name Nvariable = "variable";
private static Name Ndescription = "description";
- private static Name Npossible_value = "possible-value";
+ private static Name Nrange = "range";
- private static Name Nfuncall = "funcall";
private static Name Nprogn = "progn";
- internal class Function
+ internal abstract class Function
{
- internal class Lambda
- {
- internal Xex[] args;
- internal Xex[] body;
-
- public void SetArgs (XmlNode node, int nargs, Domain domain)
- {
- args = new Xex[nargs];
- node = node.FirstChild;
- for (int i = 0; i < nargs; node = node.NextSibling)
- if (node.Name != Noptional && node.Name != Nrest)
- args[i++] = new Xex (node, domain);
- }
-
- public void SetBody (XmlNode node, Domain domain)
- {
- XmlNodeList nlist = node.ChildNodes;
-
- body = new Xex[nlist.Count];
- for (int i = 0; i < nlist.Count; i++)
- body[i] = new Xex (nlist[i], domain);
- }
- }
-
public readonly Name name;
- public Builtin builtin;
public int min_arg, max_arg;
- internal Lambda lambda;
- public bool specialp = false;
- public Function (Name name, Builtin builtin,
- int min_arg, int max_arg, bool specialp)
+ public Function (Name name, int min_arg, int max_arg)
{
this.name = name;
- this.builtin = builtin;
this.min_arg = min_arg;
this.max_arg = max_arg;
- this.specialp = specialp;
}
- public Function (Name name, int min_arg, int max_arg)
+ public virtual object Call (Xex[] args, Domain domain)
{
- this.name = name;
- this.min_arg = min_arg;
- this.max_arg = max_arg;
+ object result;
+
+ Console.Write ("calling (" + this);
+ foreach (Xex a in args)
+ Console.Write (" " + a);
+ Console.Write (") => ");
+ result = builtin (args, domain);
+ Console.WriteLine (result);
+ return result;
}
- public void Setup (XmlNode node, Domain domain)
+ public override string ToString ()
+ {
+ return str;
+ }
+
+ internal class Subroutine : Function
{
- lambda = new Lambda ();
- node = node.FirstChild;
- if (node.Name == Nargs)
+ public Builtin builtin;
+
+ public Subroutine (Builtin builtin, Name name,
+ int min_arg, int max_arg)
+ : base (name, min_arg, max_arg)
{
- lambda.SetArgs (node, max_arg, domain);
- node = node.NextSibling;
+ this.builtin = builtin;
}
- if (node.Name == Nbody)
- lambda.SetBody (node, domain);
+
+ public override object Call (Xex[] args, Domain domain)
+ {
+ foreach (Xex a in args)
+ if (a.Eval (domain) == null)
+ throw new Exception (a + ":evaled to null");
+ return base.Call (args, domain);
+ }
}
- public static Name ParseHead (XmlNode node,
- out int min_arg, out int max_arg)
+ internal class SpecialForm : Function
{
- Name name = node.Attributes[Nfname].Value;
- int nargs = 0, noptions = 0, nrest = 0;
- XmlNode n;
-
- for (n = node.FirstChild; n != null; n = n.NextSibling)
+ public Builtin builtin;
+
+ public SpecialForm (Builtin builtin, Name name,
+ int min_arg, int max_arg)
+ : base (name, min_arg, max_arg)
{
- if (n.Name == Noptional || n.Name == Nrest)
- break;
- nargs++;
+ this.builtin = builtin;
}
- if (n != null && n.Name == Noptional)
- for (n = n.NextSibling; n != null; n = n.NextSibling)
- {
- if (n.Name == Nrest)
- break;
- noptions++;
- }
- if (n != null && n.Name == Nrest)
- for (n = n.NextSibling; n != null; n = n.NextSibling)
- nrest++;
- min_arg = nargs;
- max_arg = nargs + noptions + nrest;
- if (nrest == 1)
- max_arg = - max_arg;
- return name;
+
+ public override object Call (Xex[] args, Domain domain)
+ {
+ }
}
- public object Call (Xex[] args, Domain domain)
+ internal class Lambda : Function
{
- Bindings current = domain.bindings;
- object result = false;
+ internal Xex[] args;
+ internal Xex[] body;
- Console.Write ("calling (" + this);
- try {
- foreach (Xex e in args)
- Console.Write (" " + e);
- Console.Write (") => ");
- if (builtin != null)
+ public Lambda (Name name, int min_arg, int max_arg)
+ : base (name, min_arg, max_arg)
+ {
+ }
+
+ public void SetArgs (XmlNode node, int nargs, Domain domain)
+ {
+ args = new Xex[nargs];
+ node = node.FirstChild;
+ for (int i = 0; i < nargs; node = node.NextSibling)
+ if (node.Name != Noptional && node.Name != Nrest)
+ args[i++] = New (node, domain);
+ }
+
+ public void SetBody (XmlNode node, Domain domain)
+ {
+ XmlNodeList nlist = node.ChildNodes;
+
+ body = new Xex[nlist.Count];
+ for (int i = 0; i < nlist.Count; i++)
+ body[i] = New (nlist[i], domain);
+ }
+
+ public void Setup (XmlNode node, Domain domain)
+ {
+ lambda = new Lambda ();
+ node = node.FirstChild;
+ if (node.Name == Nargs)
{
- if (! specialp)
- foreach (Xex a in args)
- if (a.Eval (domain) == null)
- throw new Exception (a + ":evaled to null");
- result = builtin (args, domain);
- Console.WriteLine (result);
- return result;
+ SetArgs (node, max_arg, domain);
+ node = node.NextSibling;
}
+ if (node.Name == Nbody)
+ SetBody (node, domain);
+ }
- int i;
- for (i = 0; i < min_arg; i++)
+ public static Name ParseHead (XmlNode node,
+ out int min_arg, out int max_arg)
+ {
+ Name name = node.Attributes[Nfname].Value;
+ int nargs = 0, noptions = 0, nrest = 0;
+ XmlNode n;
+
+ for (n = node.FirstChild; n != null; n = n.NextSibling)
{
- Xex a = lambda.args[i];
- bool isdirect = a.args == null;
- Name name = isdirect ? (Name) a.val : (Name) a.args[0].val;
- Variable var = new VarMisc (name, null);
-
- domain.variables[name] = var;
- if (isdirect)
- domain.Bind (var, args[i]);
- else
- domain.Bind (var, args[i].Eval (domain));
+ if (n.Name == Noptional || n.Name == Nrest)
+ break;
+ nargs++;
}
- foreach (Xex e in lambda.body)
- result = e.Eval (domain);
- Console.WriteLine (result);
- } finally {
- domain.UnboundTo (current);
+ if (n != null && n.Name == Noptional)
+ for (n = n.NextSibling; n != null; n = n.NextSibling)
+ {
+ if (n.Name == Nrest)
+ break;
+ noptions++;
+ }
+ if (n != null && n.Name == Nrest)
+ for (n = n.NextSibling; n != null; n = n.NextSibling)
+ nrest++;
+ min_arg = nargs;
+ max_arg = nargs + noptions + nrest;
+ if (nrest == 1)
+ max_arg = - max_arg;
+ return name;
}
- return result;
- }
- public override string ToString ()
- {
- string str;
+ public override object Call (Xex[] args, Domain domain)
+ {
+ Bindings current = domain.bindings;
+ object result = false;
- if (builtin != null)
- str = name;
- else
- {
- str = "(" + name;
- foreach (Xex a in lambda.args)
- str += " " + a;
- str += ")";
+ try {
+ int i;
+ for (i = 0; i < min_arg; i++)
+ {
+ Xex a = this.args[i];
+ bool isdirect = a is Xex.Const;
+ Name name = (isdirect
+ ? (Name) a.val : ((Xex.Varref) a).vari.name);
+ Variable var = domain.GetVar (name);
+
+ if (isdirect)
+ domain.Bind (var, args[i].val);
+ else
+ domain.Bind (var, args[i].Eval (domain));
+ }
+ Console.Write ("calling (" + this);
+ foreach (Xex e in body)
+ result = e.Eval (domain);
+ Console.WriteLine (result);
+ } finally {
+ domain.UnboundTo (current);
}
- return str;
+ return result;
+ }
+
+ public override string ToString ()
+ {
+ str = "(" + name;
+ foreach (Xex a in args)
+ str += " " + a;
+ str += ")";
+ }
}
}
internal void Bind (Variable vari, object value)
{
bindings = Bindings.Bind (bindings, vari, value);
+ Console.WriteLine ("binding " + vari);
}
internal void UnboundTo (Bindings boundary)
bindings = bindings.UnboundTo (boundary);
}
- public void Defun (Name name, Builtin builtin, int min_arg, int max_arg)
+ public void DefSubr (Builtin builtin, string str,
+ int min_arg, int max_arg)
{
- Defun (name, builtin, min_arg, max_arg, false);
+ Name name = str;
+ functions[name]
+ = new Function.Subroutine (builtin, name, min_arg, max_arg);
}
- public void Defun (Name name, Builtin builtin,
- int min_arg, int max_arg, bool specialp)
+ public void DefSpecial (Builtin builtin, string str,
+ int min_arg, int max_arg)
{
- Function func;
-
- if (functions.TryGetValue (name, out func))
- {
- if (func.min_arg < min_arg || func.max_arg > max_arg)
- throw new Exception ("Incompatible argument numbers to override: "
- + name);
- func.builtin = builtin;
- func.lambda = null;
- func.min_arg = min_arg;
- func.max_arg = max_arg;
- func.specialp = specialp;
- }
- else
- {
- functions[name]
- = new Function (name, builtin, min_arg, max_arg, specialp);
- }
+ Name name = str;
+ functions[name]
+ = new Function.SpecialForm (builtin, name, min_arg, max_arg);
}
- internal Function RegisterFunction (XmlNode node)
+ internal Function.Lambda RegisterFunction (XmlNode node)
{
int min_arg, max_arg;
Name name = Function.ParseHead (node, out min_arg, out max_arg);
- Function func = new Function (name, min_arg, max_arg);
+ Lambda lambda = new Function.Lambda (name, min_arg, max_arg);
- functions[name] = func;
+ functions[name] = lambda;
return func;
}
internal Function Defun (XmlNode node)
{
Name name = node.Attributes[Nfname].Value;
- Function func;
+ Function.Lambda lambda;
- if (! functions.TryGetValue (name, out func))
- func = RegisterFunction (node);
- func.Setup (node, this);
+ if (! functions.TryGetValue (name, out lambda))
+ lambda = RegisterFunction (node);
+ lambda.Setup (node, this);
return func;
}
if (node.Name == Ndescription)
node = node.NextSibling;
- if (node.Name == Nconst)
+ if (node != null)
{
- Name type = (Name) node.Attributes[Ntype].Value;
+ Name type = node.Name;
string val = node.Value;
XmlNodeList range_list = null;
int nranges = 0;
node = node.NextSibling;
- if (node.Name == Npossible_value)
+ if (node != null)
{
range_list = node.ChildNodes;
nranges = range_list.Count;
{
XmlNode n = range_list[i];
- if (n.Name == Nconst)
- {
- int num = parse_integer (n.Value);
- vi.ranges[i].from = vi.ranges[i].to = num;
- }
- else // range_list[i].Name == "range"
+ if (n.Name == Nrange)
{
vi.ranges[i].from =
parse_integer (n.FirstChild.Value);
vi.ranges[i].to =
parse_integer (n.LastChild.Value);
}
+ else
+ {
+ int num = parse_integer (n.Value);
+ vi.ranges[i].from = vi.ranges[i].to = num;
+ }
}
}
vari = vi;
static Xex ()
{
- basic.Defun ("set", set_value, 2, 2, false);
- basic.Defun ("=", set_value, 2, 2, false);
- basic.Defun ("and", and, 1, -1, false);
- basic.Defun ("&&", and, 1, -1, false);
- basic.Defun ("or", or, 1, -1, false);
- basic.Defun ("||", or, 1, -1, false);
- basic.Defun ("not", not, 1, 1, false);
- basic.Defun ("!", not, 1, 1, false);
- basic.Defun ("add", add, 2, -1, false);
- basic.Defun ("+", add, 2, -1, false);
- basic.Defun ("mul", mul, 2, -1, false);
- basic.Defun ("*", mul, 2, -1, false);
- basic.Defun ("sub", sub, 1, -1, false);
- basic.Defun ("-", sub, 1, -1, false);
- basic.Defun ("div", div, 2, -1, false);
- basic.Defun ("/", div, 2, -1, false);
- basic.Defun ("mod", mod, 2, 2, false);
- basic.Defun ("%", mod, 2, 2, false);
- basic.Defun ("logior", logior, 2, -1, false);
- basic.Defun ("|", logior, 2, -1, false);
- basic.Defun ("logand", logand, 2, -1, false);
- basic.Defun ("&", logand, 2, -1, false);
- basic.Defun ("add-set", add_set, 2, -1, true);
- basic.Defun ("+=", add_set, 2, -1, true);
- basic.Defun ("mul-set", mul_set, 2, -1, true);
- basic.Defun ("*=", mul_set, 2, -1, true);
- basic.Defun ("sub-set", sub_set, 2, -1, true);
- basic.Defun ("-=", sub_set, 2, -1, true);
- basic.Defun ("div-set", div_set, 2, -1, true);
- basic.Defun ("/=", div_set, 2, -1, true);
- basic.Defun ("mod-set", mod_set, 2, 2, true);
- basic.Defun ("%=", mod_set, 2, 2, true);
- basic.Defun ("logior-set", logior_set, 2, -1, true);
- basic.Defun ("|=", logior_set, 2, -1, true);
- basic.Defun ("logand-set", logand_set, 2, -1, true);
- basic.Defun ("&=", logand_set, 2, -1, true);
- basic.Defun ("lsh", lsh, 2, 2, false);
- basic.Defun ("<<", lsh, 2, 2, false);
- basic.Defun ("rsh", rsh, 2, 2, false);
- basic.Defun (">>", rsh, 2, 2, false);
- basic.Defun ("lsh-set", lsh_set, 2, 2, true);
- basic.Defun ("<<=", lsh_set, 2, 2, true);
- basic.Defun ("rsh-set", rsh_set, 2, 2, true);
- basic.Defun (">>=", rsh_set, 2, 2, true);
- basic.Defun ("eq", eq, 2, -1, false);
- basic.Defun ("==", eq, 2, -1, false);
- basic.Defun ("noteq", noteq, 2, 2, false);
- basic.Defun ("!=", noteq, 2, 2, false);
- basic.Defun ("lt", less_than, 2, -1, false);
- basic.Defun ("<", less_than, 2, -1, false);
- basic.Defun ("le", less_eq, 2, -1, false);
- basic.Defun ("<=", less_eq, 2, -1, false);
- basic.Defun ("gt", greater_than, 2, -1, false);
- basic.Defun (">", greater_than, 2, -1, false);
- basic.Defun ("ge", greater_eq, 2, -1, false);
- basic.Defun (">=", greater_eq, 2, -1, false);
- basic.Defun ("eval", eval_clause, 1, 1, true);
- basic.Defun ("progn", progn_clause, 0, -1, true);
- basic.Defun ("expr", progn_clause, 0, -1, true);
- basic.Defun ("if", if_clause, 2, -1, true);
- basic.Defun ("when", when_clause, 1, -1, true);
- basic.Defun ("while", while_clause, 1, -1, true);
+ basic.DefSubr (set_value, "set", 2, 2);
+ basic.DefSubr (set_value, "=", 2, 2);
+ basic.DefSubr (and, "and", 1, -1);
+ basic.DefSubr (and, "&&", 1, -1);
+ basic.DefSubr (or, "or", 1, -1);
+ basic.DefSubr (or, "||", 1, -1);
+ basic.DefSubr (not, "not", 1, 1);
+ basic.DefSubr (not, "!", 1, 1);
+ basic.DefSubr (add, "add", 2, -1);
+ basic.DefSubr (add, "+", 2, -1);
+ basic.DefSubr (mul, "mul", 2, -1);
+ basic.DefSubr (mul, "*", 2, -1);
+ basic.DefSubr (sub, "sub", 1, -1);
+ basic.DefSubr (sub, "-", 1, -1);
+ basic.DefSubr (div, "div", 2, -1);
+ basic.DefSubr (div, "/", 2, -1);
+ basic.DefSubr (mod, "mod", 2, 2);
+ basic.DefSubr (mod, "%", 2, 2);
+ basic.DefSubr (logior, "logior", 2, -1);
+ basic.DefSubr (logior, "|", 2, -1);
+ basic.DefSubr (logand, "logand", 2, -1);
+ basic.DefSubr (logand, "&", 2, -1);
+ basic.DefSubr (add_set, "add-set", 2, -1);
+ basic.DefSubr (add_set, "+=", 2, -1);
+ basic.DefSubr (mul_set, "mul-set", 2, -1);
+ basic.DefSubr (mul_set, "*=", 2, -1);
+ basic.DefSubr (sub_set, "sub-set", 2, -1);
+ basic.DefSubr (sub_set, "-=", 2, -1);
+ basic.DefSubr (div_set, "div-set", 2, -1);
+ basic.DefSubr (div_set, "/=", 2, -1);
+ basic.DefSubr (mod_set, "mod-set", 2, 2);
+ basic.DefSubr (mod_set, "%=", 2, 2);
+ basic.DefSubr (logior_set, "logior-set", 2, -1);
+ basic.DefSubr (logior_set, "|=", 2, -1);
+ basic.DefSubr (logand_set, "logand-set", 2, -1);
+ basic.DefSubr (logand_set, "&=", 2, -1);
+ basic.DefSubr (lsh, "lsh", 2, 2);
+ basic.DefSubr (lsh, "<<", 2, 2);
+ basic.DefSubr (rsh, "rsh", 2, 2);
+ basic.DefSubr (rsh, ">>", 2, 2);
+ basic.DefSubr (lsh_set, "lsh-set", 2, 2);
+ basic.DefSubr (lsh_set, "<<=", 2, 2);
+ basic.DefSubr (rsh_set, "rsh-set", 2, 2);
+ basic.DefSubr (rsh_set, ">>=", 2, 2);
+ basic.DefSubr (eq, "eq", 2, -1);
+ basic.DefSubr (eq, "==", 2, -1);
+ basic.DefSubr (noteq, "noteq", 2, 2);
+ basic.DefSubr (noteq, "!=", 2, 2);
+ basic.DefSubr (less_than, "lt", 2, -1);
+ basic.DefSubr (less_than, "<", 2, -1);
+ basic.DefSubr (less_eq, "le", 2, -1);
+ basic.DefSubr (less_eq, "<=", 2, -1);
+ basic.DefSubr (greater_than, "gt", 2, -1);
+ basic.DefSubr (greater_than, ">", 2, -1);
+ basic.DefSubr (greater_eq, "ge", 2, -1);
+ basic.DefSubr (greater_eq, ">=", 2, -1);
+ basic.DefSubr (eval_clause, "eval", 1, 1);
+ basic.DefSpecial (progn_clause, "progn", 0, -1);
+ basic.DefSpecial (progn_clause, "expr", 0, -1);
+ basic.DefSpecial (if_clause, "if", 2, -1);
+ basic.DefSpecial (when_clause, "when", 1, -1);
+ basic.DefSpecial (while_clause, "while", 1, -1);
Fprogn = basic.GetFunc (Nprogn);
}
// VARREF: function == null, args[0] = DIRECT-SYMBOL
// DIRECT: function == null, args == null
- private Function function;
- private Xex[] args;
private object val;
-
- public Xex[] Args { get { return args; } }
+ public abstract object Eval (Domain domain);
public object Val { get { return val; } }
- private Xex () { }
+ private class Funcall : Xex
+ {
+ internal Function func;
+ internal Xex[] args;
+
+ public Funcall (Function func, Xex[] args)
+ {
+ this.func = func;
+ this.args = args;
+ }
- private Xex (object val)
+ public override object Eval (Domain domain)
+ {
+ val = func.Call (args, domain);
+ return val;
+ }
+
+ public override string ToString ()
+ {
+ string str = "(" + func.name;
+ if (args != null)
+ foreach (Xex e in args)
+ str += " " + e.ToString ();
+ return (str + ")");
+ }
+ }
+
+ private class Varref : Xex
{
- this.val = val;
+ internal Variable vari;
+
+ public Varref (Variable vari)
+ {
+ this.vari = vari;
+ }
+
+ public override object Eval (Domain domain)
+ {
+ val = vari.val;
+ return val;
+ }
+
+ public override string ToString ()
+ {
+ return "$" + vari.name + "/" + vari.val;
+ }
+ }
+
+ private class Const : Xex
+ {
+ public Const (object val)
+ {
+ this.val = val;
+ }
+
+ public override object Eval (Domain domain)
+ {
+ return val;
+ }
+
+ public override string ToString ()
+ {
+ return val.ToString ();
+ }
}
internal static int parse_integer (string str)
return negative ? - i : i;
}
- private int pre_parse (XmlNodeList nlist, Domain domain)
+ private static int pre_parse (XmlNodeList nlist, Domain domain)
{
int len = 0;
foreach (XmlNode node in nlist)
return len;
}
- private void post_parse (XmlNodeList nlist, Domain domain)
+ private static void post_parse (XmlNodeList nlist, Xex[] args,
+ Domain domain)
{
for (int i = 0, j = 0; i < nlist.Count; i++)
{
if (node.Name == Ndefun)
domain.Defun (node);
else if (node.Name != Ndefvar)
- args[j++] = new Xex (node, domain);
+ args[j++] = New (node, domain);
}
}
- private void Setup (XmlNode node, Domain domain)
- {
- Name name = node.Name;
-
- if (name == Nconst)
- {
- Name type = node.Attributes[Ntype].Value;
-
- if (type == Ninteger)
- val = parse_integer (node.InnerText);
- else if (type == Nstring)
- val = node.InnerText;
- else if (type == Nsymbol)
- val = (Name) node.InnerText;
- else if (type == Nboolean)
- val = node.InnerText == "true";
- else if (type == Nlist)
- {
- List<Xex> list = new List<Xex> ();
- for (XmlNode n = node.FirstChild; n != null; n = n.NextSibling)
- list.Add (new Xex (n, domain));
- val = list;
- }
- else
- throw new Exception ("Unknown type: " + type);
- }
- else if (name == Nvariable)
- {
- args = new Xex[1];
- args[0] = new Xex ((Name) node.Attributes[0].Value);
- }
- else
- {
- if (name == Nfuncall)
- name = node.Attributes[0].Value;
- function = domain.GetFunc (name);
-
- XmlNodeList nlist = node.ChildNodes;
- int nargs = nlist.Count;
-
- if (nargs < function.min_arg
- || (function.max_arg >= 0 && nargs > function.max_arg))
- throw new Exception ("Invalid number of arguments to: "
- + name + " " + nargs);
- nargs = pre_parse (nlist, domain);
- args = new Xex[nargs];
- post_parse (nlist, domain);
- }
- }
-
- public Xex (string url, Domain domain)
+ public static Xex New (string url, Domain domain)
{
XmlDocument doc = new XmlDocument (Name.Table);
XmlNode node;
node = doc.ReadNode (reader);
}
- Setup (node, domain);
+ return New (node, domain);
}
// EXPR = SYMBOL | MTEXT | INTEGER | FUNCALL | PROGN
// FUNCALL = '(' SYMBOL EXPR* ')'
// PROGN = '(' EXPR * ')'
- public Xex (XmlNode node, Domain domain)
+ public static Xex New (XmlNode node, Domain domain)
{
- Setup (node, domain);
- }
-
- public object Eval (Domain domain)
- {
- if (function == null)
- {
- if (args != null)
- {
- Variable vari = domain.GetVar ((Name) args[0].val);
- val = vari.val;
- }
- return val;
- }
- else
- val = function.Call (args, domain);
- return val;
- }
-
- public override string ToString ()
- {
- string str;
-
- if (function != null)
+ Name name = node.Name;
+ Xex xex;
+ if (name == Nvariable)
{
- str = "(" + function.name;
- if (args != null)
- foreach (Xex e in args)
- str += " " + e.ToString ();
- str += ")";
+ Variable vari = domain.GetVar ((Name) node.Attributes[0].Value);
+ xex = new Xex.Varref (vari);
}
- else if (args != null)
+ else if (name == Ninteger)
+ xex = new Xex.Const (parse_integer (node.InnerText));
+ else if (name == Nstring)
+ xex = new Xex.Const (node.InnerText);
+ else if (name == Nsymbol)
+ xex = new Xex.Const ((Name) node.InnerText);
+ else if (name == Nboolean)
+ xex = new Xex.Const (node.InnerText == "true");
+ else if (name == Nlist)
{
- str = (Name) args[0].val;
+ List<Xex> list = new List<Xex> ();
+ for (XmlNode n = node.FirstChild; n != null; n = n.NextSibling)
+ list.Add (New (n, domain));
+ xex = new Xex.Const (list);
}
- else if (val != null)
+ else
{
- if (val is string)
- str = "\"" + ((string) val) + "\"";
- else
- str = val.ToString ();
+ if (name == Nfuncall)
+ name = node.Attributes[0].Value;
+ Function func = domain.GetFunc (name);
+
+ XmlNodeList nlist = node.ChildNodes;
+ int nargs = nlist.Count;
+
+ if (nargs < func.min_arg
+ || (func.max_arg >= 0 && nargs > func.max_arg))
+ throw new Exception ("Invalid number of arguments to: "
+ + name + " " + nargs);
+ nargs = pre_parse (nlist, domain);
+ Xex[] args = new Xex[nargs];
+ post_parse (nlist, args, domain);
+ xex = new Xex.Funcall (func, args);
}
- else
- str = "()";
- return str;
+ return xex;
}
}
}