commit 51119810287735eed44e00862f44abd87912d718
parent b79426aa1f3e66e7124a25bb63c7c25d8a81a66c
Author: tomas <tomas@logand.com>
Date:   Sat, 10 Oct 2009 22:13:37 +0200
added bind, unbind, frame, unframe and linear *Env with T marking frame
Diffstat:
| M | wl.java |  |  | 204 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- | 
1 file changed, 98 insertions(+), 106 deletions(-)
diff --git a/wl.java b/wl.java
@@ -203,6 +203,7 @@ class wl implements Runnable {
 
     final Any In = mkIsym("*In", mkObj(new In(System.in)));
     final Any Out = mkIsym("*Out", mkObj(System.out));
+    final Any Env = mkIsym("*Env", NIL);
 
     Character peek() {return ((In) In.val().cxr()).peek();}
     Character xchar() {return ((In) In.val().cxr()).xchar();}
@@ -326,75 +327,51 @@ class wl implements Runnable {
         Any A = E.cdr();
         Any Fa = F.car();
         Any Fb = F.cdr();
-        Any O = saveV(Fa, A);
-        Z = xrun(Fb);
-        restoreV(Fa, O);
-        return Z;
-    }
-    Any mapcarEval(Any E) {
-        Any A = mkCons(NIL, NIL);
-        Any Z = A;
-        while(E.isCons()) {
-            Z.cdr(mkCons(eval(E.car()), NIL));
-            Z = Z.cdr();
-            E = E.cdr();
-        }
-        return A.cdr();
-    }
-    Any saveV(Any Fa, Any A) {
-        Any O = NIL;
-        if(Fa.isIsym()) {
+        frame();
+        int n = 0;
+        if(Fa.isIsym()) { // (@ . P) | (L . P) | (NIL . P)
             if(NIL != Fa) {
                 if(At == Fa) {
-                    O = mkCons(Args.val(), NIL);
-                    Args.val(mkCons(NIL, mapcarEval(A)));
+                    bind(Args, mkCons(NIL, mapcarEval(A)));
+                    n++;
                 } else {
-                    O = mkCons(Fa.val(), NIL);
-                    Fa.val(A);
+                    bind(Fa, A);
+                    n++;
                 }
-            } 
-        } else if(Fa.isCons()) {
-            Any B = mkCons(NIL, NIL);
-            Any Z = B;
+            }
+        } else if(Fa.isCons()) { // ((L ...) . P)
             while(Fa.isCons()) {
                 Any X = Fa.car();
                 Fa = Fa.cdr();
-                Z.cdr(mkCons(X.val(), NIL));
-                Z = Z.cdr();
-                X.val(eval(A.car()));
+                bind(X, eval(A.car()));
+                n++;
                 A = A.cdr();
             }
             if(NIL != Fa) {
-                if(At == Fa) {
-                    Z.cdr(mkCons(Args.val(), NIL));
-                    Args.val(mkCons(NIL, mapcarEval(A)));
-                } else {
-                    Z.cdr(mkCons(Fa.val(), NIL));
-                    Fa.val(A);
+                if(At == Fa) { // ((L . @) . P)
+                    bind(Args, mkCons(NIL, mapcarEval(A)));
+                    n++;
+                } else { // ((L . M) . P)
+                    bind(Fa, A);
+                    n++;
                 }
             }
-            O = B.cdr();
-        } else err(Fa, "Don't know how to saveV");
-        return O;
+        } else err(Fa, "Don't know how to bind");
+
+        Z = xrun(Fb);
+        unbind(n);
+        unframe();
+        return Z;
     }
-    void restoreV(Any Fa, Any O) {
-        if(Fa.isIsym()) {
-            if(NIL != Fa) {
-                if(At == Fa) Args.val(O.car());
-                else Fa.val(O.car());
-            }
-        } else if(Fa.isCons()) {
-            while(Fa.isCons()) {
-                Any X = Fa.car();
-                Fa = Fa.cdr();
-                X.val(O.car());
-                O = O.cdr();
-            }
-            if(NIL != Fa) {
-                if(At == Fa) Args.val(O.car());
-                else Fa.val(O.car());
-            }
-        } else err(Fa, "Don't know how to restoreV");
+    Any mapcarEval(Any E) {
+        Any A = mkCons(NIL, NIL);
+        Any Z = A;
+        while(E.isCons()) {
+            Z.cdr(mkCons(eval(E.car()), NIL));
+            Z = Z.cdr();
+            E = E.cdr();
+        }
+        return A.cdr();
     }
     Any applyO(Any E, Any O) { // 'obj 'meth [arg ...]
         Any I = E.cdr();
@@ -427,6 +404,36 @@ class wl implements Runnable {
         }
         return Z;
     }
+    void bind(Any S, Any V) {
+        dbg("   1", Env.val());
+        Env.val(mkCons(mkCons(S, S.val()), Env.val()));
+        S.val(V);
+        dbg("   2", Env.val());
+    }
+    void bind(Any S) {
+        dbg("   1", Env.val());
+        Env.val(mkCons(mkCons(S, S.val()), Env.val()));
+        dbg("   2", Env.val());
+    }
+    void unbind() {
+        dbg("   3", Env.val());
+        Any E = Env.val();
+        Any X = E.car();
+        X.car().val(X.cdr());
+        Env.val(E.cdr());
+        dbg("   4", Env.val());
+    }
+    void unbind(int n) {for(int i = 0; i < n; i++) unbind();}
+    void frame() {
+        dbg("1", Env.val());
+        Env.val(mkCons(T, Env.val()));
+        dbg("2", Env.val());
+    }
+    void unframe() {
+        dbg("3", Env.val());
+        Env.val(Env.val().cdr());
+        dbg("4", Env.val());
+    }
 
     void fn(String Nm, Fn F) {
         Any Z = Sd.get(Nm);
@@ -443,10 +450,15 @@ class wl implements Runnable {
         Sd.put("*Args", Args);
         Sd.put("*In", In);
         Sd.put("*Out", Out);
+        Sd.put("*Env", Env);
         Sd.put("java.lang.Class", mkIsym("java.lang.Class", mkObj(Class.class)));
 
-        fn("run", new Fn() {public Any fn(Any E) {return xrun(eval(E.cdr().car()));}});
-        fn("eval", new Fn() {public Any fn(Any E) {return eval(eval(E.cdr().car()));}});
+        fn("run", new Fn() {public Any fn(Any E) {
+            return xrun(eval(E.cdr().car()));
+        }});
+        fn("eval", new Fn() {public Any fn(Any E) {
+            return eval(eval(E.cdr().car()));
+        }});
         fn("quote", new Fn() {public Any fn(Any E) {return E.cdr();}});
         fn("car", new Fn() {public Any fn(Any E) {return eval(E.cdr().car()).car();}});
         fn("cdr", new Fn() {public Any fn(Any E) {return eval(E.cdr().car()).cdr();}});
@@ -521,10 +533,6 @@ class wl implements Runnable {
                 }
             }
         }});
