From a5e3084687ec104febe919adeff34dca72c9797b Mon Sep 17 00:00:00 2001 From: handa Date: Mon, 20 Jul 2009 23:58:49 +0000 Subject: [PATCH] *** empty log message *** --- MExpression.cs | 194 +++++++++++++++++++++++++++++++++++--------------------- MPlist.cs | 18 +++--- Makefile | 13 ++-- eval.txt | 2 + expr.cs | 12 +++- 5 files changed, 148 insertions(+), 91 deletions(-) create mode 100644 eval.txt diff --git a/MExpression.cs b/MExpression.cs index 588a5dc..1affae0 100644 --- a/MExpression.cs +++ b/MExpression.cs @@ -7,17 +7,28 @@ using M17N.Core; namespace M17N.Core { - public delegate object MEvaluator (MExpression args, MPlist bindings); + public delegate object MEvaluator (object arg, MPlist bindings); public class MFunction { - internal readonly MSymbol name; + MSymbol name; internal readonly MEvaluator evaluator; + public static Dictionary CommonTable = new Dictionary (); + public static readonly MFunction Identity + = new MFunction (MSymbol.nil, null); + + static MFunction () + { + new MFunction (MSymbol.Of ("+"), new MEvaluator (plus)); + new MFunction (MSymbol.Of ("*"), new MEvaluator (multi)); + new MFunction (MSymbol.Of ("-"), new MEvaluator (minus)); + } internal MFunction (MSymbol name, MEvaluator evaluator) { + this.name = name; this.evaluator = evaluator; CommonTable[name] = this; } @@ -29,106 +40,143 @@ namespace M17N.Core dict[name] = this; } - public object Call (MExpression args, MPlist bindings) + internal static MFunction Find (MSymbol name, + Dictionary Table) + { + if (name == MSymbol.integer + || name == MSymbol.plist + || name == MSymbol.mtext + || name == MSymbol.symbol) + return Identity; + + MFunction func; + if ((Table == null + || ! Table.TryGetValue (name, out func)) + && ! MFunction.CommonTable.TryGetValue (name, out func)) + throw new Exception ("Unknown function: " + name); + return func; + } + + public object Call (object arg, MPlist bindings) { - return evaluator (args, bindings); + if (name == MSymbol.nil) + return arg; + return evaluator (arg, bindings); } - private object plus (MExpression args) + private static object plus (object arg, MPlist bindings) { + MExpression expr = (MExpression) arg; + int n = 0; - foreach (MExpression expr in args) - n += expr.Eval (bindings); + foreach (MExpression e in expr) + n += (int) e.Eval (bindings); return n; } - private object multiply (MExpression args) + private static object multi (object arg, MPlist bindings) { + MExpression expr = (MExpression) arg; + int n = 1; - foreach (MExpression expr in args) - n *= expr.Eval (bindings); + foreach (MExpression e in expr) + n *= (int) e.Eval (bindings); return n; } -#if false - if (key == Mminus) - { - int n = - Plist.Eval (env); - foreach (MPlist plist in Plist.next) - n -= plist.Eval (env); - return n; - } - if (key == Mslash) - { - int n = Plist.Eval (env); - foreach (MPlist plist in Plist.next) - n /= plist.Eval (env); - return n; - } - if (key == Mpercent) - { - return Plist.Eval (env) % Plist.next.Eval (env); - } - if (key == Mlogior) - { - return Plist.Eval (env) | Plist.next.Eval (env); - } - if (key == Mlogand) - { - return Plist.Eval (env) & Plist.next.Eval (env); - } - if (key == Mlshift) - { - return Plist.Eval (env) << Plist.next.Eval (env); - } - if (key == Mrshift) - { - return Plist.Eval (env) >> Plist.next.Eval (env); - } - if (key == Mset) - { - MSymbol var = (MSymbol) Plist.val; - - } -#endif - } + private static object minus (object arg, MPlist bindings) + { + MExpression expr = (MExpression) arg; - public class MBindings : MPlist - { - public MBindings () : base () { } + int n = (int) expr.Eval (bindings); + foreach (MExpression e in expr.next) + n -= (int) e.Eval (bindings); + return n; + } - public new MBindings Push (MSymbol variable, object value) - { - base.Push (variable, value); - } +#if false - public override string ToString () + if (key == Mslash) + { + int n = Plist.Eval (env); + foreach (MPlist plist in Plist.next) + n /= plist.Eval (env); + return n; + } + if (key == Mpercent) + { + return Plist.Eval (env) % Plist.next.Eval (env); + } + if (key == Mlogior) + { + return Plist.Eval (env) | Plist.next.Eval (env); + } + if (key == Mlogand) + { + return Plist.Eval (env) & Plist.next.Eval (env); + } + if (key == Mlshift) + { + return Plist.Eval (env) << Plist.next.Eval (env); + } + if (key == Mrshift) { - string str = "("; - foreach (MBindings b in this) - { - if (b != this) - str += ", "; - str += b.key + " = " + b.val; - } - return str + ")"; + return Plist.Eval (env) >> Plist.next.Eval (env); } + if (key == Mset) + { + MSymbol var = (MSymbol) Plist.val; + + } +#endif } public class MExpression : MPlist { + internal Dictionary FunctionTable; + + private MFunction function; + public MExpression () : base () { } - public MExpression Append (MFunction func, MExpression args) + public MExpression (Dictionary function_table) + : base () { FunctionTable = function_table; } + + public new MExpression Add (MPlist plist) { - base.Add (op, (MPlist) args); - return this; + if (plist.IsPlist) + { + 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); + } + return Add (plist.key, plist.val); } - public object Eval () + public new MExpression Add (MSymbol function_name, object arg) { - + MExpression expr = this, e = new MExpression (); + + 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 object Eval (MPlist bindings) + { + return function.Call (val, bindings); } } } \ No newline at end of file diff --git a/MPlist.cs b/MPlist.cs index 0535d86..a566dbd 100644 --- a/MPlist.cs +++ b/MPlist.cs @@ -11,7 +11,7 @@ namespace M17N.Core { public MSymbol key; public object val; - private MPlist next; + public MPlist next; public MSymbol Key { get { return key; } } public object Val { get { return val; } } @@ -149,15 +149,15 @@ namespace M17N.Core public bool IsEmpty { get { return next == null; } } - internal bool IsSymbol { get { return Key == MSymbol.symbol; } } - internal bool IsMText { get { return Key == MSymbol.mtext; } } - internal bool IsPlist { get { return Key == MSymbol.plist; } } - internal bool IsInteger { get { return Key == MSymbol.integer; } } + public bool IsSymbol { get { return Key == MSymbol.symbol; } } + public bool IsMText { get { return Key == MSymbol.mtext; } } + public bool IsPlist { get { return Key == MSymbol.plist; } } + public bool IsInteger { get { return Key == MSymbol.integer; } } - internal MSymbol Symbol { get { return (MSymbol) val; } } - internal MText Text { get { return (MText) val; } } - internal MPlist Plist { get { return (MPlist) val; } } - internal int Integer { get { return (int) val; } } + public MSymbol Symbol { get { return (MSymbol) val; } } + public MText Text { get { return (MText) val; } } + public MPlist Plist { get { return (MPlist) val; } } + public int Integer { get { return (int) val; } } public int Count { diff --git a/Makefile b/Makefile index 1148bd8..c446c26 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CS=gmcs M17N_SRC = M17N.cs CORE_SRC = MSymbol.cs MPlist.cs MCharTable.cs MText.cs MDatabase.cs -INPUT_SRC = MInputMethod.cs +EXPR_SRC = MExpression.cs EXAMPLE = symbol.exe plist.exe chartab.exe text.exe textprop.exe database.exe TEST = rearsticky.exe frontsticky.exe \ sensitive.exe frontsensitive.exe rearsensitive.exe @@ -15,17 +15,14 @@ M17N.dll: ${M17N_SRC} M17NCore.dll: M17N.dll ${CORE_SRC} $(CS) -out:$@ -t:library -r:M17N.dll ${CORE_SRC} -M17NInput.dll: M17N.dll M17NCore.dll ${INPUT_SRC} - $(CS) -out:$@ -t:library -r:M17N.dll -r:M17NCore.dll ${INPUT_SRC} +M17NExpr.dll: M17N.dll M17NCore.dll ${EXPR_SRC} + $(CS) -out:$@ -t:library -r:M17N.dll -r:M17NCore.dll ${EXPR_SRC} -%.exe: %.cs M17NCore.dll - $(CS) -codepage:65001 -r:M17N.dll -r:M17NCore $< +%.exe: %.cs + $(CS) -codepage:65001 -r:M17N.dll -r:M17NCore -r:M17NExpr $< clean: rm -f *.dll *.exe temp.exe: temp.cs $(CS) temp.cs - -expr.exe: M17N.dll M17NCore.dll MExpression.cs expr.cs - $(CS) -out:$@ -t:library -r:M17N.dll -r:M17NCore.dll MExpression.cs expr.cs diff --git a/eval.txt b/eval.txt new file mode 100644 index 0000000..6e4ca98 --- /dev/null +++ b/eval.txt @@ -0,0 +1,2 @@ +(+ 1 2 (* 3 4) (- 3 4)) + diff --git a/expr.cs b/expr.cs index 1d4af26..e527b92 100644 --- a/expr.cs +++ b/expr.cs @@ -1,5 +1,5 @@ using System; -using System.Collections.Generic; +using System.IO; using M17N; using M17N.Core; @@ -7,5 +7,15 @@ public class Test { public static void Main() { + MExpression expr = new MExpression (); + + using (FileStream stream = new FileStream ("eval.txt", FileMode.Open)) + { + MPlist plist = new MPlist (stream); + + foreach (MPlist p in plist) + expr.Add (p); + } + Console.WriteLine (expr+"="+expr.Eval (null)); } } -- 1.7.10.4