commit f52a20b38a71df5f713542e6a8ad47ac6dab7bd8
parent 1fd98e0abcb9c888d5a013561cce5e99aecffa8b
Author: tomas <tomas@logand.com>
Date:   Sun, 11 Oct 2009 11:22:23 +0200
*Stk, comment reader, run|eval 1 up (undo/redo), loop fix, 'set', 'sym?', 'up.' and more
Diffstat:
| M | java.wl |  |  | 77 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- | 
| M | wl.java |  |  | 122 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- | 
2 files changed, 177 insertions(+), 22 deletions(-)
diff --git a/java.wl b/java.wl
@@ -30,21 +30,30 @@
 
 (de rest () (cdr *Args))
 (de args () (bool (cdr *Args)))
+(de next ()
+   (set *Args (cadr *Args))
+   (con *Args (cddr *Args))
+   (car *Args) )
 
 (de list @ (rest))
 
 (de nil P (run P 1) NIL)
 (de t P (run P 1) T)
 
-(de prog P (run P 1))
-(de prog1 (E . P) (up @ E) (run P 1) E)
-(de prog2 (E F . P) (up @ F) (run P 1) F)
-
 (de if (C . L)
    (loop
-      (T C (up @ @) (eval (car L) 1))
+      (T C (up. '@ @) (eval (car L) 1))
       (T T (run (cdr L) 1)) ) )
 
+# (de up L
+#    (let C (pop 'L)
+#      (print C L *Stk *Env)
+#       (if (sym? C)
+#          (up. 2 C (eval (car L) 1))
+#          (up. (+ 1 (eval C 1)) (pop 'L) (eval (car L) 1)) )
+#      (print C L *Stk *Env)
+#          ) )
+
 (de ifn (C . L)
    (loop
       (NIL C (eval (pop 'L) 1))
@@ -60,6 +69,10 @@
       (pop 'L)
       (T T (run L 1)) ) )
 
+(de prog P (run P 1))
+(de prog1 (E . P) (up @ E) (run P 1) E)
+(de prog2 (E F . P) (up @ F) (run P 1) F)
+
 (de when (C . P)
    (loop
       (T C (up @ @) (run P 1))
@@ -85,13 +98,13 @@
          (T (eval C 1) Z)
          (def 'Z (run L 1)) ) ) )
 
-(de set L
-   (while L
-      (def (eval (pop 'L) 1) (eval (pop 'L) 1)) ) )
-
 (de setq L
-   (while L
-      (def (pop 'L) (eval (pop 'L) 1)) ) )
+   (let (V NIL K)
+      (while L
+         (def 'K (pop 'L))
+         (def 'V (eval (pop 'L) 1))
+         (up. K V) )
+      V ) )
 
 (de and L
    (loop
@@ -122,6 +135,12 @@
       (and (not Y) T)
       (and Y T) ) )
 
+(de let? L
+   (let (K (pop 'L) V (eval (pop 'L) 1))
+      (when V
+         (def 'K V)
+         (run L 1 '(K)) ) ) ) # TODO
+
 (de println @
    (pass print)
    (prin "^J") )
@@ -141,3 +160,39 @@
       (while L
          (setq C (pop 'L))
          (def C (jclass (pack P "." C))) ) ) )
+
+(setq *Int (jclass 'java.math.BigInteger))
+
+(de - L
+   (let? Z (eval (pop 'L) 1)
+      (ifn L
+         ((jfield *Int 'ZERO) 'subtract Z)
+         (loop
+            (NIL L Z)
+            (setq Y (eval (pop 'L) 1))
+            (NIL Y)
+            (setq Z (Z 'subtract Y)) ) ) ) )
+
+(de * L
+   (let? Z (eval (pop 'L) 1)
+      (loop
+         (NIL L Z)
+         (setq Y (eval (pop 'L) 1))
+         (NIL Y)
+         (setq Z (Z 'multiply Y)) ) ) )
+
+(de / L
+   (let? Z (eval (pop 'L) 1)
+      (loop
+         (NIL L Z)
+         (setq Y (eval (pop 'L) 1))
+         (NIL Y)
+         (setq Z (Z 'divide Y)) ) ) )
+
+(de % L
+   (let? Z (eval (pop 'L) 1)
+      (loop
+         (NIL L Z)
+         (setq Y (eval (pop 'L) 1))
+         (NIL Y)
+         (setq Z (Z 'reminder Y)) ) ) )
diff --git a/wl.java b/wl.java
@@ -204,6 +204,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);
+    final Any Stk = mkIsym("*Stk", NIL);
 
     Character peek() {return ((In) In.val().cxr()).peek();}
     Character xchar() {return ((In) In.val().cxr()).xchar();}
@@ -211,17 +212,24 @@ class wl implements Runnable {
     void eof(Any X) {((In) In.val().cxr()).eof(X);}
 
     boolean charIn(Character C, String L) {return 0 <= L.indexOf(C);}
+    void skip1() {
+        Character Z;
+        while(null != (Z = peek()) && charIn(Z, " \t\n\r")) xchar();
+    }
     void skip() {
+        skip1();
         Character Z;
-        while(null != (Z = peek()) && charIn(Z, " \t\n\r"))
-            xchar();
+        while(null != (Z = peek()) && '#' == Z) {
+            while(null != (Z = peek()) && '\n' != Z) xchar();
+            skip1();
+        }
     }
     Any symbol() {
         Character C = xchar();
-        if(charIn(C, "()\" \t\n\r")) err(C, "Symbol expected");
+        if(charIn(C, "#()\" \t\n\r")) err(C, "Symbol expected");
         StringBuffer L = new StringBuffer();
         L.append(C);
-        while((null != (C = peek())) && !charIn(C, "()\" \t\n\r"))
+        while((null != (C = peek())) && !charIn(C, "#()\" \t\n\r"))
             L.append(xchar());
         String M = L.toString();
         return intern(M);
@@ -251,6 +259,7 @@ class wl implements Runnable {
         Character X = peek();
         if(null != X) {
             switch(X) {
+                //        case "#": return comment();
             case '(': xchar(); Z = readL(); break;
             case ')': xchar(); if(Top) err("Reader overflow"); Z = Rp; break;
             case '"': xchar(); Z = text(); break;
@@ -299,32 +308,38 @@ class wl implements Runnable {
 
     Any xrun(Any P, int n, Any L) {
         Any Z = NIL;
+        Any E = 0 < n ? undo(n, L) : NIL;
         if(P.isCons())
             while(NIL != P) {
                 Z = eval(P.car());
                 P = P.cdr();
             }
         else eval(P);
+        if(NIL != E) redo(E);
         return Z;
     }
     Any xrun(Any P) {return xrun(P, 0, NIL);}
     Any eval(Any X, int n, Any L) {
         Any Z = NIL;
+        Any E = 0 < n ? undo(n, L) : NIL;
         if(X.isCons()) Z = apply(X);
         else if(X.isIsym()) Z = X.val();
         else if(X.isObj()) Z = X;
         else err(X, "Don't know how to eval");
+        if(NIL != E) redo(E);
         return Z;
     }
     Any eval(Any X) {return eval(X, 0, NIL);}
     Any apply(Any E) {
         Any Z = NIL;
         Any F = eval(E.car());
+        Stk.val(mkCons(E.car(), Stk.val()));
         if(F.isCons()) Z = applyC(E, F);
         //else if(F.isSym()) Z = applyS(E, F); // TODO ?
         else if(F.isOfn()) Z = ((Fn) F.cxr()).fn(E);
         else if(F.isObj()) Z = applyO(E, F);
         else err(E, "Don't know how to apply");
+        Stk.val(Stk.val().cdr());
         return Z;
     }
     Any applyC(Any E, Any F) {
@@ -411,6 +426,51 @@ class wl implements Runnable {
         if(null != Z) Z.val(mkObj(F));
         else Sd.put(Nm, mkIsym(Nm, mkObj(F)));
     }
+    Any undo(int n, Any L) {
+        Any Z = NIL;
+        Any E = Env.val();
+        while(E.isCons() && T != E.car()) {
+            Any C = E.car();
+            // flip
+            Any F = E;
+            E = E.cdr();
+            F.cdr(Z);
+            Z = F;
+            // swap
+            Any K = C.car();
+            Any V = K.val();
+            K.val(C.cdr());
+            C.cdr(V);
+        }
+        if(T == E.car()) {
+            // flip
+            Any F = E;
+            E = E.cdr();
+            F.cdr(Z);
+            Z = F;
+        }
+        Env.val(E);
+        return Z;
+    }
+    void redo(Any E) {
+        Any X = Env.val();
+        while(NIL != E) {
+            Any C = E.car();
+            if(C.isCons()) {
+                // swap
+                Any K = C.car();
+                Any V = K.val();
+                K.val(C.cdr());
+                C.cdr(V);
+            }
+            // flip
+            Any F = E;
+            E = E.cdr();
+            F.cdr(X);
+            X = F;
+        }
+        Env.val(X);
+    }
 
     public wl() {
         Sd.put("NIL", NIL);
@@ -422,6 +482,7 @@ class wl implements Runnable {
         Sd.put("*In", In);
         Sd.put("*Out", Out);
         Sd.put("*Env", Env);
+        Sd.put("*Stk", Stk);
         Sd.put("java.lang.Class", mkIsym("java.lang.Class", mkObj(Class.class)));
 
         fn("run", new Fn() {public Any fn(Any E) {
@@ -431,7 +492,7 @@ class wl implements Runnable {
             Any L = NIL;
             if(I.cdr().isCons()) {
                 I = I.cdr();
-                n = ((BigInteger) I.car().val()).intValue();
+                n = 1; // TODO ((BigInteger) I.car().val()).intValue();
                 if(I.cdr().isCons()) L = I.cdr();
             }
             return xrun(P, n, L);
@@ -443,7 +504,7 @@ class wl implements Runnable {
             Any L = NIL;
             if(I.cdr().isCons()) {
                 I = I.cdr();
-                n = ((BigInteger) I.car().val()).intValue();
+                n = 1; // TODO ((BigInteger) I.car().val()).intValue();
                 if(I.cdr().isCons()) L = I.cdr();
             }
             return eval(X, n, L);
@@ -509,14 +570,14 @@ class wl implements Runnable {
                         Any C = Y.car();
                         if(NIL == C) {
                             Y = Y.cdr();
-                            if(NIL == eval(Y.car())) return xrun(Y.cdr());
+                            Any Z = eval(Y.car());
+                            if(NIL == Z) return xrun(Y.cdr());
+                            At.val(Z);
                         } else if(T == C) {
                             Y = Y.cdr();
                             Any Z = eval(Y.car());
-                            if(NIL != Z) {
-                                At.val(Z);
-                                return xrun(Y.cdr());
-                            }
+                            At.val(Z);
+                            if(NIL != Z) return xrun(Y.cdr());
                         } else eval(Y);
                     } else eval(Y);
                 }
@@ -680,10 +741,27 @@ class wl implements Runnable {
             L.cdr(Z);
             return Z;
         }});
+        fn("set", new Fn() {public Any fn(Any E) {
+            Any Z = NIL;
+            Any I = E.cdr();
+            while(NIL != I) {
+                Any K = eval(I.car());
+                I = I.cdr();
+                Z = eval(I.car());
+                I = I.cdr();
+                if(K.isCons()) K.car(Z);
+                else K.val(Z);
+            }
+            return Z;
+        }});
         fn("pair", new Fn() {public Any fn(Any E) {
             Any X = eval(E.cdr().car());
             return X.isCons() ? X : NIL;
         }});
+        fn("sym?", new Fn() {public Any fn(Any E) {
+            Any X = eval(E.cdr().car());
+            return X.isSym() ? T : NIL;
+        }});
         fn("let", new Fn() {public Any fn(Any E) {
             Any Z = NIL;
             Any I = E.cdr();
@@ -751,6 +829,28 @@ class wl implements Runnable {
             }
             return Z;
         }});
+        fn("up.", new Fn() {public Any fn(Any E) { // TODO cnt frame up
+            Any Z;
+            Any I = E.cdr();
+            Any K = eval(I.car());
+            I = I.cdr();
+            if(I.isCons()) { // (up 'K 'Z)
+                Z = eval(I.car());
+                boolean done = false;
+                for(Any J = Env.val(); J.isCons() && T != J.car(); J = J.cdr()) {
+                    Any C = J.car();
+                    if(K == C.car()) {C.cdr(Z); done = true; break;}
+                }
+                if(!done) Env.val(mkCons(mkCons(K, Z), Env.val()));
+            } else { // (up 'K)
+                Z = K.val();
+                for(Any J = Env.val(); J.isCons() && T != J.car(); J = J.cdr()) {
+                    Any C = J.car();
+                    if(K == C.car()) {Z = C.cdr(); break;}
+                }
+            }
+            return Z;
+        }});
 
         fn("jnew", new Fn() {public Any fn(Any E) { // jnew 'cls [arg ...]
             Any I = E.cdr();