commit b79426aa1f3e66e7124a25bb63c7c25d8a81a66c
parent 041254aceea82871d3a0ad9febdf8fb4b0f4415a
Author: tomas <tomas@logand.com>
Date:   Sat, 10 Oct 2009 00:38:44 +0200
io fix ^d and load java.wl, 'loop', 'run' and 'def' fix
Diffstat:
| M | java.wl |  |  | 105 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| M | wl.java |  |  | 100 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- | 
2 files changed, 174 insertions(+), 31 deletions(-)
diff --git a/java.wl b/java.wl
@@ -1,5 +1,7 @@
 # -*- picolisp -*-
 
+# *In *Out *Args
+
 (def 'de '(L (def (pop 'L) L)))
 
 (de caar (L) (car (car L)))
@@ -31,8 +33,111 @@
 
 (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 T (run (cdr L) 1)) ) )
+
+(de ifn (C . L)
+   (loop
+      (NIL C (eval (pop 'L) 1))
+      (T T (up @ C) (run (cdr L) 1)) ) )
+
+(de if2 (C D . L)
+   (loop
+      (T (and C D) (up @ @) (eval (pop 'L) 1))
+      (pop 'L)
+      (T C (up @ @) (eval (pop 'L) 1))
+      (pop 'L)
+      (T D (up @ @) (eval (pop 'L) 1))
+      (pop 'L)
+      (T T (run L 1)) ) )
+
+(de when (C . P)
+   (loop
+      (T C (up @ @) (run P 1))
+      (T T) ) )
+
+(de unless (C . P)
+   (loop
+      (NIL C (run P 1))
+      (T T) ) )
+
+(de as (C . L) (when C L))
+
+(de while L
+   (let (C (pop 'L) Z)
+      (loop
+         (NIL (eval C 1) Z)
+         (up @ @)
+         (def 'Z (run L 1)) ) ) )
+
+(de until L
+   (let (C (pop 'L) Z)
+      (loop
+         (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)) ) )
+
+(de and L
+   (loop
+      (NIL (eval (pop 'L) 1))
+      (up @ @)
+      (NIL (pair L) @) ) )
+
+(de or L
+   (loop
+      (T (eval (pop 'L) 1) @)
+      (up @ @)
+      (NIL (pair L)) ) )
+
+(de nand L
+   (loop
+      (NIL (eval (pop 'L) 1) T)
+      (up @ @)
+      (NIL (pair L)) ) )
+
+(de nor L
+   (loop
+      (T (eval (pop 'L) 1))
+      (up @ @)
+      (NIL (pair L) T) ) )
+
+(de xor (X Y)
+   (if X
+      (and (not Y) T)
+      (and Y T) ) )
+
+(de println @
+   (pass print)
+   (prin "^J") )
+
+(de prinl @
+   (pass prin)
+   (prin "^J") )
+
 # java
 
 (de jclass (N) (java.lang.Class 'forName N))
 
 (de gc () (((jclass 'java.lang.Runtime) 'getRuntime) 'gc))
+
+(de import L
+   (let (P (pop 'L) C)
+      (while L
+         (setq C (pop 'L))
+         (def C (jclass (pack P "." C))) ) ) )
diff --git a/wl.java b/wl.java
@@ -11,6 +11,8 @@ import java.math.BigInteger;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.lang.reflect.Field;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 
 class wl implements Runnable {
 
@@ -174,28 +176,39 @@ class wl implements Runnable {
     final Any Args = mkIsym("*Args", NIL);
 
     class In {
-        Character c;
         InputStream s;
-        public In(InputStream S) {c = null; s = S;}
+        int b; // -2 ~ unbound, -1 ~ eof, otherwise 0--255
+        Character c; // null ~ NIL
+        public In(InputStream S) {s = S; clear();}
+        void clear() {b = -2; c = null;}
+        public boolean eof() {return b == -1;}
+        public void eof(Any X) {if(NIL != X) b = -1;}
+        public Character peek() {
+            try {
+                if(-2 == b) {
+                    // TODO handle utf-8 myself
+                    b = s.read();
+                    if(0 <= b)
+                        c = (char) b;
+                }
+            } catch(Exception e) {} // TODO eof vs error?
+            return c;
+        }
+        public Character xchar() {
+            Character Z = peek();;
+            clear();
+            return Z;
+        }
     }
 
     final Any In = mkIsym("*In", mkObj(new In(System.in)));
     final Any Out = mkIsym("*Out", mkObj(System.out));
 
-    Character peek() {
-        In I = (In) In.val().cxr();
-        try {
-            if(null == I.c) I.c = (char) I.s.read();
-        } catch(Exception e) {} // TODO eof vs error?
-        return I.c;
-    }
-    Character xchar() {
-        peek();
-        In I = (In) In.val().cxr();
-        Character Z = I.c;
-        I.c = null;
-        return Z;
-    }
+    Character peek() {return ((In) In.val().cxr()).peek();}
+    Character xchar() {return ((In) In.val().cxr()).xchar();}
+    boolean eof() {return ((In) In.val().cxr()).eof();}
+    void eof(Any X) {((In) In.val().cxr()).eof(X);}
+
     boolean charIn(Character C, String L) {return 0 <= L.indexOf(C);}
     void skip() {
         Character Z;
@@ -214,7 +227,8 @@ class wl implements Runnable {
     }
     Any text() {
         StringBuffer L = new StringBuffer();
-        while(null != peek() && '"' != peek()) {
+        Character Z;
+        while(null != (Z = peek()) && '"' != Z) {
             Character C = xchar();
             if('\\' == C) C = xchar();
             else if('^' == C) {
@@ -431,7 +445,7 @@ class wl implements Runnable {
         Sd.put("*Out", Out);
         Sd.put("java.lang.Class", mkIsym("java.lang.Class", mkObj(Class.class)));
 
-        fn("run", new Fn() {public Any fn(Any E) {return xrun(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();}});
@@ -487,20 +501,30 @@ class wl implements Runnable {
         //     return Z;
         // }});
         fn("loop", new Fn() {public Any fn(Any E) {
-            // TODO @
             while(true) {
-                for(Any X = E.cdr(); NIL != X.cdr(); X = X.cdr()) {
+                for(Any X = E.cdr(); X.isCons(); X = X.cdr()) {
                     Any Y = X.car();
-                    if(Y.isCons() && NIL == Y) {
-                        Y = Y.cdr();
-                        if(NIL == eval(Y.car())) return xrun(Y.cdr());
-                    } else if(Y.isCons() && T == Y) {
-                        Y = Y.cdr();
-                        if(NIL != eval(Y.car())) return xrun(Y.cdr());
+                    if(Y.isCons()) {
+                        Any C = Y.car();
+                        if(NIL == C) {
+                            Y = Y.cdr();
+                            if(NIL == eval(Y.car())) return xrun(Y.cdr());
+                        } else if(T == C) {
+                            Y = Y.cdr();
+                            Any Z = eval(Y.car());
+                            if(NIL != Z) {
+                                At.val(Z);
+                                return xrun(Y.cdr());
+                            }
+                        } else eval(Y);
                     } else eval(Y);
                 }
             }
         }});
+        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;
@@ -615,11 +639,11 @@ class wl implements Runnable {
 
         fn("def", new Fn() {public Any fn(Any E) {
             Any X = E.cdr();
-            Any N = eval(X.car());
-            if(!Sd.containsKey(N.nm())) err(E, "Symbol not interned");
-            Any V = eval(X.cdr().car());
-            Sd.get(N.nm()).val(V);
-            return N;
+            Any A = eval(X.car());
+            X = X.cdr();
+            Any B = eval(X.car());
+            A.val(B);
+            return A;
         }});
         fn("val", new Fn() {public Any fn(Any E) {
             Any Z = NIL;
@@ -866,8 +890,22 @@ class wl implements Runnable {
         return Z;
     }
 
+    public void load(String F) {
+        Any I = In.val();
+        try {
+            In.val(mkObj(new In(new FileInputStream(F))));
+            Any Z;
+            while(null != (Z = read1(true)))
+                eval(Z);
+        } catch(FileNotFoundException e) {
+            err(F, "File not found");
+        }
+        In.val(I);
+    }
+
     public static void main(String args[]) {
         wl X = new wl();
+        X.load("java.wl"); // TODO from args
         X.run();
     }
 }