public bool Equals (Name name)
{
- Console.WriteLine ("Equals ({0}, {1})", this, name);
- bool result = Object.ReferenceEquals (this.name, name.name);
- Console.WriteLine (result);
- return result;
+ return Object.ReferenceEquals (this.name, name.name);
}
public override bool Equals (object obj)
{
- Console.WriteLine ("Equals ({0}, {1})", this, obj);
- bool result = Object.ReferenceEquals (this.name, obj);
- Console.WriteLine (result);
- return result;
+ return Object.ReferenceEquals (this.name, obj);
}
public override int GetHashCode ()
}
private static Name Nexpr = "expr";
+ private static Name Ntype = "type";
private static Name Nargs = "args";
private static Name Ninteger = "integer";
private static Name Nlist = "list";
private static Name Nobject = "object";
+ private static Name Ndefun = "defun";
+ private static Name Ndefmacro = "defmacro";
+ private static Name Ndefvar = "defvar";
private static Name Nconst = "const";
- private static Name Nvariable = "varialbe";
+ private static Name Nvariable = "variable";
+ private static Name Ndescription = "description";
+ private static Name Npossible_value = "possible-value";
private static Name Nfuncall = "funcall";
private static Name Nmname = "mname";
{
internal class Lambda
{
- internal Name[] args;
+ internal Variable[] args;
internal Xex[] body;
public Lambda (XmlNode node, Domain domain)
this.min_arg = this.max_arg = lambda.args.Length;
}
- private Function ()
+ internal Function (Name name, int nargs, bool specialp)
{
- name = "nil";
+ this.name = name;
+ this.min_arg = this.max_arg = nargs;
}
public object Call (Xex[] args, Domain domain)
Bindings current = domain.bindings;
object result = false;
+ Console.Write ("calling (" + this + "(");
try {
if (! specialp)
foreach (Xex e in args)
e.Eval (domain);
+ Console.WriteLine (")");
if (builtin != null)
return builtin (args, domain);
if (lambda == null)
return null;
-
+ for (int i = 0; i < args.Length; i++)
+ domain.Bind (bindings, lambda.args[i], args[i].val);
foreach (Xex e in lambda.body)
- result = e.Eval (domain);
+ {
+ result = e.Eval (domain);
+ Console.WriteLine (e.ToString () + "=>" + result);
+ }
} finally {
+ Console.WriteLine (")");
domain.UnboundTo (current);
}
return result;
}
+
+ public override string ToString ()
+ {
+ return name;
+ }
}
internal abstract class Variable
public Domain (object context) : this (basic, context)
{
- Console.WriteLine (basic);
}
public Domain (Domain parent, object context)
internal void UnboundTo (Bindings boundary)
{
- bindings = bindings.UnboundTo (boundary);
+ if (boundary != null)
+ bindings = bindings.UnboundTo (boundary);
}
public void Defun (Name name, Builtin builtin, int min_arg, int max_arg)
public void Defun (XmlNode node)
{
- Name name = node.Attributes["id"].Value;
+ Name name = node.Attributes[0].Value;
Function func;
if (functions.TryGetValue (name, out func))
{
XmlNode args = node.FirstChild;
- int nargs = args.Name == "args" ? args.ChildNodes.Count : 0;
+ int nargs = args.Name == Nargs ? args.ChildNodes.Count : 0;
if (func.min_arg < nargs || func.max_arg > nargs)
throw new Exception ("Incompatible argument numbers to override: "
+ name);
- func.lambda.Set (node, this);
+ if (func.lambda == null)
+ func.lambda = new Function.Lambda (node, this);
+ else
+ func.lambda.Set (node, this);
func.builtin = null;
}
else
}
}
+ public void Defun (Name name, int nargs, bool specialp)
+ {
+ Function func;
+
+ if (functions.TryGetValue (name, out func))
+ {
+ if (func.min_arg < nargs || func.max_arg > nargs)
+ throw new Exception ("Incompatible argument numbers to override: "
+ + name);
+ func.min_arg = func.max_arg = nargs;
+ func.specialp = specialp;
+ func.builtin = null;
+ }
+ else
+ {
+ func = new Function (name, nargs, specialp);
+ functions[name] = func;
+ }
+ }
+
+ public void Defvar (Name name, XmlNode node)
+ {
+ Variable vari;
+
+ if (node.Name == Ndescription)
+ node = node.NextSibling;
+ if (node.Name == Nconst)
+ {
+ Name type = (Name) node.Attributes[Ntype].Value;
+ string val = node.Value;
+ XmlNodeList range_list = null;
+ int nranges = 0;
+
+ node = node.NextSibling;
+ if (node.Name == Npossible_value)
+ {
+ range_list = node.ChildNodes;
+ nranges = range_list.Count;
+ }
+
+ if (type == Ninteger)
+ {
+ VarInt vi = new VarInt (name, parse_integer (val));
+ if (range_list != null)
+ {
+ vi.ranges = new VarInt.Range[nranges];
+
+ for (int i = 0; i < nranges; i++)
+ {
+ 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"
+ {
+ vi.ranges[i].from =
+ parse_integer (n.FirstChild.Value);
+ vi.ranges[i].to =
+ parse_integer (n.LastChild.Value);
+ }
+ }
+ }
+ vari = vi;
+ }
+ else if (type == Nstring)
+ {
+ VarStr vs = new VarStr (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);
+ variables[name] = vari;
+ }
+
internal Function GetFunc (Name name)
{
Function func;
return xex;
}
+ internal static int parse_integer (string str)
+ {
+ int len = str.Length;
+ bool negative = false;
+
+ if (len <= 1)
+ return (len == 0 ? 0 : str[0] - '0');
+
+ int c = str[0];
+ int i;
+
+ if (c == '0' && str[1] == 'x')
+ {
+ i = 0;
+ for (int idx = 2; idx < len; idx++)
+ {
+ c = str[idx];
+ if (c < '0')
+ break;
+ else if (c <= '9')
+ i = i * 16 + (c - '0');
+ else if (c < 'A')
+ break;
+ else if (c <= 'F')
+ i = i * 16 + (c - 'A');
+ else if (c < 'a')
+ break;
+ else if (c <= 'f')
+ i = i * 16 + (c - 'a');
+ else
+ break;
+ }
+ return i;
+ }
+ if (c == '-')
+ negative = true;
+ i = c - '0';
+ for (int idx = 1; idx < len; idx++)
+ {
+ c = str[idx];
+ if (c < '0' || c > '9')
+ break;
+ i = i * 10 + (c - '0');
+ }
+ return negative ? - i : i;
+ }
+
+ private int pre_parse (XmlNodeList nlist, Domain domain)
+ {
+ int len = 0;
+ foreach (XmlNode node in nlist)
+ {
+ if (node.Name == Ndefun)
+ {
+ XmlNode n = node.FirstChild;
+ domain.Defun ((Name) node.Attributes[0].Value,
+ n.Name == Nargs ? n.ChildNodes.Count : 0, false);
+ }
+ else if (node.Name == Ndefmacro)
+ {
+ XmlNode n = node.FirstChild;
+ domain.Defun ((Name) node.Attributes[0].Value,
+ n.Name == Nargs ? n.ChildNodes.Count : 0, true);
+ }
+ else if (node.Name == Ndefvar)
+ {
+ domain.Defvar ((Name) node.Attributes[0].Value, node.FirstChild);
+ }
+ else
+ len++;
+ }
+ return len;
+ }
+
+ private void post_parse (XmlNodeList nlist, Domain domain)
+ {
+ for (int i = 0, j = 0; i < nlist.Count; i++)
+ {
+ XmlNode node = nlist[i];
+
+ if (node.Name == Ndefun)
+ domain.Defun (node);
+ else if (node.Name == Ndefmacro)
+ domain.Defun (node);
+ else if (node.Name != Ndefvar)
+ args[j++] = new Xex (node, domain);
+ }
+ }
+
private void Setup (XmlNode node, Domain domain)
{
Name name = node.Name;
if (name == Nconst)
{
- Name type = node.Attributes["type"].Value;
+ Name type = node.Attributes[Ntype].Value;
if (type == Ninteger)
val = parse_integer (node.InnerText);
else if (name == Nvariable)
{
args = new Xex[1];
- args[0] = new Xex (node.Attributes[0]);
+ args[0] = new Xex ((Name) node.Attributes[0].Value);
}
else
{
if (Nmname == node.Attributes[0].Name)
is_macro = true;
}
+
function = domain.GetFunc (name);
XmlNodeList nlist = node.ChildNodes;
|| (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];
- for (int i = 0; i < nargs; i++)
- args[i] = new Xex (nlist[i]);
+ post_parse (nlist, domain);
if (is_macro)
{
reader.Read ();
} while (reader.NodeType != XmlNodeType.None
&& (reader.NodeType != XmlNodeType.Element
- || (object) Nexpr != (object) reader.Name));
- if (reader.NodeType != XmlNodeType.None)
+ || Nexpr != reader.Name));
+ if (reader.NodeType == XmlNodeType.None)
throw new Exception ("Node <expr> not found");
- Console.WriteLine (doc.ReadNode (reader).OuterXml);
node = doc.ReadNode (reader);
- Console.WriteLine ("node read:" + node.OuterXml);
}
Setup (node, domain);
Setup (node, domain);
}
- private int parse_integer (string str)
- {
- int len = str.Length;
- bool negative = false;
-
- if (len <= 1)
- return (len == 0 ? 0 : str[0]);
-
- int c = str[0];
- int i;
-
- if (c == '0' && str[1] == 'x')
- {
- i = 0;
- for (int idx = 2; idx < len; idx++)
- {
- c = str[idx];
- if (c < '0')
- break;
- else if (c <= '9')
- i = i * 16 + c;
- else if (c < 'A')
- break;
- else if (c <= 'F')
- i = i * 16 + (c - 'A');
- else if (c < 'a')
- break;
- else if (c <= 'f')
- i = i * 16 + (c - 'a');
- else
- break;
- }
- return i;
- }
- if (c == '-')
- negative = true;
- i = c;
- for (int idx = 1; idx < len; idx++)
- {
- c = str[idx];
- if (c < '0' || c > '9')
- break;
- i = i * 10 + (c - '0');
- }
- return negative ? - i : i;
- }
-
public object Eval (Domain domain)
{
if (function == null)
}
else if (args != null)
{
- str = (string) args[0].val;
+ str = (Name) args[0].val;
}
else if (val != null)
{