From: handa Date: Fri, 24 Jul 2009 06:46:41 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=979b3ac2f471babc8f225af5725bf0230f2eae7d;p=m17n%2Fm17n-lib-cs.git *** empty log message *** --- diff --git a/MExpression.cs b/MExpression.cs index 7da715e..ccc4878 100644 --- a/MExpression.cs +++ b/MExpression.cs @@ -11,7 +11,7 @@ namespace M17N.Core { 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 @@ -21,15 +21,16 @@ namespace M17N.Core 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; @@ -37,15 +38,15 @@ namespace M17N.Core 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); @@ -88,20 +89,19 @@ namespace M17N.Core 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) @@ -114,6 +114,25 @@ namespace M17N.Core 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) { @@ -127,6 +146,13 @@ namespace M17N.Core 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; @@ -145,13 +171,6 @@ namespace M17N.Core 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); @@ -519,6 +538,44 @@ namespace M17N.Core ((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 @@ -533,10 +590,8 @@ namespace M17N.Core 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, @@ -641,10 +696,24 @@ namespace M17N.Core 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) @@ -681,6 +750,8 @@ namespace M17N.Core else args[i++] = p.val; } + if (function == MFunction.defun) + function.Call (args, null); } public MExpression (MSymbol sym) @@ -716,6 +787,6 @@ namespace M17N.Core function.pp (function, indent, args); } - public void PretyPrint () { pp (""); } + public void PrettyPrint () { pp (""); } } } diff --git a/MPlist.cs b/MPlist.cs index a566dbd..e62fdb4 100644 --- a/MPlist.cs +++ b/MPlist.cs @@ -312,6 +312,15 @@ namespace M17N.Core return p.Push (key, val); } + public MPlist Cons (MSymbol key, object val) + { + MPlist plist = new MPlist (); + plist.key = key; + plist.val = val; + plist.next = this; + return plist; + } + public MPlist Clear () { key = MSymbol.nil; diff --git a/eval.txt b/eval.txt index 174896d..dbb567b 100644 --- a/eval.txt +++ b/eval.txt @@ -1,8 +1,13 @@ ;; -*- lisp -*- +(defun temp (a b c) + (+= a 1) + (+ a b c)) + (cond (0 (+ X 2 (* 3 4) (- 3 4)) (set X 4)) (1 (+= X 10))) +(+= X (temp 1 2 3)) (if (> 20 X 10) ((<<= X 2) (set Y "abc") diff --git a/expr.cs b/expr.cs index a2294a2..07aca8b 100644 --- a/expr.cs +++ b/expr.cs @@ -36,7 +36,8 @@ public class Test { expr = new MExpression (new MPlist (stream), func_table); } - expr.PretyPrint (); + Console.WriteLine (bindings); + expr.PrettyPrint (); Console.WriteLine ("\n => " + expr.Eval (bindings)); Console.WriteLine (bindings); }