-        fn("up", new Fn() {public Any fn(Any E) {
-            // TODO
-            return NIL;
-        }});        
         fn("==", new Fn() {public Any fn(Any E) {
             Any X = E.cdr();
             return eval(X.car()) == eval(X.cdr().car()) ? T : NIL;
@@ -691,35 +699,24 @@ class wl implements Runnable {
             Any Z = NIL;
             Any I = E.cdr();
             Any L = I.car();
-            if(L.isCons()) {
-                Any A = L;
-                Any B = mkCons(NIL, NIL);
-                Any C = B;
-                while(A.isCons()) {
-                    Any K = A.car();
-                    A = A.cdr();
-                    Any V = eval(A.car());
-                    A = A.cdr();
-                    C.cdr(mkCons(K.val(), NIL));
-                    C = C.cdr();
-                    K.val(V);
+            if(L.isCons()) { // (let (K 'V ...) . P)
+                int n = 0;
+                while(L.isCons()) {
+                    Any K = L.car();
+                    L = L.cdr();
+                    Any V = eval(L.car());
+                    L = L.cdr();
+                    bind(K, V);
+                    n++;
                 }
                 Z = xrun(I.cdr());
-                A = L;
-                C = B.cdr();
-                while(A.isCons()) {
-                    Any K = A.car();
-                    A = A.cdr().cdr();
-                    K.val(C.car());
-                    C = C.cdr();
-                }
-            } else if(L.isIsym()) {
+                unbind(n);
+            } else if(L.isIsym()) { // (let L 'V . P)
                 I = I.cdr();
                 Any V = eval(I.car());
-                Any O = L.val();
-                L.val(V);
+                bind(L, V);
                 Z = xrun(I.cdr());
-                L.val(O);
+                unbind();
             } else err(E, "Don't know how to let");
             return Z;
         }});
@@ -727,32 +724,27 @@ class wl implements Runnable {
             Any Z = NIL;
             Any I = E.cdr();
             Any L = I.car();
-            if(L.isCons()) {
-                Any A = L;
-                Any B = mkCons(NIL, NIL);
-                Any C = B;
-                while(A.isCons()) {
-                    Any K = A.car();
-                    A = A.cdr();
-                    C.cdr(mkCons(K.val(), NIL));
-                    C = C.cdr();
+            if(L.isCons()) { // (use (K ...) . P)
+                int n = 0;
+                while(L.isCons()) {
+                    Any K = L.car();
+                    L = L.cdr();
+                    bind(K);
+                    n++;
                 }
                 Z = xrun(I.cdr());
-                A = L;
-                C = B.cdr();
-                while(A.isCons()) {
-                    Any K = A.car();
-                    A = A.cdr();
-                    K.val(C.car());
-                    C = C.cdr();
-                }
-            } else if(L.isIsym()) {
-                Any O = L.val();
+                unbind(n);
+            } else if(L.isIsym()) { // (use L . P)
+                bind(L);
                 Z = xrun(I.cdr());
-                L.val(O);
+                unbind();
             } else err(E, "Don't know how to let");
             return Z;
         }});
+        fn("up", new Fn() {public Any fn(Any E) {
+            // TODO
+            return NIL;
+        }});
 
         fn("jnew", new Fn() {public Any fn(Any E) { // jnew 'cls [arg ...]
             Any I = E.cdr();