namespace M17N.Core
{
- public delegate object MEvaluator (object arg, MPlist bindings);
-
- public class MFunction
+ public class MExpression
{
- MSymbol name;
- internal readonly MEvaluator evaluator;
+ public delegate object Evaluator (object[] args, MPlist bindings);
- public static Dictionary<MSymbol, MFunction> CommonTable
- = new Dictionary<MSymbol, MFunction> ();
- public static readonly MFunction Identity
- = new MFunction (MSymbol.nil, null);
+ internal delegate void PretyPrinter (MFunction func,
+ string indent, object[] args);
- static MFunction ()
+ internal class MFunction
{
- new MFunction (MSymbol.Of ("+"), new MEvaluator (plus));
- new MFunction (MSymbol.Of ("*"), new MEvaluator (multi));
- new MFunction (MSymbol.Of ("-"), new MEvaluator (minus));
- }
+ internal MSymbol name;
+ internal readonly Evaluator eval;
+ internal int min_arg;
+ internal int max_arg;
+ internal Type[] arg_types;
- internal MFunction (MSymbol name, MEvaluator evaluator)
- {
- this.name = name;
- this.evaluator = evaluator;
- CommonTable[name] = this;
- }
+ public PretyPrinter pp;
- public MFunction (MSymbol name, MEvaluator evaluator,
- Dictionary<MSymbol, MFunction> dict)
- {
- this.evaluator = evaluator;
- dict[name] = this;
- }
+ private static PretyPrinter default_prety_printer;
+ private static PretyPrinter set_prety_printer;
+ internal static MFunction literal, varref, block;
- internal static MFunction Find (MSymbol name,
- Dictionary<MSymbol, MFunction> Table)
- {
- if (name == MSymbol.integer
- || name == MSymbol.plist
- || name == MSymbol.mtext
- || name == MSymbol.symbol)
- return Identity;
+ public MFunction (MSymbol name, Evaluator eval,
+ int min_arg, int max_arg, Type[] arg_types)
+ {
+ this.name = name;
+ this.eval = eval;
+ this.min_arg = min_arg;
+ this.max_arg = max_arg;
+ this.arg_types = (Type []) arg_types.Clone ();
+ if (arg_types.Length == 2 && arg_types[0] == typeof (MSymbol))
+ pp = set_prety_printer;
+ else
+ pp = default_prety_printer;
+ }
- MFunction func;
- if ((Table == null
- || ! Table.TryGetValue (name, out func))
- && ! MFunction.CommonTable.TryGetValue (name, out func))
- throw new Exception ("Unknown function: " + name);
- return func;
- }
+ static MFunction ()
+ {
+ default_prety_printer = new PretyPrinter (default_pp);
+ set_prety_printer = new PretyPrinter (set_pp);
+ literal = Defun ("nil", null, 1, 1);
+ varref = Defun ("symbol", new Evaluator (get_value), 1, 1);
+ block = Defun ("plist", new Evaluator (progn), 1, -1);
- public object Call (object arg, MPlist bindings)
- {
- if (name == MSymbol.nil)
- return arg;
- return evaluator (arg, bindings);
- }
+ Defun ("set", new Evaluator (set_value), 2, 2,
+ typeof (MSymbol), typeof (MExpression));
+ Defun ("=", new Evaluator (set_value), 2, 2,
+ typeof (MSymbol), typeof (MExpression));
+ Defun ("+", new Evaluator (plus), 1, -1);
+ Defun ("*", new Evaluator (multi), 2, -1);
+ Defun ("-", new Evaluator (minus), 1, -1);
+ Defun ("/", new Evaluator (divide), 2, -1);
+ Defun ("%", new Evaluator (percent), 2, -1);
+ Defun ("|", new Evaluator (logior), 2, -1);
+ Defun ("&", new Evaluator (logand), 2, -1);
+ Defun ("+=", new Evaluator (pluseq), 2, -1,
+ typeof (MSymbol), typeof (MExpression));
+ Defun ("*=", new Evaluator (multieq), 2, -1,
+ typeof (MSymbol), typeof (MExpression));
+ Defun ("-=", new Evaluator (minuseq), 2, -1,
+ typeof (MSymbol), typeof (MExpression));
+ Defun ("/=", new Evaluator (divideeq), 2, -1,
+ typeof (MSymbol), typeof (MExpression));
+ Defun ("%=", new Evaluator (percenteq), 2, -1,
+ typeof (MSymbol), typeof (MExpression));
+ Defun ("|=", new Evaluator (logioreq), 2, -1,
+ typeof (MSymbol), typeof (MExpression));
+ Defun ("&=", new Evaluator (logandeq), 2, -1,
+ typeof (MSymbol), typeof (MExpression));
+ Defun ("<<", new Evaluator (lshift), 2, 2);
+ Defun (">>", new Evaluator (rshift), 2, 2);
+ Defun ("<<=", new Evaluator (lshifteq), 2, 2,
+ typeof (MSymbol), typeof (MExpression));
+ Defun (">>=", new Evaluator (rshifteq), 2, 2,
+ typeof (MSymbol), typeof (MExpression));
+ Defun ("==", new Evaluator (eq), 2, -1);
+ Defun ("!=", new Evaluator (noteq), 2, 2);
+ Defun ("<", new Evaluator (less), 2, -1);
+ Defun ("<=", new Evaluator (lesseq), 2, -1);
+ Defun (">", new Evaluator (more), 2, -1);
+ Defun (">=", new Evaluator (moreeq), 2, -1);
+ block = Defun ("progn", new Evaluator (progn), 1, -1);
+ block.pp = new PretyPrinter (block_pp);
+ Defun ("cond", new Evaluator (cond), 1, -1,
+ typeof (MExpression[])).pp = new PretyPrinter (cond_pp);
+ Defun ("if", new Evaluator (ifclause), 2, -1,
+ typeof (MExpression)).pp = new PretyPrinter (if_pp);
+ Defun ("while", new Evaluator (whileclause), 1, -1,
+ typeof (MExpression)).pp = new PretyPrinter (while_pp);
+ }
- private static object plus (object arg, MPlist bindings)
- {
- MExpression expr = (MExpression) arg;
+ public object Call (object[] args, MPlist bindings)
+ {
+ if (name == MSymbol.nil)
+ return args[0];
+ return eval (args, bindings);
+ }
- int n = 0;
- foreach (MExpression e in expr)
- n += (int) e.Eval (bindings);
- return n;
- }
+ private static MPlist find_binding (object[] args, MPlist bindings)
+ {
+ MSymbol var = (MSymbol) args[0];
+ MPlist slot = bindings.Find (var);
- private static object multi (object arg, MPlist bindings)
- {
- MExpression expr = (MExpression) arg;
+ if (slot == null)
+ throw new Exception ("Unbound variable: " + var);
+ return slot;
+ }
- int n = 1;
- foreach (MExpression e in expr)
- n *= (int) e.Eval (bindings);
- return n;
- }
+ public static void default_pp (MFunction func,
+ string indent, object[] args)
+ {
+ Console.Write ("(" + func.name);
+ indent += " ";
+ foreach (MExpression o in args)
+ {
+ Console.Write (" ");
+ o.pp (indent);
+ }
+ Console.Write (")");
+ }
+
+ private static object get_value (object[] args, MPlist bindings)
+ {
+ return find_binding (args, bindings).val;
+ }
+
+ private static object set_value (object[] args, MPlist bindings)
+ {
+ MSymbol var = (MSymbol) args[0];
+ MPlist slot = bindings.Find (var);
- private static object minus (object arg, MPlist bindings)
+ if (slot == null)
+ slot = bindings.Push (var, null);
+ slot.val = ((MExpression) args[1]).Eval (bindings);
+ if (slot.val is MText)
+ slot.val = ((MText) slot.val).Dup ();
+ return slot.val;
+ }
+
+ private static void set_pp (MFunction func, string indent, object[] args)
+ {
+ Console.Write ("(set " + (MSymbol) args[0] + " ");
+ ((MExpression) args[1]).pp (indent);
+ Console.Write (")");
+ }
+
+ private static object plus (object[] args, MPlist bindings)
{
- MExpression expr = (MExpression) arg;
+ object val = ((MExpression) args[0]).Eval (bindings);
- int n = (int) expr.Eval (bindings);
- foreach (MExpression e in expr.next)
- n -= (int) e.Eval (bindings);
+ if (val is int)
+ {
+ int n = 0;
+ foreach (MExpression e in args)
+ n += (int) e.Eval (bindings);
+ val = n;
+ }
+ else if (val is MText)
+ {
+ MText mt = new MText ();
+ foreach (MExpression e in args)
+ mt += (MText) e.Eval (bindings);
+ val = mt;
+ }
+ return val;
+ }
+
+ private static object multi (object[] args, MPlist bindings)
+ {
+ int n = 1;
+ foreach (MExpression e in args)
+ n *= (int) e.Eval (bindings);
return n;
}
-#if false
+ private static object minus (object[] args, MPlist bindings)
+ {
+ int n = (int) ((MExpression) args[0]).Eval (bindings);
+ if (args.Length == 1)
+ return - n;
+ for (int i = 1; i < args.Length; i++)
+ n -= (int) ((MExpression) args[i]).Eval (bindings);
+ return n;
+ }
- if (key == Mslash)
+ private static object divide (object[] args, MPlist bindings)
{
- int n = Plist.Eval (env);
- foreach (MPlist plist in Plist.next)
- n /= plist.Eval (env);
+ int n = (int) ((MExpression) args[0]).Eval (bindings);
+ for (int i = 1; i < args.Length; i++)
+ n /= (int) ((MExpression) args[i]).Eval (bindings);
return n;
}
- if (key == Mpercent)
+
+ private static object percent (object[] args, MPlist bindings)
+ {
+ int n = (int) ((MExpression) args[0]).Eval (bindings);
+ for (int i = 1; i < args.Length; i++)
+ n %= (int) ((MExpression) args[i]).Eval (bindings);
+ return n;
+ }
+
+ private static object logior (object[] args, MPlist bindings)
{
- return Plist.Eval (env) % Plist.next.Eval (env);
+ int n = (int) ((MExpression) args[0]).Eval (bindings);
+ for (int i = 1; i < args.Length; i++)
+ n |= (int) ((MExpression) args[i]).Eval (bindings);
+ return n;
}
- if (key == Mlogior)
+
+ private static object logand (object[] args, MPlist bindings)
+ {
+ int n = (int) ((MExpression) args[0]).Eval (bindings);
+ for (int i = 1; i < args.Length; i++)
+ n &= (int) ((MExpression) args[i]).Eval (bindings);
+ return n;
+ }
+
+ private static object pluseq (object[] args, MPlist bindings)
{
- return Plist.Eval (env) | Plist.next.Eval (env);
+ MPlist slot = find_binding (args, bindings);
+ object val = slot.val;
+
+ if (val is int)
+ {
+ int n = (int) val;
+ for (int i = 1; i < args.Length; i++)
+ n += (int) ((MExpression) args[i]).Eval (bindings);
+ slot.val = n;
+ }
+ else if (val is MText)
+ {
+ MText mt = (MText) val;
+ for (int i = 1; i < args.Length; i++)
+ mt.Cat ((MText) ((MExpression) args[i]).Eval (bindings));
+ }
+ return slot.val;
}
- if (key == Mlogand)
+
+ private static object multieq (object[] args, MPlist bindings)
{
- return Plist.Eval (env) & Plist.next.Eval (env);
+ MPlist slot = find_binding (args, bindings);
+ int n = (int) slot.val;
+ for (int i = 1; i < args.Length; i++)
+ n *= (int) ((MExpression) args[i]).Eval (bindings);
+ return (slot.val = n);
}
- if (key == Mlshift)
+
+ private static object minuseq (object[] args, MPlist bindings)
{
- return Plist.Eval (env) << Plist.next.Eval (env);
+ MPlist slot = find_binding (args, bindings);
+ int n = (int) slot.val;
+ for (int i = 1; i < args.Length; i++)
+ n -= (int) ((MExpression) args[i]).Eval (bindings);
+ return (slot.val = n);
}
- if (key == Mrshift)
+
+ private static object divideeq (object[] args, MPlist bindings)
{
- return Plist.Eval (env) >> Plist.next.Eval (env);
+ MPlist slot = find_binding (args, bindings);
+ int n = (int) slot.val;
+ for (int i = 1; i < args.Length; i++)
+ n /= (int) ((MExpression) args[i]).Eval (bindings);
+ return (slot.val = n);
}
- if (key == Mset)
+
+ private static object percenteq (object[] args, MPlist bindings)
{
- MSymbol var = (MSymbol) Plist.val;
+ MPlist slot = find_binding (args, bindings);
+ int n = (int) slot.val;
+ for (int i = 1; i < args.Length; i++)
+ n %= (int) ((MExpression) args[i]).Eval (bindings);
+ return (slot.val = n);
+ }
+ private static object logioreq (object[] args, MPlist bindings)
+ {
+ MPlist slot = find_binding (args, bindings);
+ int n = (int) slot.val;
+ for (int i = 1; i < args.Length; i++)
+ n |= (int) ((MExpression) args[i]).Eval (bindings);
+ return (slot.val = n);
}
-#endif
- }
- public class MExpression : MPlist
- {
- internal Dictionary<MSymbol, MFunction> FunctionTable;
+ private static object logandeq (object[] args, MPlist bindings)
+ {
+ MPlist slot = find_binding (args, bindings);
+ int n = (int) slot.val;
+ for (int i = 1; i < args.Length; i++)
+ n &= (int) ((MExpression) args[i]).Eval (bindings);
+ return (slot.val = n);
+ }
+
+ private static object lshift (object[] args, MPlist bindings)
+ {
+ int n1 = (int) ((MExpression) args[0]).Eval (bindings);
+ int n2 = (int) ((MExpression) args[1]).Eval (bindings);
+ return n1 << n2;
+ }
+
+ private static object lshifteq (object[] args, MPlist bindings)
+ {
+ MPlist slot = find_binding (args, bindings);
+ int n1 = (int) slot.val;
+ int n2 = (int) ((MExpression) args[1]).Eval (bindings);
+ return (slot.val = (n1 << n2));
+ }
+
+ private static object rshift (object[] args, MPlist bindings)
+ {
+ int n1 = (int) ((MExpression) args[0]).Eval (bindings);
+ int n2 = (int) ((MExpression) args[1]).Eval (bindings);
+ return n1 >> n2;
+ }
+
+ private static object rshifteq (object[] args, MPlist bindings)
+ {
+ MPlist slot = find_binding (args, bindings);
+ int n1 = (int) slot.val;
+ int n2 = (int) ((MExpression) args[1]).Eval (bindings);
+ return (slot.val = (n1 >> n2));
+ }
+
+ private static object eq (object[] args, MPlist bindings)
+ {
+ int n = (int) ((MExpression) args[0]).Eval (bindings);
+ for (int i = 1; i < args.Length; i++)
+ if (n != (int) ((MExpression) args[i]).Eval (bindings))
+ return 0;
+ return 1;
+ }
+
+ private static object noteq (object[] args, MPlist bindings)
+ {
+ int n1 = (int) ((MExpression) args[0]).Eval (bindings);
+ int n2 = (int) ((MExpression) args[1]).Eval (bindings);
+ return (n1 != n2);
+ }
+
+ private static object less (object[] args, MPlist bindings)
+ {
+ int n = (int) ((MExpression) args[0]).Eval (bindings);
+ for (int i = 1; i < args.Length; i++)
+ {
+ int n1 = (int) ((MExpression) args[i]).Eval (bindings);
+ if (n >= n1)
+ return 0;
+ n = n1;
+ }
+ return 1;
+ }
+
+ private static object lesseq (object[] args, MPlist bindings)
+ {
+ int n = (int) ((MExpression) args[0]).Eval (bindings);
+ for (int i = 1; i < args.Length; i++)
+ {
+ int n1 = (int) ((MExpression) args[i]).Eval (bindings);
+ if (n > n1)
+ return 0;
+ n = n1;
+ }
+ return 1;
+ }
+
+ private static object more (object[] args, MPlist bindings)
+ {
+ int n = (int) ((MExpression) args[0]).Eval (bindings);
+ for (int i = 1; i < args.Length; i++)
+ {
+ int n1 = (int) ((MExpression) args[i]).Eval (bindings);
+ if (n <= n1)
+ return 0;
+ n = n1;
+ }
+ return 1;
+ }
+
+ private static object moreeq (object[] args, MPlist bindings)
+ {
+ int n = (int) ((MExpression) args[0]).Eval (bindings);
+ for (int i = 1; i < args.Length; i++)
+ {
+ int n1 = (int) ((MExpression) args[i]).Eval (bindings);
+ if (n < n1)
+ return 0;
+ n = n1;
+ }
+ return 1;
+ }
+
+ private static object progn (object[] args, MPlist bindings)
+ {
+ object result = null;
+
+ foreach (MExpression e in args)
+ result = e.Eval (bindings);
+ return result;
+ }
+
+ private static void block_pp (MFunction func,
+ string indent, object[] args)
+ {
+ bool first = true;
+
+ Console.Write ("(");
+ indent += " ";
+ foreach (MExpression e in args)
+ {
+ if (first)
+ first = false;
+ else
+ Console.Write ("\n" + indent);
+ e.pp (indent);
+ }
+ Console.Write (")");
+ }
+
+ private static object cond (object[] args, MPlist bindings)
+ {
+ foreach (MExpression[] elist in args)
+ {
+ int i = (int) elist[0].Eval (bindings);
+ if (i != 0)
+ return progn ((object[]) elist, bindings);
+ }
+ return 0;
+ }
+
+ private static void cond_pp (MFunction func,
+ string indent, object[] args)
+ {
+ Console.Write ("(cond");
+ indent += " ";
+ foreach (MExpression[] expr_list in args)
+ {
+ Console.Write ("\n" + indent + "(");
+ bool first = true;
+ foreach (MExpression e in expr_list)
+ {
+ if (first)
+ first = false;
+ else
+ Console.Write (" ");
+ e.pp (indent);
+ }
+ Console.Write (")");
+ }
+ Console.Write (")");
+ }
+
+ private static object ifclause (object[] args, MPlist bindings)
+ {
+ object result = 0;
+
+ if ((int) ((MExpression) args[0]).Eval (bindings) != 0)
+ result = ((MExpression) args[1]).Eval (bindings);
+ else
+ for (int i = 2; i < args.Length; i++)
+ result = ((MExpression) args[i]).Eval (bindings);
+ return result;
+ }
+
+ private static void if_pp (MFunction func,
+ string indent, object[] args)
+ {
+ Console.Write ("(if ");
+ ((MExpression) args[0]).pp (indent + " ");
+ Console.Write ("\n" + indent + " ");
+ ((MExpression) args[1]).pp (indent + " ");
+ bool first = true;
+ indent += " ";
+ for (int i = 2; i < args.Length; i++)
+ {
+ if (first)
+ {
+ Console.Write ("\n" + indent);
+ first = false;
+ }
+ else
+ Console.Write (" ");
+ ((MExpression) args[i]).pp (indent);
+ }
+ }
+
+ private static object whileclause (object[] args, MPlist bindings)
+ {
+ object result = 0;
+
+ while ((int) ((MExpression) args[0]).Eval (bindings) != 0)
+ for (int i = 1; i < args.Length; i++)
+ result = ((MExpression) args[i]).Eval (bindings);
+ return result;
+ }
+
+ private static void while_pp (MFunction func,
+ string indent, object[] args)
+ {
+ Console.Write ("(while ");
+ ((MExpression) args[0]).pp (indent + " ");
+ bool first = true;
+ indent += " ";
+ for (int i = 1; i < args.Length; i++)
+ {
+ if (first)
+ {
+ Console.Write ("\n" + indent);
+ first = false;
+ }
+ else
+ Console.Write (" ");
+ ((MExpression) args[i]).pp (indent);
+ }
+ }
+ }
+
+ public class FunctionTable
+ {
+ internal Dictionary<MSymbol, MFunction> table
+ = new Dictionary<MSymbol, MFunction> ();
+ }
+
+ private static FunctionTable basic_table = new FunctionTable ();
+
+ public static void Defun (FunctionTable table, string name,
+ Evaluator evaluator, int min_arg, int max_arg,
+ params Type[] arg_types)
+ {
+ MSymbol sym = MSymbol.Of (name);
+ MFunction func = new MFunction (sym, evaluator, min_arg, max_arg,
+ arg_types);
+ table.table[sym] = func;
+ }
+
+ private static MFunction Defun (string name, Evaluator evaluator,
+ int min_arg, int max_arg,
+ params Type[] arg_types)
+ {
+ MSymbol sym = MSymbol.Of (name);
+ MFunction func = new MFunction (sym, evaluator, min_arg, max_arg,
+ arg_types);
+ basic_table.table[sym] = func;
+ return func;
+ }
+
+ private static MFunction Defun (string name, Evaluator evaluator,
+ int min_arg, int max_arg)
+ {
+ return Defun (name, evaluator, min_arg, max_arg, typeof (MExpression));
+ }
+
+ private static MFunction Find (MSymbol name, FunctionTable table)
+ {
+ if (name == MSymbol.integer
+ || name == MSymbol.mtext)
+ return MFunction.literal;
+
+ MFunction func;
+ if ((table == null
+ || ! table.table.TryGetValue (name, out func))
+ && ! basic_table.table.TryGetValue (name, out func))
+ return null;
+ return func;
+ }
+
+ private void invalid_expression (object o)
+ {
+ throw new Exception ("Invalid expresssion: " + o);
+ }
+
+ private void invalid_argument (object o)
+ {
+ throw new Exception ("Invalid argument: " + o);
+ }
private MFunction function;
+ private object[] args;
- public MExpression () : base () { }
+ public MExpression (MSymbol function_name, object[] args,
+ FunctionTable function_table)
+ {
+ function = Find (function_name, function_table);
+ int nargs = args.Length;
+ if (nargs < function.min_arg
+ || (function.max_arg >= 0 && nargs > function.max_arg))
+ throw new Exception ("Invalid number of arguments: " + args);
+ this.args = (object[]) args.Clone ();
+ }
+
+ private MExpression[] expression_list (MPlist plist, FunctionTable table)
+ {
+ int len = plist.Count;
+ MExpression[] expr_list = new MExpression[len];
- public MExpression (Dictionary<MSymbol, MFunction> function_table)
- : base () { FunctionTable = function_table; }
+ for (int i = 0; i < len; i++, plist = plist.next)
+ {
+ if (plist.IsSymbol)
+ expr_list[i] = new MExpression (plist.Symbol);
+ else if (plist.IsMText || plist.IsInteger)
+ expr_list[i] = new MExpression (plist.val);
+ else if (plist.IsPlist)
+ {
+ MPlist p = plist.Plist;
+ if (p.IsSymbol)
+ expr_list[i] = new MExpression (p.Symbol, p.next, table);
+ else
+ expr_list[i] = new MExpression (p, table);
+ }
+ else
+ invalid_expression (plist.val);
+ }
+ return expr_list;
+ }
- public new MExpression Add (MPlist plist)
+ // EXPR = SYMBOL | MTEXT | INTEGER | FUNCALL | EXPRLIST
+ // FUNCALL = '(' SYMBOL EXPR* ')'
+ // EXPRLIST = '(' EXPR* ')'
+
+ // EXPRLIST: PLIST = EXPR ...
+ public MExpression (MPlist plist, FunctionTable table)
{
- if (plist.IsPlist)
+ function = MFunction.block;
+ args = expression_list (plist, table);
+ }
+
+ // FUNCALL: NAME = FUNCTION-NAME, ARG-LIST = EXPR ...
+ private MExpression (MSymbol name, MPlist arg_list, FunctionTable table)
+ {
+ function = Find (name, table);
+ if (function == null)
+ throw new Exception ("Unknown function: " + name);
+
+ int nargs = arg_list.Count;
+ if (nargs < function.min_arg
+ || (function.max_arg >= 0 && nargs > function.max_arg))
+ throw new Exception ("Invalid number of arguments: " + nargs);
+ args = new object[nargs];
+
+ int i = 0;
+ Type arg_type = typeof (MExpression);
+ foreach (MPlist p in arg_list)
{
- MPlist pl = plist.Plist;
-
- if (! pl.IsSymbol)
- throw new Exception ("Invalid expression: " + plist);
- MExpression e = new MExpression (FunctionTable);
- pl.key = pl.Symbol;
- foreach (MPlist p in pl.next)
- e.Add (p);
- pl.val = e;
- return Add (pl);
+ if (i < function.arg_types.Length)
+ arg_type = function.arg_types[i];
+ if (arg_type == typeof (MExpression))
+ {
+ if (p.IsSymbol)
+ args[i++] = new MExpression (p.Symbol);
+ else if (p.IsMText || p.IsInteger)
+ args[i++] = new MExpression (p.val);
+ else if (p.IsPlist)
+ {
+ MPlist p0 = p.Plist;
+ if (p0.IsSymbol)
+ args[i++] = new MExpression (p0.Symbol, p0.next, table);
+ else
+ args[i++] = new MExpression (p0, table);
+ }
+ else
+ invalid_expression (p.val);
+ }
+ else if (arg_type == typeof (MExpression[]))
+ {
+ if (! p.IsPlist)
+ invalid_argument (p.val);
+ args[i++] = expression_list (p.Plist, table);
+ }
+ else if (arg_type == typeof (MSymbol))
+ {
+ if (! p.IsSymbol)
+ invalid_argument (p.val);
+ args[i++] = p.Symbol;
+ }
+ else
+ args[i++] = p.val;
}
- return Add (plist.key, plist.val);
}
- public new MExpression Add (MSymbol function_name, object arg)
+ public MExpression (MSymbol sym)
{
- MExpression expr = this, e = new MExpression ();
+ function = MFunction.varref;
+ args = new object[1];
+ args[0] = sym;
+ }
- while (! expr.IsEmpty)
- expr = (MExpression) expr.next;
- expr.key = function_name;
- expr.val = arg;
- expr.next = e;
- expr.FunctionTable = FunctionTable;
- expr.function = MFunction.Find (function_name, FunctionTable);
- return expr;
+ public MExpression (object obj)
+ {
+ function = MFunction.literal;
+ args = new object[1];
+ args[0] = obj;
}
public object Eval (MPlist bindings)
{
- return function.Call (val, bindings);
+ return function.Call (args, bindings);
+ }
+
+ private void pp (string indent)
+ {
+ if (function == MFunction.varref
+ || function == MFunction.literal)
+ {
+ if (args[0] is MText)
+ Console.Write ("\"{0}\"", args[0]);
+ else
+ Console.Write (args[0]);
+ }
+ else
+ function.pp (function, indent, args);
}
+
+ public void PretyPrint () { pp (""); }
}
-}
\ No newline at end of file
+}