string str = (InnerException != null ? InnerException.ToString ()
: base.ToString ()) + "\n" + "Xexpression:" + name + "\n";
if (node != null)
- str += " at " + node.Parent.OuterXml + "\n";
+ str += " at " + node.OuterXml + "\n";
if (stack != null)
{
str += "Call stack: ";
public static Symbol VariableRangeConflict = "variable-range-conflict";
public static Symbol VariableWrongRange = "variable-wrong-range";
public static Symbol VariableWrongValue = "variable-wrong-value";
+
public static Symbol UnknownFunction = "unknown-function";
public static Symbol MacroExpansionError = "macro-expansion-error";
public static Symbol NoVariableName = "no-variable-anme";
internal void ThrowSymbol (Term tag)
{
+ int i = catch_count;
foreach (CatchTag elt in catch_stack)
{
- catch_count--;
+ i--;
if (elt.Tag.Matches (tag))
- return;
+ {
+ catch_count = i;
+ return;
+ }
}
throw new Error (Error.UncaughtThrow,
"No corresponding catch: {0}", tag);
internal Variable Defvar (Symbol name)
{
- Variable vari = new Variable (this, name, Zero);
- variables[name] = vari;
+ Variable vari;
+
+ if (variables.TryGetValue (name, out vari))
+ {
+ Variable.Typed typed = vari as Variable.Typed;
+ if (typed != null)
+ throw new Error (Error.VariableTypeConflict,
+ "Not a non-typed variable: {0}", name);
+ }
+ else
+ {
+ vari = new Variable (this, name, Zero);
+ variables[name] = vari;
+ }
return vari;
}
domain.functions[kv.Key] = kv.Value;
}
- public Variable GetVar (Symbol name)
+ public Variable GetVarCreate (Symbol name)
{
Variable vari;
return vari;
}
+ public Variable GetVar (Symbol name)
+ {
+ Variable vari;
+
+ if (! variables.TryGetValue (name, out vari))
+ return null;
+ return vari;
+ }
+
public override string ToString ()
{
string str = "<(functions";
private static Term Fand (Domain domain, Variable vari, Term[] args)
{
foreach (Term arg in args)
- if (! arg.Eval (domain).IsTrue)
- return Zero;
+ {
+ Term result = arg.Eval (domain);
+ if (domain.Thrown ())
+ result;
+ if (! result.IsTrue)
+ return Zero;
+ }
return One;
}
private static Term For (Domain domain, Variable vari, Term[] args)
{
foreach (Term arg in args)
- if (arg.Eval (domain).IsTrue)
- return One;
+ {
+ Term result = arg.Eval (domain);
+ if (domain.Thrown ())
+ return result;
+ if (result.IsTrue)
+ return One;
+ }
return Zero;
}
Term result = One;
foreach (Term arg in args)
- result = arg.Eval (domain);
+ {
+ result = arg.Eval (domain);
+ if (domain.Thrown ())
+ return result;
+ }
return result;
}
private static Term Fif (Domain domain, Variable vari, Term[] args)
{
- if (args[0].Eval (domain).IsTrue)
+ Term result = args[0].Eval (domain);
+
+ if (domain.Thrown)
+ return result;
+ if (result.IsTrue)
return args[1].Eval (domain);
if (args.Length == 2)
return Zero;
private static Term Fwhen (Domain domain, Variable vari, Term[] args)
{
- if (! args[0].Eval (domain).IsTrue)
+ Term result = args[0].Eval (domain);
+
+ if (domain.Thrown)
+ return result;
+ if (! result.IsTrue)
return Zero;
- Term result = One;
+ result = One;
for (int i = 1; i < args.Length; i++)
- result = args[i].Eval (domain);
+ {
+ result = args[i].Eval (domain);
+ if (domain.Thrown)
+ return result;
+ }
return result;
}
{
result = terms[i].Eval (domain);
if (domain.Thrown (out caught))
- break;
+ return result;
}
return result;
}
public virtual bool Matches (TermValue other) { return Equals (other); }
public override abstract bool Equals (object obj);
public override abstract int GetHashCode ();
- public abstract string ToString (bool detail);
+ public virtual string ToString (bool detail) { return ToString (); }
}
private class Varref : TermValue
public override Term Eval (Domain domain)
{
if (vari == null || vari.domain != domain)
- vari = domain.GetVar (vname);
+ vari = domain.GetVarCreate (vname);
return vari.Value;
}
{
private static Symbol name = "funcall";
public static Symbol Name { get { return name; } }
+ private static Term[] null_args = new Term[0];
internal Function func;
internal Variable vari;
public Funcall (Function func, Variable vari, Term[] args)
{
+ if (args == null)
+ args = null_args;
int nargs = args.Length;
-
if (nargs < func.min_args
|| (func.max_args >= 0 && nargs > func.max_args))
throw new Error (Error.WrongArgument,
Function func = domain.GetFunc (fname);
Variable vari;
attr = node.Attributes[Qvname];
- vari = attr == null ? null : domain.GetVar (attr.Value);
+ vari = attr == null ? null : domain.GetVarCreate (attr.Value);
XmlNodeList nlist = node.ChildNodes;
int nargs = nlist.Count;
Term[] args = new Term[nargs];
intval = 0;
Function func = domain.GetFunc (fname);
- Variable vari = vname == Qnull ? null : domain.GetVar (vname);
+ Variable vari = vname == Qnull ? null : domain.GetVarCreate(vname);
Funcall funcall = new Funcall (func, vari, args);
if (func is Function.Macro)
{
Function func = domain.GetFunc (name);
for (node = node.FirstChild; node != null; node = node.NextSibling)
- if (node.Name != Qdescription
- && node.Name != Qargs)
+ if (node.Name != Qdescription && node.Name != Qargs)
break;
+ Console.WriteLine ("found body " + node.Name);
+
Term[] body = Parse (domain, node, null);
if (is_defun)
((Function.Lambda) func).SetBody (body);
XmlDocument doc = new XmlDocument (Symbol.NameTable);
XmlNode node;
- using (XmlTextReader reader = new XmlTextReader (url, doc.NameTable))
+ using (XmlTextReader reader = new XmlTextReader (url, Symbol.NameTable))
{
+ reader.WhitespaceHandling = WhitespaceHandling.None;
do {
reader.Read ();
} while (reader.NodeType != XmlNodeType.None
return Parse (domain, node.FirstChild, null);
}
+ public static Term Eval (Domain domain, Term term)
+ {
+ return Eval (domain, new Term[] { term });
+ }
+
public static Term Eval (Domain domain, Term[] terms)
{
Term result = Zero;