{
public delegate object Evaluator (object[] args, MPlist bindings);
- internal delegate void PretyPrinter (MFunction func,
+ internal delegate void PrettyPrinter (MFunction func,
string indent, object[] args);
internal class MFunction
internal int min_arg;
internal int max_arg;
internal Type[] arg_types;
+ internal object[] data;
- public PretyPrinter pp;
+ public PrettyPrinter pp;
- private static PretyPrinter default_prety_printer;
- private static PretyPrinter set_prety_printer;
- internal static MFunction literal, varref, block;
+ private static PrettyPrinter default_pretty_printer;
+ private static PrettyPrinter set_pretty_printer;
+ internal static MFunction literal, varref, block, defun;
public MFunction (MSymbol name, Evaluator eval,
- int min_arg, int max_arg, Type[] arg_types)
+ int min_arg, int max_arg, params Type[] arg_types)
{
this.name = name;
this.eval = eval;
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;
+ pp = set_pretty_printer;
else
- pp = default_prety_printer;
+ pp = default_pretty_printer;
}
static MFunction ()
{
- default_prety_printer = new PretyPrinter (default_pp);
- set_prety_printer = new PretyPrinter (set_pp);
+ default_pretty_printer = new PrettyPrinter (default_pp);
+ set_pretty_printer = new PrettyPrinter (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);
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);
+ block.pp = new PrettyPrinter (block_pp);
Defun ("cond", new Evaluator (cond), 1, -1,
- typeof (MExpression[])).pp = new PretyPrinter (cond_pp);
+ typeof (MExpression[])).pp = new PrettyPrinter (cond_pp);
Defun ("if", new Evaluator (ifclause), 2, -1,
- typeof (MExpression)).pp = new PretyPrinter (if_pp);
+ typeof (MExpression)).pp = new PrettyPrinter (if_pp);
Defun ("while", new Evaluator (whileclause), 1, -1,
- typeof (MExpression)).pp = new PretyPrinter (while_pp);
- }
-
- public object Call (object[] args, MPlist bindings)
- {
- if (name == MSymbol.nil)
- return args[0];
- return eval (args, bindings);
+ typeof (MExpression)).pp = new PrettyPrinter (while_pp);
+ defun = Defun ("defun", new Evaluator (define_function), 4, -1,
+ typeof (FunctionTable),
+ typeof (MSymbol),
+ typeof (MPlist),
+ typeof (MExpression));
+ defun.pp = new PrettyPrinter (defun_pp);
}
private static MPlist find_binding (object[] args, MPlist bindings)
return slot;
}
+ public object Call (object[] args, MPlist bindings)
+ {
+ if (name == MSymbol.nil)
+ return args[0];
+ if (eval != null)
+ return eval (args, bindings);
+
+ MPlist arg_symbols = (MPlist) data[0];
+ for (int i = 0; i < args.Length; i++, arg_symbols = arg_symbols.next)
+ bindings = bindings.Cons (arg_symbols.Symbol,
+ ((MExpression) args[i]).Eval (bindings));
+ object result = 0;
+ for (int i = 1; i < data.Length; i++)
+ result = ((MExpression) data[i]).Eval (bindings);
+ return result;
+ }
+
+ // Commonly used pretty-printers.
+
public static void default_pp (MFunction func,
string indent, object[] args)
{
Console.Write (")");
}
+ private static void set_pp (MFunction func, string indent, object[] args)
+ {
+ Console.Write ("(" + func.name + " " + (MSymbol) args[0] + " ");
+ ((MExpression) args[1]).pp (indent);
+ Console.Write (")");
+ }
+
private static object get_value (object[] args, MPlist bindings)
{
return find_binding (args, bindings).val;
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)
{
object val = ((MExpression) args[0]).Eval (bindings);
((MExpression) args[i]).pp (indent);
}
}
+
+ private static object define_function (object[] args, MPlist bindings)
+ {
+ FunctionTable table = (FunctionTable) args[0];
+ MSymbol sym = (MSymbol) args[1];
+ MPlist arg_symbols = (MPlist) args[2];
+ int nargs = arg_symbols.Count;
+ object[] data = new object[args.Length - 2];
+
+ data[0] = args[2];
+ for (int i = 3; i < args.Length; i++)
+ data[i - 2] = args[i];
+
+ MFunction func = new MFunction (sym, null, nargs, nargs,
+ typeof (MExpression));
+ table.table[sym] = func;
+ func.data = data;
+ return null;
+ }
+
+ private static void defun_pp (MFunction func,
+ string indent, object[] args)
+ {
+ Console.Write ("(defun " + args[1] + " " + args[2]);
+ bool first = true;
+ indent += " ";
+ for (int i = 3; i < args.Length; i++)
+ {
+ if (first)
+ {
+ Console.Write ("\n" + indent);
+ first = false;
+ }
+ else
+ Console.Write (" ");
+ ((MExpression) args[i]).pp (indent);
+ }
+ }
}
public class FunctionTable
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;
+ MFunction func = Defun (name, evaluator, min_arg, max_arg, arg_types);
+ table.table[func.name] = func;
}
private static MFunction Defun (string name, Evaluator evaluator,
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);
+ if (function.arg_types.Length > 0)
+ {
+ arg_type = function.arg_types[0];
+ if (arg_type == typeof (FunctionTable))
+ {
+ nargs++;
+ args = new object[nargs];
+ args[i++] = table;
+ }
+ else
+ args = new object[nargs];
+ }
+ else
+ args = new object[nargs];
+
foreach (MPlist p in arg_list)
{
if (i < function.arg_types.Length)
else
args[i++] = p.val;
}
+ if (function == MFunction.defun)
+ function.Call (args, null);
}
public MExpression (MSymbol sym)
function.pp (function, indent, args);
}
- public void PretyPrint () { pp (""); }
+ public void PrettyPrint () { pp (""); }
}
}