From: handa Date: Thu, 23 Jul 2009 12:42:35 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=3ae490784a2d2a150d2f918edf52586681e256b3;p=m17n%2Fm17n-lib-cs.git *** empty log message *** --- diff --git a/MExpression.cs b/MExpression.cs index 1affae0..7da715e 100644 --- a/MExpression.cs +++ b/MExpression.cs @@ -7,176 +7,715 @@ using M17N.Core; 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 CommonTable - = new Dictionary (); - 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 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 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 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 table + = new Dictionary (); + } + + 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 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 +} diff --git a/MText.cs b/MText.cs index 05e6fcf..5c916f1 100644 --- a/MText.cs +++ b/MText.cs @@ -440,6 +440,12 @@ namespace M17N.Core return this; } + public MText Cat (MText mt) + { + insert (nchars, mt, 0, mt.Length); + return this; + } + public MText Del (int from, int to) { if (check_range (from, to, true)) diff --git a/eval.txt b/eval.txt index beec40f..174896d 100644 --- a/eval.txt +++ b/eval.txt @@ -1,16 +1,14 @@ ;; -*- lisp -*- -(progn - (cond - (0 (+ X 2 (* 3 4) (- 3 4))) - (1 (+= X 10))) - (if (> 20 X 10) - (progn - (<<= X 2) - (set Y "abc") - (+= Y "def")) - (while (> X 7) - (/= X 2)) - (set Y "ABC") - (set Z (+ Y "def"))) - (insert "kkk")) +(cond + (0 (+ X 2 (* 3 4) (- 3 4)) (set X 4)) + (1 (+= X 10))) +(if (> 20 X 10) + ((<<= X 2) + (set Y "abc") + (+= Y "def")) + (while (> X 7) + (/= X 2)) + (set Y "ABC") + (set Z (+ Y "def"))) +(insert "kkk") diff --git a/expr.cs b/expr.cs index e527b92..a2294a2 100644 --- a/expr.cs +++ b/expr.cs @@ -1,21 +1,43 @@ using System; +using System.Collections.Generic; using System.IO; using M17N; using M17N.Core; public class Test { + static MSymbol Mpreedit = MSymbol.Of ("preedit"); + + public static object insert (object[] args, MPlist bindings) + { + object arg = ((MExpression) args[0]).Eval (bindings); + MPlist slot = bindings.Find (Mpreedit); + MText preedit = (MText) slot.val; + + if (arg is int) + preedit.Cat ((int) arg); + else + preedit.Cat ((MText) arg); + return arg; + } + public static void Main() { - MExpression expr = new MExpression (); + MExpression expr; + MPlist bindings = new MPlist (); + MExpression.FunctionTable func_table = new MExpression.FunctionTable (); + + MExpression.Defun (func_table, "insert", new MExpression.Evaluator (insert), + 1, 1, typeof (MExpression)); + bindings.Add (MSymbol.Of ("X"), 10); + bindings.Add (Mpreedit, new MText ("PREEDIT TEXT")); using (FileStream stream = new FileStream ("eval.txt", FileMode.Open)) { - MPlist plist = new MPlist (stream); - - foreach (MPlist p in plist) - expr.Add (p); + expr = new MExpression (new MPlist (stream), func_table); } - Console.WriteLine (expr+"="+expr.Eval (null)); + expr.PretyPrint (); + Console.WriteLine ("\n => " + expr.Eval (bindings)); + Console.WriteLine (bindings); } }