From: handa Date: Thu, 17 Sep 2009 08:54:28 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2071d76a521f876a44893bb3a3e7447c4ff1b0f9;p=m17n%2Fm17n-lib-cs.git *** empty log message *** --- diff --git a/XmlExpr.cs b/XmlExpr.cs index 947d326..ee82b94 100644 --- a/XmlExpr.cs +++ b/XmlExpr.cs @@ -6,9 +6,9 @@ using System.Xml; namespace System.Xml.Expression { - public abstract class Xex + public class Xexpression { - public static bool Debug = false; + public static int debug_level = 0; public struct Name : IEquatable { @@ -87,10 +87,8 @@ namespace System.Xml.Expression private static Name Nvariable = "variable"; private static Name Ninteger = "integer"; private static Name Nstring = "string"; - private static Name Nboolean = "boolean"; private static Name Nsymbol = "symbol"; private static Name Nlist = "list"; - private static Name Nobject = "object"; private static Name Ndefun = "defun"; private static Name Nfname = "fname"; @@ -120,7 +118,7 @@ namespace System.Xml.Expression this.max_arg = max_arg; } - public abstract object Call (object[] args, Domain domain); + public abstract Term Call (Domain domain, Term[] args); public override string ToString () { @@ -138,21 +136,13 @@ namespace System.Xml.Expression this.builtin = builtin; } - public override object Call (object[] args, Domain domain) + public override Term Call (Domain domain, Term[] args) { - object result; + Term[] newargs = new Term[args.Length]; for (int i = 0; i < args.Length; i++) - { - object val = args[i]; - if (val is Xex) - val = ((Xex) val).Eval (domain); - if (val == null) - throw new Exception (args[i] + ":evaled to null"); - args[i] = val; - } - result = builtin (args, domain); - return result; + newargs[i] = args[i].Eval (domain); + return builtin (domain, newargs); } } @@ -167,17 +157,17 @@ namespace System.Xml.Expression this.builtin = builtin; } - public override object Call (object[] args, Domain domain) + public override Term Call (Domain domain, Term[] args) { - return builtin (args, domain); + return builtin (domain, args); } } internal class Lambda : Function { internal bool args_evalled; - internal Name[] args; - internal Xex[] body; + internal Term[] args; + internal Term[] body; public Lambda (XmlNode node) { @@ -207,13 +197,13 @@ namespace System.Xml.Expression nrest++; min_arg = nargs; max_arg = nargs + noptions + nrest; - if (nrest == 1) - max_arg = - max_arg; - args = new Name[max_arg]; + args = new Term[max_arg]; n = node.FirstChild; for (int i = 0; i < max_arg; n = n.NextSibling) if (n.Name == Nsymbol) - args[i++] = n.InnerText; + args[i++] = new Term (n, null); + if (nrest == 1) + max_arg = - max_arg; } else { @@ -230,60 +220,54 @@ namespace System.Xml.Expression { XmlNodeList nlist = node.ChildNodes; - body = new Xex[nlist.Count]; + body = new Term[nlist.Count]; for (int i = 0; i < nlist.Count; i++) - body[i] = New (nlist[i], domain); + body[i] = new Term (nlist[i], domain); } } - public override object Call (object[] args, Domain domain) + public override Term Call (Domain domain, Term[] args) { Bindings current = domain.bindings; - object result = false; + Term result = Zero; try { int i; if (args_evalled) - for (i = 0; i < min_arg; i++) - args[i] = ((Xex) args[i]).Eval (domain); + { + Term[] newargs = new Term[args.Length]; + for (i = 0; i < min_arg; i++) + newargs[i] = args[i].Eval (domain); + args = newargs; + } for (i = 0; i < min_arg; i++) { - Variable var = domain.GetVar (this.args[i]); + Variable var = domain.GetVar ((Name) this.args[i]); domain.Bind (var, args[i]); } - foreach (Xex e in body) - result = e.Eval (domain); + if (body != null) + foreach (Term term in body) + result = term.Eval (domain); } finally { domain.UnboundTo (current); } return result; } - - public override string ToString () - { - string str = "(" + name; - foreach (Name a in args) - str += " " + a; - return (str + ")"); - } } } internal abstract class Variable { public readonly Name name; - public readonly Name type; - internal object val; + internal Term val; - public Variable (Name name, Name type, object value) + public Variable (Name name, Term term) { - if (value != null) - Value = value; this.name = name; - this.type = type; + Value = term; } - public object Value + public Term Value { get { return val; } set @@ -294,87 +278,69 @@ namespace System.Xml.Expression } } - public abstract bool ValueP (object value); + public abstract bool ValueP (Term term); public override string ToString () { return name + "(" + val + ")"; } - } - internal class VarInt : Variable - { - public struct Range + internal class Int : Variable { - public int from, to; - } + public struct Range + { + public int from, to; + } - public Range[] ranges; + public Range[] ranges; - public VarInt (Name name, object value) : base (name, Ninteger, value) { } + public Int (Name name, int i) : base (name, new Term (i)) { } - public override bool ValueP (object value) - { - int i; + public override bool ValueP (Term term) + { + int i; - if (! (value is int)) - return false; - if (ranges == null) - return true; - i = (int) value; - foreach (Range r in ranges) - if (i >= r.from && i <= r.to) + if (term.objval != null) + return false; + if (ranges == null) return true; - return false; + i = term.intval; + foreach (Range r in ranges) + if (i >= r.from && i <= r.to) + return true; + return false; + } } - } - - internal class VarStr : Variable - { - public string[] ranges; - - public VarStr (Name name, object value) : base (name, Nstring, value) { } - public override bool ValueP (object value) + internal class Str : Variable { - string str; - - if (! (value is string)) - return false; - if (ranges == null) - return true; - str = (string) value; - foreach (string s in ranges) - if (s == str) - return true; - return false; - } - } + public string[] ranges; - internal class VarBool : Variable - { - public VarBool (Name name, object value) - : base (name, Nboolean, value) { } + public Str (Name name, string str) : base (name, new Term (str)) { } - public override bool ValueP (object value) - { - if (! (value is bool)) + public override bool ValueP (Term term) + { + if (! (term.objval is string)) + return false; + if (ranges == null) + return true; + string str = (string) term.objval; + foreach (string s in ranges) + if (s == str) + return true; return false; - return true; + } } - } - internal class VarMisc : Variable - { - public VarMisc (Name name, object value) : base (name, Nobject, value) { } - - public override bool ValueP (object value) + internal class Misc : Variable { - return true; + public Misc (Name name, Term term) : base (name, term) { } + + public override bool ValueP (Term term) { return true; } } } internal class Bindings { private Variable vari; - private object old_value; + private Term old_value; private Bindings next; private Bindings (Variable vari) @@ -383,12 +349,11 @@ namespace System.Xml.Expression old_value = vari.val; } - public static Bindings Bind (Bindings bindings, - Variable vari, object value) + public static Bindings Bind (Bindings bindings, Variable vari, Term val) { Bindings b = new Bindings (vari); - b.vari.Value = value; + b.vari.Value = val; b.next = bindings; return b; } @@ -449,7 +414,7 @@ namespace System.Xml.Expression this.context = context; } - internal void Bind (Variable vari, object value) + internal void Bind (Variable vari, Term value) { bindings = Bindings.Bind (bindings, vari, value); } @@ -495,10 +460,12 @@ namespace System.Xml.Expression return func; } - public void Defvar (Name name, XmlNode node) + public void Defvar (XmlNode node) { + Name name = node.Attributes[0].Value; Variable vari; + node = node.FirstChild; if (node.Name == Ndescription) node = node.NextSibling; if (node != null) @@ -517,10 +484,10 @@ namespace System.Xml.Expression if (type == Ninteger) { - VarInt vi = new VarInt (name, parse_integer (val)); + Variable.Int vi = new Variable.Int (name, parse_integer (val)); if (range_list != null) { - vi.ranges = new VarInt.Range[nranges]; + vi.ranges = new Variable.Int.Range[nranges]; for (int i = 0; i < nranges; i++) { @@ -544,22 +511,18 @@ namespace System.Xml.Expression } else if (type == Nstring) { - VarStr vs = new VarStr (name, val); + Variable.Str vs = new Variable.Str (name, val); if (range_list != null) vs.ranges = new string[nranges]; for (int i = 0; i < nranges; i++) vs.ranges[i] = range_list[i].Value; vari = vs; } - else if (type == Nboolean) - { - vari = new VarBool (name, val == "true"); - } else throw new Exception ("Unknown type: " + type); } else - vari = new VarMisc (name, null); + vari = new Variable.Misc (name, Zero); variables[name] = vari; } @@ -591,7 +554,7 @@ namespace System.Xml.Expression Variable vari; if (! variables.TryGetValue (name, out vari)) - variables[name] = vari = new VarMisc (name, null); + variables[name] = vari = new Variable.Misc (name, Zero); return vari; } @@ -612,9 +575,9 @@ namespace System.Xml.Expression return str; } - public void DebugWrite (bool head, string fmt, params object[] arg) + public void DebugWrite (bool head, string fmt, params string[] arg) { - if (Debug) + if (debug_level > depth) { if (head) { @@ -627,13 +590,13 @@ namespace System.Xml.Expression } } - public delegate object Builtin (object[] args, Domain domain); + public delegate Term Builtin (Domain domain, Term[] args); private static Domain basic = new Domain (); internal static Function Fprogn; - static Xex () + static Xexpression () { basic.DefSubr (set_value, "set", 2, 2); basic.DefSubr (set_value, "=", 2, 2); @@ -691,6 +654,9 @@ namespace System.Xml.Expression basic.DefSubr (greater_than, ">", 2, -1); basic.DefSubr (greater_eq, "ge", 2, -1); basic.DefSubr (greater_eq, ">=", 2, -1); + basic.DefSubr (copy, "copy", 1, 1); + basic.DefSubr (append, "append", 1, -1); + basic.DefSpecial (quote_clause, "quote", 1, 1); basic.DefSubr (eval_clause, "eval", 1, 1); basic.DefSpecial (progn_clause, "progn", 0, -1); basic.DefSpecial (progn_clause, "expr", 0, -1); @@ -701,14 +667,7 @@ namespace System.Xml.Expression Fprogn = basic.GetFunc (Nprogn); } - private static bool is_true (object val) - { - return (val is bool ? (bool) val - : val is int ? (int) val == 0 - : true); - } - - private static object set_value (object[] args, Domain domain) + private static Term set_value (Domain domain, Term[] args) { Variable vari = domain.GetVar ((Name) args[0]); @@ -716,44 +675,44 @@ namespace System.Xml.Expression return vari.val; } - private static object and (object[] args, Domain domain) + private static Term and (Domain domain, Term[] args) { - foreach (object arg in args) - if (! is_true (((Xex) arg).Eval (domain))) - return false; - return true; + foreach (Term arg in args) + if (! arg.Eval (domain).IsTrue) + return Zero; + return One; } - private static object or (object[] args, Domain domain) + private static Term or (Domain domain, Term[] args) { - foreach (object arg in args) - if (is_true (((Xex) arg).Eval (domain))) - return true; - return false; + foreach (Term arg in args) + if (arg.Eval (domain).IsTrue) + return One; + return Zero; } - private static object not (object[] args, Domain domain) + private static Term not (Domain domain, Term[] args) { - return ! is_true (args); + return args[0].IsTrue ? Zero : One; } - private static object add (object[] args, Domain domain) + private static Term add (Domain domain, Term[] args) { int n = 0; - foreach (object arg in args) + foreach (Term arg in args) n += (int) arg; return n; } - private static object mul (object[] args, Domain domain) + private static Term mul (Domain domain, Term[] args) { int n = 1; - foreach (object arg in args) + foreach (Term arg in args) n *= (int) arg; return n; } - private static object sub (object[] args, Domain domain) + private static Term sub (Domain domain, Term[] args) { int n = (int) args[0]; if (args.Length == 1) @@ -763,7 +722,7 @@ namespace System.Xml.Expression return n; } - private static object div (object[] args, Domain domain) + private static Term div (Domain domain, Term[] args) { int n = (int) args[0]; for (int i = 1; i < args.Length; i++) @@ -771,20 +730,20 @@ namespace System.Xml.Expression return n; } - private static object mod (object[] args, Domain domain) + private static Term mod (Domain domain, Term[] args) { return ((int) args[0] % (int) args[1]); } - private static object logior (object[] args, Domain domain) + private static Term logior (Domain domain, Term[] args) { int n = 0; - foreach (object arg in args) + foreach (Term arg in args) n |= (int) arg; return n; } - private static object logand (object[] args, Domain domain) + private static Term logand (Domain domain, Term[] args) { int n = (int) args[0]; for (int i = 1; i < args.Length; i++) @@ -792,129 +751,138 @@ namespace System.Xml.Expression return n; } - private static object add_set (object[] args, Domain domain) + private static Term add_set (Domain domain, Term[] args) { - Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val); + Variable vari = domain.GetVar ((Name) args[0]); int n = (int) vari.val; for (int i = 1; i < args.Length; i++) n += (int) args[i]; vari.val = n; - return n; + return vari.val; } - private static object mul_set (object[] args, Domain domain) + private static Term mul_set (Domain domain, Term[] args) { - Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val); + Variable vari = domain.GetVar ((Name) args[0]); int n = (int) vari.val; for (int i = 1; i < args.Length; i++) n *= (int) args[i]; vari.val = n; - return n; + return vari.val; } - private static object sub_set (object[] args, Domain domain) + private static Term sub_set (Domain domain, Term[] args) { - Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val); + Variable vari = domain.GetVar ((Name) args[0]); int n = (int) vari.val; for (int i = 1; i < args.Length; i++) n -= (int) args[i]; vari.val = n; - return n; + return vari.val; } - private static object div_set (object[] args, Domain domain) + private static Term div_set (Domain domain, Term[] args) { - Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val); + Variable vari = domain.GetVar ((Name) args[0]); int n = (int) vari.val; for (int i = 1; i < args.Length; i++) n /= (int) args[i]; vari.val = n; - return n; + return vari.val; } - private static object mod_set (object[] args, Domain domain) + private static Term mod_set (Domain domain, Term[] args) { - Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val); + Variable vari = domain.GetVar ((Name) args[0]); int n = (int) vari.val; for (int i = 1; i < args.Length; i++) n %= (int) args[i]; vari.val = n; - return n; + return vari.val; } - private static object logior_set (object[] args, Domain domain) + private static Term logior_set (Domain domain, Term[] args) { - Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val); + Variable vari = domain.GetVar ((Name) args[0]); int n = (int) vari.val; for (int i = 1; i < args.Length; i++) n |= (int) args[i]; vari.val = n; - return n; + return vari.val; } - private static object logand_set (object[] args, Domain domain) + private static Term logand_set (Domain domain, Term[] args) { - Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val); + Variable vari = domain.GetVar ((Name) args[0]); int n = (int) vari.val; for (int i = 1; i < args.Length; i++) n &= (int) args[i]; vari.val = n; - return n; + return vari.val; } - private static object lsh (object[] args, Domain domain) + private static Term lsh (Domain domain, Term[] args) { return (int) args[0] << (int) args[1]; } - private static object lsh_set (object[] args, Domain domain) + private static Term lsh_set (Domain domain, Term[] args) { - Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val); + Variable vari = domain.GetVar ((Name) args[0]); int n = (int) vari.val; n <<= (int) args[1]; vari.val = n; - return n; + return vari.val; } - private static object rsh (object[] args, Domain domain) + private static Term rsh (Domain domain, Term[] args) { return (int) args[0] >> (int) args[1]; } - private static object rsh_set (object[] args, Domain domain) + private static Term rsh_set (Domain domain, Term[] args) { - Variable vari = domain.GetVar ((Name) ((Xex.Const) args[0]).val); + Variable vari = domain.GetVar ((Name) args[0]); int n = (int) vari.val; n >>= (int) args[1]; vari.val = n; - return n; + return vari.val; } - private static object eq (object[] args, Domain domain) + private static Term eq (Domain domain, Term[] args) { - object o = args[0]; + Term o = args[0]; - for (int i = 1; i < args.Length; i++) - if (o != args[i]) - return false; - return true; + if (o.objval == null) + { + for (int i = 1; i < args.Length; i++) + if (args[i].objval != null || args[i].intval != o.intval) + return Zero; + } + else + { + for (int i = 1; i < args.Length; i++) + if (o.objval.Equals (args[i].objval)) + return Zero; + } + return One; } - private static object noteq (object[] args, Domain domain) + private static Term noteq (Domain domain, Term[] args) { - return (args[0] != args[1]); + return eq (domain, args); } - private static object less_than (object[] args, Domain domain) + private static Term less_than (Domain domain, Term[] args) { int n = (int) args[0]; @@ -922,189 +890,293 @@ namespace System.Xml.Expression { int n1 = (int) args[i]; if (n >= n1) - return false; + return Zero; n = n1; } - return true; + return One; } - private static object less_eq (object[] args, Domain domain) + private static Term less_eq (Domain domain, Term[] args) { int n = (int) args[0]; for (int i = 1; i < args.Length; i++) { int n1 = (int) args[i]; if (n > n1) - return false; + return Zero; n = n1; } - return true; + return One; } - private static object greater_than (object[] args, Domain domain) + private static Term greater_than (Domain domain, Term[] args) { int n = (int) args[0]; for (int i = 1; i < args.Length; i++) { int n1 = (int) args[i]; if (n <= n1) - return false; + return Zero; n = n1; } - return true; + return One; } - private static object greater_eq (object[] args, Domain domain) + private static Term greater_eq (Domain domain, Term[] args) { int n = (int) args[0]; for (int i = 1; i < args.Length; i++) { int n1 = (int) args[i]; if (n < n1) - return false; + return Zero; n = n1; } - return true; + return One; + } + + private static Term copy (Domain domain, Term[] args) + { + object obj = args[0].objval; + + if (! (obj is List)) + throw new Exception ("Invalid arg to copy: " + args[0]); + return new Term (new List ((List) obj)); + } + + private static Term append (Domain domain, Term[] args) + { + object obj = args[0].objval; + if (obj is string) + { + string str = ""; + foreach (Term arg in args) + str += arg; + return new Term (str); + } + else if (obj is List) + { + List list = new List (); + foreach (Term arg in args) + list.AddRange ((List) arg.objval); + return new Term (list); + } + throw new Exception ("Invalid term to append: " + obj); + } + + private static Term quote_clause (Domain domain, Term[] args) + { + return new Term (args[0]); } - private static object eval_clause (object[] args, Domain domain) + private static Term eval_clause (Domain domain, Term[] args) { - return ((Xex) args[0]).Eval (domain); + return (args[0].Eval (domain)); } - private static object progn_clause (object[] args, Domain domain) + private static Term progn_clause (Domain domain, Term[] args) { - object result = true; + Term result = One; - foreach (object arg in args) - result = ((Xex) arg).Eval (domain); + foreach (Term arg in args) + result = arg.Eval (domain); return result; } - private static object if_clause (object[] args, Domain domain) + private static Term if_clause (Domain domain, Term[] args) { - object result; + if (args[0].Eval (domain).IsTrue) + return args[1].Eval (domain); - if (is_true (((Xex) args[0]).Eval (domain))) - result = ((Xex) args[1]).Eval (domain); - else - { - result = false; - for (int i = 2; i < args.Length; i++) - result = ((Xex) args[i]).Eval (domain); - } + Term result = Zero; + for (int i = 2; i < args.Length; i++) + result = args[i].Eval (domain); return result; } - private static object when_clause (object[] args, Domain domain) + private static Term when_clause (Domain domain, Term[] args) { - if (! is_true (((Xex) args[0]).Eval (domain))) - return false; + if (! args[0].Eval (domain).IsTrue) + return Zero; - object result = true; + Term result = One; for (int i = 1; i < args.Length; i++) - result = ((Xex) args[i]).Eval (domain); + result = args[i].Eval (domain); return result; } - private static object while_clause (object[] args, Domain domain) + private static Term while_clause (Domain domain, Term[] args) { - while (is_true (((Xex) args[0]).Eval (domain))) + while (args[0].Eval (domain).IsTrue) for (int i = 1; i < args.Length; i++) - ((Xex) args[i]).Eval (domain); - return false; + args[i].Eval (domain); + return Zero; } - public abstract object Eval (Domain domain); - public abstract Name TypeOf { get; } - - private class Funcall : Xex + public struct Term { - internal Function func; - internal Xex[] args; - internal object[] real_args; + public int intval; + public object objval; + + public Term (int i) { intval = i; objval = null; } + public Term (Name name) { intval = 0; objval = name; } + public Term (string str) { intval = 0; objval = str; } + public Term (List list) { intval = 0; objval = list; } + public Term (Term term) { intval = 0; objval = term; } + + public Term (XmlNode node, Domain domain) + { + Name name = node.Name; - public Funcall (Function func, Xex[] args) + if (name == Ninteger) + { + intval = parse_integer (node.InnerText); + objval = null; + } + else + { + intval = 0; + if (name == Nsymbol) + objval = (Name) node.InnerText; + else if (name == Nstring) + objval = node.InnerText.Clone (); + else if (name == Nvariable) + objval = domain.GetVar ((Name) node.Attributes[0].Value); + else if (name == Nlist) + { + List list = new List (); + for (node = node.FirstChild; node != null; + node = node.NextSibling) + list.Add (new Term (node, domain)); + objval = list; + } + else + { + 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); + Term[] args = new Term[nargs]; + for (int i = 0; i < nlist.Count; i++) + args[i] = new Term (nlist[i], domain); + objval = new Funcall (func, args); + } + } + } + + private class Funcall + { + internal Function func; + internal Term[] args; + + public Funcall (Function func, Term[] args) { this.func = func; this.args = args; - real_args = new object[args.Length]; } - public override object Eval (Domain domain) - { - domain.DebugWrite (true, "(({0}", func); - for (int i = 0; i < args.Length; i++) - { - domain.DebugWrite (false, " {0}", args[i]); - real_args[i] = args[i]; - } - domain.DebugWrite (false, ")"); - domain.depth += 2; - object result = func.Call (real_args, domain); - domain.depth -= 2; - domain.DebugWrite (true, " => {0})", result); - return result; + public Term Eval (Domain domain) + { + domain.DebugWrite (true, "(({0}", func.name); + for (int i = 0; i < args.Length; i++) + domain.DebugWrite (false, " {0}", args[i].ToString ()); + domain.DebugWrite (false, ")"); + domain.depth += 2; + Term result = func.Call (domain, args); + domain.depth -= 2; + domain.DebugWrite (true, " => {0})", result.ToString ()); + return result; + } + + public override string ToString () + { + string str = ""; + str += "\">"; + foreach (Term e in args) + str += e; + return (str + ""); + } } - public override Name TypeOf { get { return Nfuncall; } } + public bool IsTrue { + get { + return (objval == null + ? (intval != 0) + : objval is List + ? (((List) objval).Count != 0) + : true); + } + } - public override string ToString () + public Term Eval (Domain domain) { - string str = "(" + func.name; - if (args != null) - foreach (Xex e in args) - str += " " + e.ToString (); - return (str + ")"); + if (objval == null || objval is Name || objval is string) + return this; + if (objval is List) + return new Term ((List) objval); + if (objval is Funcall) + return ((Funcall) objval).Eval (domain); + if (objval is Variable) + return ((Variable) objval).val; + if (objval is Term) + return (Term) objval; + throw new Exception ("invalid Term object: " + objval); } - } - - private class Varref : Xex - { - internal Variable vari; - public Varref (Variable vari) { this.vari = vari; } - - public override object Eval (Domain domain) + public static explicit operator int (Term term) { - domain.DebugWrite (true, "(get-value {0})", vari); - return vari.val; + if (term.objval != null) + throw new Exception ("Not an integer term: " + term); + return term.intval; } - public override Name TypeOf { get { return Nvariable; } } - - public override string ToString () + public static explicit operator Name (Term term) { - return "$" + vari.name + "/" + vari.val; + return (Name) term.objval; } - } - - private class Const : Xex - { - public object val; - - public Const (object val) { this.val = val; } - public override object Eval (Domain domain) + public static implicit operator Term (int i) { - domain.DebugWrite (true, "(const {0})\n", val); - return val; + return new Term (i); } - public override Name TypeOf { - get + public override string ToString () + { + if (objval == null) + return "" + intval + ""; + if (objval is Name) + return "" + objval + ""; + if (objval is string) + return "" + objval + ""; + if (objval is List) { - return (val is int ? Ninteger - : val is string ? Nstring - : val is bool ? Nboolean - : val is Name ? Nsymbol - : Nlist); + string str = ""; + foreach (Term e in (List) objval) + str += e; + return str + ""; } + if (objval is Funcall) + return ""; + if (objval is Variable) + return ""; + if (objval is Term) + return "" + objval + ""; + throw new Exception ("invalid Term object: " + objval); } - - public override string ToString () { return val.ToString (); } } + static Term Zero = new Term (0); + static Term One = new Term (1); + internal static int parse_integer (string str) { int len = str.Length; @@ -1152,36 +1224,9 @@ namespace System.Xml.Expression return negative ? - i : i; } - private static int pre_parse (XmlNodeList nlist, Domain domain) - { - int len = 0; - foreach (XmlNode node in nlist) - { - if (node.Name == Ndefun) - domain.RegisterFunction (node); - else if (node.Name == Ndefvar) - domain.Defvar ((Name) node.Attributes[0].Value, node.FirstChild); - else - len++; - } - return len; - } - - private static void post_parse (XmlNodeList nlist, Xex[] args, - Domain domain) - { - for (int i = 0, j = 0; i < nlist.Count; i++) - { - XmlNode node = nlist[i]; + private Term[] terms; - if (node.Name == Ndefun) - domain.Defun (node); - else if (node.Name != Ndefvar) - args[j++] = New (node, domain); - } - } - - public static Xex New (string url, Domain domain) + public Xexpression (string url, Domain domain) { XmlDocument doc = new XmlDocument (Name.Table); XmlNode node; @@ -1192,58 +1237,47 @@ namespace System.Xml.Expression reader.Read (); } while (reader.NodeType != XmlNodeType.None && (reader.NodeType != XmlNodeType.Element - || Nexpr != reader.Name)); + || reader.Name != Nexpr)); if (reader.NodeType == XmlNodeType.None) throw new Exception ("Node not found"); node = doc.ReadNode (reader); } - return New (node, domain); + int nterms = 0; + for (XmlNode n = node.FirstChild; n != null; n = n.NextSibling) + if (n.NodeType == XmlNodeType.Element) + { + if (n.Name == Ndefun) + domain.RegisterFunction (n); + else if (n.Name == Ndefvar) + domain.Defvar (n); + else + nterms++; + } + + terms = new Term[nterms]; + int i = 0; + for (XmlNode n = node.FirstChild; n != null; n = n.NextSibling) + if (n.NodeType == XmlNodeType.Element) + { + if (n.Name == Ndefun) + domain.Defun (n); + else if (n.Name != Ndefvar) + terms[i]= new Term (n, domain); + } } - public static Xex New (XmlNode node, Domain domain) + public Term Eval (Domain domain) { - Name name = node.Name; - Xex xex; - if (name == Nvariable) - { - Variable vari = domain.GetVar ((Name) node.Attributes[0].Value); - xex = new Xex.Varref (vari); - } - 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) - { - List list = new List (); - for (XmlNode n = node.FirstChild; n != null; n = n.NextSibling) - list.Add (New (n, domain)); - xex = new Xex.Const (list); - } - else + Term result = Zero; + + domain.depth = 0; + foreach (Term term in terms) { - 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); + result = term.Eval (domain); + Console.WriteLine (result); } - return xex; + return result; } } } diff --git a/xex.cs b/xex.cs index 2afa166..6b3a690 100644 --- a/xex.cs +++ b/xex.cs @@ -8,11 +8,10 @@ public class Test { public static void Main() { - Xex.Domain domain = new Xex.Domain (null); - Xex xex = Xex.New ("xex.xml", domain); + Xexpression.Domain domain = new Xexpression.Domain (null); + Xexpression xex = new Xexpression ("xex.xml", domain); - Xex.Debug = true; + Xexpression.debug_level = 1; Console.WriteLine (xex.Eval (domain)); - Console.WriteLine (domain); } } diff --git a/xex.txt b/xex.txt index 575304f..950fa79 100644 --- a/xex.txt +++ b/xex.txt @@ -83,9 +83,10 @@ PREDEFINED-FUNC-SYMBOL = | 'add-set' | 'sub-set' | 'mul-set' | 'div-set' | 'mod-set' | 'logand' | 'logior' | 'logxor' | 'lsh' | 'logand-set' | 'logior-set' | 'logxor-set' | 'lsh-set' - | 'append' | 'concat' | 'substr' | 'tolist' | 'tostring' - | 'cons' | 'car' | 'cdr' | 'nth' | 'copy' | 'ins' | 'del' + | 'copy' | 'append' + | 'ins' | 'del' + | 'cons' | 'car' | 'cdr' | 'nth' | 'case' | 'cond' | 'if' | 'progn' | 'when' | 'while' | 'for' | 'foreach' | 'typeof' diff --git a/xex.xml b/xex.xml index 2a32d58..6efacdd 100644 --- a/xex.xml +++ b/xex.xml @@ -15,6 +15,27 @@ + + x + y + rest + + + + + + x10 + + + sym + sym + sym + + + 1 + + 2 +