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;
}
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
{
public MSymbol key;
public object val;
- private MPlist next;
+ public MPlist next;
public MSymbol Key { get { return key; } }
public object Val { get { return val; } }
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
{