*** empty log message ***
authorhanda <handa>
Fri, 24 Jul 2009 06:46:41 +0000 (06:46 +0000)
committerhanda <handa>
Fri, 24 Jul 2009 06:46:41 +0000 (06:46 +0000)
MExpression.cs
MPlist.cs
eval.txt
expr.cs

index 7da715e..ccc4878 100644 (file)
@@ -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 (""); }
   }
 }
index a566dbd..e62fdb4 100644 (file)
--- 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;
index 174896d..dbb567b 100644 (file)
--- 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 (file)
--- 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);
   }