private static Symbol Qnull = "";
private static Symbol Qfuncall = "funcall";
- private static Symbol Qvarref = "varref";
private static Symbol Qinteger = "integer";
private static Symbol Qstring = "string";
private static Symbol Qsymbol = "symbol";
: base (name, min_arg, max_arg)
{
this.builtin = builtin;
+ this.setvar = setvar;
}
public override Term Call (Domain domain, Variable vari, Term[] args)
{
- args = (Term[]) args.Clone ();
- for (int i = 0; i < args.Length; i++)
+ if (args != null)
{
- args[i] = args[i].Eval (domain);
- if (domain.Thrown)
- return args[i];
+ args = (Term[]) args.Clone ();
+ for (int i = 0; i < args.Length; i++)
+ {
+ args[i] = args[i].Eval (domain);
+ if (domain.Thrown)
+ return args[i];
+ }
}
return builtin (domain, vari, args);
}
}
}
- public Lambda (Domain domain, Symbol name, bool args_evalled, Symbol[] args)
+ public Lambda (Domain domain, Symbol name,
+ bool args_evalled, Symbol[] args)
{
int nfixed = 0;
int noptional = 0;
}
}
- public class Variable : TermValue
+ public class Variable
{
+ public Domain domain;
public readonly Symbol name;
public string desc;
- internal Term default_val;
- internal Term val;
+ protected Term default_val;
+ protected Term val;
object range;
- public Variable (Symbol name, Term value)
+ public Variable (Domain domain, Symbol name, Term val)
{
+ this.domain = domain;
this.name = name;
- val = value;
+ this.val = val;
default_val = Zero;
}
public virtual bool ValueP (Term val) { return true; }
- public override TermValue Clone ()
+ public Variable Clone (Domain domain)
{
- Variable v = new Variable (name, val);
+ Variable v = new Variable (domain, name, val);
v.desc = desc;
v.default_val = default_val;
v.range = range;
}
}
+ public Term SetValue (int i)
+ {
+ val.intval = i;
+ val.objval = null;
+ return val;
+ }
+
+ public Term SetValue (string s)
+ {
+ val.objval = s;
+ return val;
+ }
+
public Term DefaultValue
{
get { return default_val; }
set { range = value; }
}
- public override Term Eval (Domain domain) { return val; }
-
public override string ToString () { return name + "(" + val + ")"; }
public class Int : Variable
return false;
}
- public Int (Symbol name, string description, int value, int[] range)
- : base (name, new Term (value))
+ public Int (Domain domain, Symbol name, string description,
+ int value, int[] range)
+ : base (domain, name, new Term (value))
{
if (! SubsetP (value, range))
throw new Exception ("Invalid value: " + value);
return false;
}
- public Str (Symbol name, string description, string value, string[] range)
- : base (name, new Term (value))
+ public Str (Domain domain, Symbol name, string description,
+ string value, string[] range)
+ : base (domain, name, new Term (value))
{
if (! SubsetP (value, range))
throw new Exception ("Invalid value: " + value);
return false;
}
- public Sym (Symbol name, string description, Symbol value, Symbol[] range)
- : base (name, new Term (value))
+ public Sym (Domain domain, Symbol name, string description,
+ Symbol value, Symbol[] range)
+ : base (domain, name, new Term (value))
{
if (! SubsetP (value, range))
throw new Exception ("Invalid value: " + value);
private Bindings (Variable vari)
{
this.vari = vari;
- old_value = vari.val;
+ old_value = vari.Value;
}
public static Bindings Bind (Bindings bindings, Variable vari, Term val)
internal Bindings UnboundTo (Bindings boundary)
{
for (Bindings b = this; b != boundary; b = b.next)
- b.vari.val = b.old_value;
+ b.vari.Value = b.old_value;
return boundary;
}
public class Domain
{
+ public Symbol name;
public object context;
public int depth = 0;
private Stack<CatchTag> catch_stack = new Stack<CatchTag> ();
private int catch_count = 0;
- internal Domain () { }
+ internal Domain (Symbol name) { this.name = name; }
- public Domain (object context) : this (basic, context) { }
+ public Domain (Symbol name, object context)
+ : this (name, basic, context) { }
- public Domain (Domain parent, object context)
+ public Domain (Symbol name, Domain parent, object context) : this (name)
{
termtypes = new Dictionary<Symbol, TermType> (parent.termtypes);
functions = new Dictionary<Symbol, Function> (parent.functions);
{
if (! (vari is Variable.Int))
throw new Exception ("Inalid value");
- vari = (Variable) vari.Clone ();
+ vari = (Variable) vari.Clone (this);
Term v = new Term (intval);
vari.Value = v;
vari.DefaultValue = v;
vari.Range = range;
}
else
- vari = new Variable.Int (name, desc, intval, range);
+ vari = new Variable.Int (this, name, desc, intval, range);
}
else if (type == Qstring)
{
{
if (! (vari is Variable.Str))
throw new Exception ("Invalid value");
- vari = (Variable) vari.Clone ();
+ vari = (Variable) vari.Clone (this);
Term v = new Term (val);
vari.Value = v;
vari.DefaultValue = v;
vari.Range = range;
}
else
- vari = new Variable.Str (name, desc, val, range);
+ vari = new Variable.Str (this, name, desc, val, range);
}
else if (type == Qsymbol)
{
{
if (! (vari is Variable.Sym))
throw new Exception ("Invalid value");
- vari = (Variable) vari.Clone ();
+ vari = (Variable) vari.Clone (this);
Term v = new Term (val);
vari.Value = v;
vari.DefaultValue = v;
vari.Range = range;
}
else
- vari = new Variable.Sym (name, desc, val, range);
+ vari = new Variable.Sym (this, name, desc, val, range);
}
else
throw new Exception ("Unknown type: " + type);
else
{
if (variables.TryGetValue (name, out vari))
- vari = (Variable) vari.Clone ();
+ vari = (Variable) vari.Clone (this);
else
- vari = new Variable (name, Zero);
+ vari = new Variable (this, name, Zero);
}
variables[name] = vari;
return vari;
public Variable Defvar (Variable vari)
{
+ vari = vari.Clone (this);
variables[vari.name] = vari;
return vari;
}
internal Variable Defvar (Symbol name)
{
- Variable vari = new Variable (name, Zero);
+ Variable vari = new Variable (this, name, Zero);
variables[name] = vari;
return vari;
}
{
if (! create)
return null;
- variables[name] = vari = new Variable (name, Zero);
+ variables[name] = vari = new Variable (this, name, Zero);
}
return vari;
}
str += " " + kv.Key;
str += ") (variabls";
foreach (KeyValuePair<Symbol, Variable> kv in variables)
- str += " " + kv.Key;
+ str += " " + kv.Value;
str += ")";
if (bindings != null)
str += " " + bindings;
Dictionary<Variable,Term> values = new Dictionary<Variable,Term> ();
foreach (KeyValuePair<Symbol,Variable> kv in variables)
- values[kv.Value] = kv.Value.val.Clone ();
+ values[kv.Value] = kv.Value.Value.Clone ();
return values;
}
{
foreach (KeyValuePair<Variable,Term> kv
in (Dictionary<Variable,Term>) values)
- kv.Key.val = kv.Value;
+ kv.Key.Value = kv.Value;
}
}
public delegate Term Builtin (Domain domain, Variable vari, Term[] args);
- private static Domain basic = new Domain ();
+ private static Domain basic = new Domain ("basic");
static Xexpression ()
{
basic.DefTerm ("funcall", Funcall.parser);
+ basic.DefTerm ("varref", Varref.parser);
basic.DefSubr (Fset, "set", true, 1, 1, "=");
basic.DefSubr (Fnot, "not", false, 1, 1, "!");
private static Term Fset (Domain domain, Variable vari, Term[] args)
{
vari.Value = args[0];
- return vari.val;
+ return args[0];
}
private static Term Fnot (Domain domain, Variable vari, Term[] args)
private static Term Fadd (Domain domain, Variable vari, Term[] args)
{
- int n = vari == null ? 0 : vari.val.Intval;
+ int n = vari == null ? 0 : vari.Value.Intval;
foreach (Term arg in args)
n += arg.Intval;
- if (vari == null)
- return new Term (n);
- vari.val.intval = n;
- return vari.val;
+ return (vari == null ? new Term (n) : vari.SetValue (n));
}
private static Term Fmul (Domain domain, Variable vari, Term[] args)
{
- int n = vari == null ? 1 : vari.val.Intval;
+ int n = vari == null ? 1 : vari.Value.Intval;
foreach (Term arg in args)
n *= arg.Intval;
- if (vari == null)
- return new Term (n);
- vari.val.intval = n;
- return vari.val;
+ return (vari == null ? new Term (n) : vari.SetValue (n));
}
private static Term Fsub (Domain domain, Variable vari, Term[] args)
}
else
{
- n = vari.val.Intval;
+ n = vari.Value.Intval;
i = 0;
}
while (i < args.Length)
n -= args[i++].Intval;
- if (vari == null)
- return new Term (n);
- vari.val.intval = n;
- return vari.val;
+ return (vari == null ? new Term (n) : vari.SetValue (n));
}
private static Term Fdiv (Domain domain, Variable vari, Term[] args)
}
else
{
- n = vari.val.Intval;
+ n = vari.Value.Intval;
i = 0;
}
while (i < args.Length)
n /= args[i++].Intval;
- if (vari == null)
- return new Term (n);
- vari.val.intval = n;
- return vari.val;
+ return (vari == null ? new Term (n) : vari.SetValue (n));
}
private static Term Fmod (Domain domain, Variable vari, Term[] args)
{
- if (vari == null)
- return new Term (args[0].Intval % args[1].Intval);
- vari.val.intval = vari.val.Intval % args[0].Intval;
- return vari.val;
+ int n = args[0].Intval % args[1].Intval;
+
+ return (vari == null ? new Term (n) : vari.SetValue (n));
}
private static Term Flogior (Domain domain, Variable vari, Term[] args)
{
- int n = vari == null ? 0 : vari.val.Intval;
+ int n = vari == null ? 0 : vari.Value.Intval;
foreach (Term arg in args)
n |= arg.Intval;
- if (vari == null)
- return new Term (n);
- vari.val.intval = n;
- return vari.val;
+ return (vari == null ? new Term (n) : vari.SetValue (n));
}
private static Term Flogand (Domain domain, Variable vari, Term[] args)
}
else
{
- n = vari.val.Intval;
+ n = vari.Value.Intval;
i = 0;
}
while (i < args.Length)
n &= args[i++].Intval;
- if (vari == null)
- return new Term (n);
- vari.val.intval = n;
- return vari.val;
+ return (vari == null ? new Term (n) : vari.SetValue (n));
}
private static Term Flsh (Domain domain, Variable vari, Term[] args)
{
- if (vari == null)
- return new Term (args[0].Intval << args[1].Intval);
- vari.val.intval = vari.val.Intval << args[0].Intval;
- return vari.val;
+ int n = args[0].Intval << args[1].Intval;
+ return (vari == null ? new Term (n) : vari.SetValue (n));
}
private static Term Frsh (Domain domain, Variable vari, Term[] args)
{
- if (vari == null)
- return new Term (args[0].Intval >> args[1].Intval);
- vari.val.intval = vari.val.Intval >> args[0].Intval;
- return vari.val;
+ int n = args[0].Intval >> args[1].Intval;
+ return (vari == null ? new Term (n) : vari.SetValue (n));
}
private static Term Feq (Domain domain, Variable vari, Term[] args)
if (vari == null)
list = new List<Term> ();
else
- list = vari.val.Listval;
+ list = vari.Value.Listval;
foreach (Term arg in args)
{
result.objval = list;
return result;
}
- return vari.val;
+ return vari.Value;
}
private static Term Fconcat (Domain domain, Variable vari, Term[] args)
if (vari == null)
str = "";
else
- str = vari.val.Strval;
+ str = vari.Value.Strval;
foreach (Term arg in args)
{
else
str += (char) arg.Intval;
}
+
if (vari == null)
{
- Term result;
- result.intval = 0;
- result.objval = str;
- return result;
+ Term term;
+ term.intval = 0;
+ term.objval = str;
+ return term;
}
- vari.val.objval = str;
- return vari.val;
+ return vari.SetValue (str);
}
private static Term Fnth (Domain domain, Variable vari, Term[] args)
private static Term Fins (Domain domain, Variable vari, Term[] args)
{
- if (vari.val.IsStr)
- vari.val.objval
- = vari.val.Strval.Insert (args[0].Intval, args[1].Strval);
- else if (vari.val.IsList)
- vari.val.Listval.InsertRange (args[0].Intval, args[1].Listval);
+ Term term = vari.Value;
+
+ if (term.IsStr)
+ {
+ string str = term.Strval.Insert (args[0].Intval, args[1].Strval);
+ vari.SetValue (str);
+ }
+ else if (vari.Value.IsList)
+ vari.Value.Listval.InsertRange (args[0].Intval, args[1].Listval);
else
- throw new Exception ("term is not collection: " + vari.val);
- return vari.val;
+ throw new Exception ("term is not collection: " + vari.Value);
+ return vari.Value;
}
private static Term Fdel (Domain domain, Variable vari, Term[] args)
{
- if (vari.val.IsStr)
- vari.val.objval
- = vari.val.Strval.Remove (args[0].Intval,
- args[1].Intval - args[0].Intval);
-
- else if (vari.val.IsList)
- vari.val.Listval.RemoveRange (args[0].Intval,
+ if (vari.Value.IsStr)
+ {
+ string str
+ = vari.Value.Strval.Remove (args[0].Intval,
+ args[1].Intval - args[0].Intval);
+ vari.SetValue (str);
+ }
+ else if (vari.Value.IsList)
+ vari.Value.Listval.RemoveRange (args[0].Intval,
args[1].Intval - args[0].Intval);
else
- throw new Exception ("term is not collection: " + vari.val);
- return vari.val;
+ throw new Exception ("term is not collection: " + vari.Value);
+ return vari.Value;
}
private static Term Fand (Domain domain, Variable vari, Term[] args)
public abstract class TermValue
{
public virtual Term Eval (Domain domain) { return new Term (this); }
- public abstract TermValue Clone ();
+ public virtual TermValue Clone () { return this; }
+ }
+
+ private class Varref : TermValue
+ {
+ private Symbol name;
+ private Variable vari;
+
+ public Varref (Symbol name) { this.name = name; }
+
+ public override Term Eval (Domain domain)
+ {
+ if (vari == null || vari.domain != domain)
+ vari = domain.GetVar (name, true);
+ return vari.Value;
+ }
+
+ internal static TermValue parser (Domain domain, XmlNode node)
+ {
+ return new Varref ((Symbol) node.Attributes[Qvname].Value);
+ }
+
+ public override string ToString ()
+ {
+ return "<varref vname=\"" + name + "\"/>";
+ }
}
private class Funcall : TermValue
public Funcall (Domain domain, Symbol fname, Term[] args)
{
func = domain.GetFunc (fname);
+ if (args != null)
+ {
+ int nargs = args.Length;
+ if (nargs < func.min_arg
+ || (func.max_arg >= 0 && nargs > func.max_arg))
+ throw new Exception ("Invalid number of arguments to: "
+ + fname + " " + nargs);
+ }
this.args = args;
}
public Funcall (Domain domain, Symbol fname, Symbol vname, Term[] args)
{
func = domain.GetFunc (fname);
- int nargs = args.Length;
- if (nargs < func.min_arg
- || (func.max_arg >= 0 && nargs > func.max_arg))
- throw new Exception ("Invalid number of arguments to: "
- + fname + " " + nargs);
+ if (args != null)
+ {
+ int nargs = args.Length;
+ if (nargs < func.min_arg
+ || (func.max_arg >= 0 && nargs > func.max_arg))
+ throw new Exception ("Invalid number of arguments to: "
+ + fname + " " + nargs);
+ }
this.args = args;
if (vname != Qnull)
vari = domain.GetVar (vname, true);
public override 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.DebugWrite (true, ToString ());
domain.depth++;
Term result = func.Call (domain, vari, args);
domain.depth--;
- domain.DebugWrite (true, " ==> {0})", result.ToString ());
+ domain.DebugWrite (true, " ==> {0}", result.ToString ());
return result;
}
public override string ToString ()
{
- string str = "<funcall fname=\"" + func.name;
+ string str = "<" + func.name;
+ if (vari != null)
+ str += " vname=\"" + vari.name + "\"";
if (args == null)
- return str + "\"/>";
- str += "\">";
- foreach (Term e in args)
- str += e;
- return (str + "</funcall>");
+ return str + "/>";
+ str += ">";
+ if (func is Function.SpecialForm)
+ str += String.Format ("({0})...", args.Length);
+ else
+ foreach (Term e in args)
+ str += e;
+ return (str + "</" + func.name + ">");
}
}
public int intval;
public object objval;
+ // <integer>...</integer>
public Term (int i) { intval = i; objval = null; }
+ // <symbol>...</symbol>
public Term (Symbol name) { intval = 0; objval = name; }
+ // <string>...</string>
public Term (string str) { intval = 0; objval = str; }
+ // <list>...</list>
public Term (List<Term> list) { intval = 0; objval = list; }
+
public Term (Term term) { intval = term.intval; objval = term.objval; }
public Term (TermValue obj) { intval = 0; objval = obj; }
objval = (Symbol) node.InnerText;
else if (name == Qstring)
objval = node.InnerText.Clone ();
- else if (name == Qvarref)
- objval = domain.GetVar ((Symbol) node.Attributes[0].Value, true);
else if (name == Qlist)
{
List<Term> list = new List<Term> ();
}
}
+ // <varref vname="VNAME"/>
public Term (Domain domain, Symbol vname)
{
intval = 0;
- objval = domain.GetVar (vname, true);
+ objval = new Varref (vname);
}
+ // <funcall fname="FNAME">...</funcall>
public Term (Domain domain, Symbol fname, Term[] args)
{
intval = 0;
objval = new Funcall (domain, fname, args);
}
+ // <funcall fname="FNAME" vname="VNAME">...</funcall>
public Term (Domain domain, Symbol fname, Symbol vname, Term[] args)
{
intval = 0;
str += e;
str += "</list>";
}
- else if (objval is Funcall)
- str = "<funcall fname=\"" + ((Funcall) objval).func.name + "\"/>";
- else if (objval is Variable)
- str = "<variable vname=\"" + ((Variable) objval).name + "\"/>";
else if (objval is Term)
str = "<quote>" + objval + "</quote>";
+ else if (objval is TermValue)
+ str = ((TermValue) objval).ToString ();
else
throw new Exception ("invalid Term object: " + objval);
return str;
return terms;
}
+ public static Term Eval (Domain domain, Term[] terms)
+ {
+ Term result = new Term (0);
+ foreach (Term term in terms)
+ {
+ result = term;
+ if (result.Objval is Funcall)
+ while ((result = result.Eval (domain)).Objval is Funcall);
+ }
+ return result;
+ }
+
+
public Xexpression (Domain domain, XmlNode node)
{
terms = ParseTerms (domain, node);