*** empty log message ***
authorhanda <handa>
Mon, 20 Jul 2009 23:58:49 +0000 (23:58 +0000)
committerhanda <handa>
Mon, 20 Jul 2009 23:58:49 +0000 (23:58 +0000)
MExpression.cs
MPlist.cs
Makefile
eval.txt [new file with mode: 0644]
expr.cs

index 588a5dc..1affae0 100644 (file)
@@ -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<MSymbol, MFunction> CommonTable
       = new Dictionary<MSymbol, MFunction> ();
+    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<MSymbol, MFunction> 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<MSymbol, MFunction> FunctionTable;
+
+    private MFunction function;
+
     public MExpression () : base () { }
 
-    public MExpression Append (MFunction func, MExpression args)
+    public MExpression (Dictionary<MSymbol, MFunction> 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
index 0535d86..a566dbd 100644 (file)
--- 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
     {
index 1148bd8..c446c26 100644 (file)
--- 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 (file)
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 (file)
--- 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));
   }
 }