commit 7d4915d7392b8e071c4ccbffd179d0b48804a280
parent b8f1f048daff1b016c995c02056eff5c2ee08885
Author: tomas <tomas@logand.com>
Date: Tue, 6 Oct 2009 21:09:48 +0200
eval and java ffi
Diffstat:
M | wl.java | | | 635 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
1 file changed, 365 insertions(+), 270 deletions(-)
diff --git a/wl.java b/wl.java
@@ -10,12 +10,56 @@ import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.util.ArrayList;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.math.BigInteger;
-class wl {
+class wl implements Runnable {
- void dbg(String M) {System.out.println(M);}
- void dbg(String M, Any E) {System.out.println(M); print(E);}
- void dbg(String M, Any E, Any F) {System.out.println(M); print(E); print(F);}
+ final static String Enc = "UTF-8";
+
+ int Level = 0;
+
+ void _level() {
+ for(int I = Level; 0 < I; I--)
+ System.out.print(" ");
+ }
+ void dbg(String M) {
+ _level();
+ System.out.println(M);
+ }
+ void dbg(String M, Any E) {
+ _level();
+ System.out.print(M);
+ System.out.print(' ');
+ print(E);
+ System.out.println();
+ }
+ void dbg(String M, Any E, Any F) {
+ _level();
+ System.out.print(M);
+ System.out.print(' ');
+ print(E);
+ System.out.print(' ');
+ print(F);
+ System.out.println();
+ }
+ void dbg(String M, Any E, Any F, Any G, Any H) {
+ _level();
+ System.out.print(M);
+ System.out.print(' ');
+ print(E);
+ System.out.print(' ');
+ print(F);
+ System.out.print(' ');
+ print(G);
+ System.out.print(' ');
+ print(H);
+ System.out.println();
+ }
void err(Object X, String M) {
if(X instanceof Any) throw new RuntimeException(M + ": " + str((Any) X));
@@ -23,7 +67,7 @@ class wl {
}
void err(String M) {throw new RuntimeException(M);}
- static interface Fn {
+ public static interface Fn {
public Any fn(Any E);
}
@@ -37,13 +81,15 @@ class wl {
public boolean isSym() {return null != nm;}
public boolean isCons() {return null == nm && null != car && null != cdr;}
public boolean isStr() {return null == nm && cxr instanceof String;}
- public boolean isInt() {return null == nm && cxr instanceof Integer;}
+ public boolean isInt() {return null == nm && cxr instanceof BigInteger;}
public boolean isFn() {return cxr instanceof Fn;}
+ public boolean isObj() {return null == car && null == cdr;}
}
static Any cons(Any a, Any d) {return new Any(null, a, d, null);}
- static Any mkInt(String x) {return new Any(null, null, null, Integer.parseInt(x));}
- static Any mkFix(String x) {return new Any(null, null, null, Float.parseFloat(x));}
+ static Any mkInt(String x) {return new Any(null, null, null, new BigInteger(x));}
+ Any mkFix(String x) {err(NIL, "fixpoint not implemented"); return NIL;}
static Any mkStr(String x) {return new Any(null, null, null, x);}
+ static Any mkAny(Object x) {return new Any(null, null, null, x);}
final static Any NIL = new Any("NIL", null, null, null);
final static Any T = new Any("T", NIL, null, null);
@@ -58,7 +104,7 @@ class wl {
final static Any Lp = new Any(null, null, null, null);
final static Any Rp = new Any(null, null, null, null);
- final Any Qte = new Any("quote", NIL, NIL, null);
+ //final Any Qte = new Any("quote", NIL, NIL, null);
final Any Dot = new Any(".", NIL, NIL, null);
class In {
@@ -74,7 +120,7 @@ class wl {
In I = (In) In.cxr;
try {
if(null == I.c) I.c = (char) I.s.read();
- } catch(Exception e) {}
+ } catch(Exception e) {} // TODO eof vs error?
return I.c;
}
Character xchar() {
@@ -84,73 +130,68 @@ class wl {
I.c = null;
return Z;
}
-
boolean charIn(Character C, String L) {return 0 <= L.indexOf(C);}
-
void skip() {
Character Z;
- while((Z = peek()) != null && charIn(Z, " \t\n\r"))
+ while(null != (Z = peek()) && charIn(Z, " \t\n\r"))
xchar();
}
- void comment() {
- while('#' == peek()) {
- Character X;
- while(((X = peek()) != null) && ('\n' != X))
- xchar();
- skip();
- }
- }
- Any text() {
- StringBuffer L = new StringBuffer();
- while('"' != peek()) {
- Character C = xchar();
- if('\\' == C) C = xchar();
- else if('^' == C) {
- C = xchar();
- if('I' == C) C = '\t';
- else if('J' == C) C = '\n';
- else if('M' == C) C = '\r';
- else C = (char) ('?' == C ? 127 : C & 0x1f);
- }
- L.append(C);
- }
- if('"' != xchar()) err("Unbalanced double quote");
- if(0 < L.length()) return mkStr(L.toString()); //.replace(/\r\n/g, "\n");
- return mkStr("");
- }
Any symbol() {
+ //dbg("symbol");
Character C = xchar();
- if(charIn(C, "()# \t\n")) err(C, "Symbol expected");
- boolean N = charIn(C, "+-0123456789.");
- boolean F = ('.' == C);
+ if(charIn(C, "() \t\n")) err(C, "Symbol expected");
StringBuffer L = new StringBuffer();
L.append(C);
- Character X;
- while(((X = peek()) != null) && !charIn(X, "()# \t\n")) {
- C = xchar();
- L.append(C);
- if(N && !charIn(C, "0123456789")) {
- if(!F && ('.' == C)) F = true;
- else N = false;
- }
- }
+ while((null != (C = peek())) && !charIn(C, "() \t\n"))
+ L.append(xchar());
String M = L.toString();
- if((1 == M.length()) && charIn(M.charAt(0), "+-.")) N = false;
- return N ? (F ? mkFix(M) : mkInt(M)) : intern(M);
+ //dbg("symbol: " + M);
+ return intern(M);
}
- Any token() {
+ Any read1(boolean Top) {
+ //dbg("read1: " + Top);
skip();
+ Any Z = null;
Character X = peek();
- if(null == X) return null;
- else
+ if(null != X) {
+ //dbg("read1: '" + X + "'");
switch(X) {
- case '#': comment(); return null;
- case '"': xchar(); return text();
- case '\'': xchar(); return Qte;
- case '(': xchar(); return Lp;
- case ')': xchar(); return Rp;
- default: return symbol();
+ case '(': xchar(); Z = readL(); break;
+ case ')': xchar(); if(Top) err("Reader overflow"); Z = Rp; break;
+ default: Z = symbol();
+ }
+ }
+ //dbg("read1", Z);
+ return Z;
+ }
+ Any readL() {
+ Level++;
+ //dbg("readL");
+ Any A = cons(NIL, NIL);
+ Any Z = A;
+ Any X;
+ boolean D = false;
+ while(null != (X = read1(false)) && Rp != X) {
+ if(Dot != X) {
+ Z.cdr = D ? X : cons(X, NIL);
+ if(Z.cdr.isCons()) Z = Z.cdr;
}
+ D = Dot == X;
+ }
+ if(D) Z.cdr = A.cdr;
+ //dbg("readL", Z);
+ Level--;
+ return A.cdr;
+ }
+ public void run() {
+ Any Z = null;
+ System.out.print(": ");
+ while(null != (Z = read1(true))) {
+ System.out.print("-> ");
+ print(eval(Z));
+ System.out.println();
+ System.out.print(": ");
+ }
}
// evaluator
@@ -161,7 +202,11 @@ class wl {
return Sd.get(Nm);
}
- Any run(Any E) {
+
+
+
+
+ Any xrun(Any E) {
Any Z = NIL;
while(NIL != E) {
Z = eval(E.car);
@@ -173,19 +218,35 @@ class wl {
//dbg("eval", E);
Any Z = NIL;
if(E.isInt()) Z = E;
- else if(E.isSym()) Z = E.cdr;
- else if(E.isCons()) {
- Any X = E.car;
- if(X.isInt()) Z = E;
- else if(X.isSym()) {
- if(X.isFn()) Z = ((Fn) X.cxr).fn(E);
- else err(E, "TODO ap"); //Z = ap(E);
- } else err(E, "Unexpected function type");
- } else if(E.isStr()) Z = E;
+ else if(E.isSym()) Z = E.isFn() ? E : E.cdr;
+ else if(E.isCons()) Z = apply(E);
+ else if(E.isStr()) Z = E;
else err(E, "Don't know how to eval");
//dbg("eval", E, Z);
return Z;
}
+ Any apply(Any E) {
+ Any Z = NIL;
+ Any F = eval(E.car);
+ if(F.isInt()) Z = E;
+ else if(F.isSym()) {
+ if(F.isFn()) Z = ((Fn) F.cxr).fn(E);
+ else applyC(E, F);
+ } else if(F.isCons()) applyC(E, F);
+ else err(E, "Unexpected function type");
+ return Z;
+ }
+ Any applyC(Any E, Any F) {
+ dbg("applyC", E, F); // TODO !!!
+ Any Z = NIL;
+ Any A = E.cdr;
+ Any Fa = F.car;
+ Any Fb = F.cdr;
+ dbg("A", A);
+ dbg("Fa", Fa);
+ dbg("Fb", Fb);
+ return Z;
+ }
void fn(String Nm, Fn F) {
Any Z = Sd.get(Nm);
@@ -196,66 +257,66 @@ class wl {
public wl() {
Sd.put("NIL", NIL);
Sd.put("T", T);
- Sd.put("quote", Qte);
+ //Sd.put("quote", Qte);
Sd.put(".", Dot);
Sd.put("*In", In);
Sd.put("*Out", Out);
- fn("run", new Fn() {public Any fn(Any E) {return run(E.cdr.car);}});
+ fn("run", new Fn() {public Any fn(Any E) {return xrun(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;}});
- fn("-", new Fn() {public Any fn(Any E) {
- Any X = E.cdr;
- Any Z = eval(X.car);
- if(NIL == Z) return NIL;
- if(NIL == X.cdr) Z.cxr = -((Integer) Z.cxr);
- else
- while(NIL != X.cdr) {
- X = X.cdr;
- Any Y = eval(X.car);
- if(NIL == Y) return NIL;
- Z.cxr = (Integer) Z.cxr - (Integer) Y.cxr;
- }
- return Z;
- }});
- fn("*", new Fn() {public Any fn(Any E) {
- Any X = E.cdr;
- Any Z = eval(X.car);
- if(NIL == Z) return NIL;
- while(NIL != X.cdr) {
- X = X.cdr;
- Any Y = eval(X.car);
- if(NIL == Y) return NIL;
- Z.cxr = (Integer) Z.cxr * (Integer) Y.cxr;
- }
- return Z;
- }});
- fn("/", new Fn() {public Any fn(Any E) {
- Any X = E.cdr;
- Any Z = eval(X.car);
- if(NIL == Z) return NIL;
- while(NIL != X.cdr) {
- X = X.cdr;
- Any Y = eval(X.car);
- if(NIL == Y) return NIL;
- Z.cxr = (Integer) Z.cxr / (Integer) Y.cxr;
- }
- return Z;
- }});
- fn("%", new Fn() {public Any fn(Any E) {
- Any X = E.cdr;
- Any Z = eval(X.car);
- if(NIL == Z) return NIL;
- while(NIL != X.cdr) {
- X = X.cdr;
- Any Y = eval(X.car);
- if(NIL == Y) return NIL;
- Z.cxr = (Integer) Z.cxr % (Integer) Y.cxr;
- }
- return Z;
- }});
+ // fn("-", new Fn() {public Any fn(Any E) {
+ // Any X = E.cdr;
+ // Any Z = eval(X.car);
+ // if(NIL == Z) return NIL;
+ // if(NIL == X.cdr) Z.cxr = -((Integer) Z.cxr);
+ // else
+ // while(NIL != X.cdr) {
+ // X = X.cdr;
+ // Any Y = eval(X.car);
+ // if(NIL == Y) return NIL;
+ // Z.cxr = (Integer) Z.cxr - (Integer) Y.cxr;
+ // }
+ // return Z;
+ // }});
+ // fn("*", new Fn() {public Any fn(Any E) {
+ // Any X = E.cdr;
+ // Any Z = eval(X.car);
+ // if(NIL == Z) return NIL;
+ // while(NIL != X.cdr) {
+ // X = X.cdr;
+ // Any Y = eval(X.car);
+ // if(NIL == Y) return NIL;
+ // Z.cxr = (Integer) Z.cxr * (Integer) Y.cxr;
+ // }
+ // return Z;
+ // }});
+ // fn("/", new Fn() {public Any fn(Any E) {
+ // Any X = E.cdr;
+ // Any Z = eval(X.car);
+ // if(NIL == Z) return NIL;
+ // while(NIL != X.cdr) {
+ // X = X.cdr;
+ // Any Y = eval(X.car);
+ // if(NIL == Y) return NIL;
+ // Z.cxr = (Integer) Z.cxr / (Integer) Y.cxr;
+ // }
+ // return Z;
+ // }});
+ // fn("%", new Fn() {public Any fn(Any E) {
+ // Any X = E.cdr;
+ // Any Z = eval(X.car);
+ // if(NIL == Z) return NIL;
+ // while(NIL != X.cdr) {
+ // X = X.cdr;
+ // Any Y = eval(X.car);
+ // if(NIL == Y) return NIL;
+ // Z.cxr = (Integer) Z.cxr % (Integer) Y.cxr;
+ // }
+ // return Z;
+ // }});
fn("loop", new Fn() {public Any fn(Any E) {
// TODO @
while(true) {
@@ -263,10 +324,10 @@ class wl {
Any Y = X.car;
if(Y.isCons() && NIL == Y) {
Y = Y.cdr;
- if(NIL == eval(Y.car)) return run(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 run(Y.cdr);
+ if(NIL != eval(Y.car)) return xrun(Y.cdr);
} else eval(Y);
}
}
@@ -284,8 +345,6 @@ class wl {
Character X = xchar();
return null == X ? NIL : mkStr(X.toString());
}});
- fn("skip", new Fn() {public Any fn(Any E) {skip(); return NIL;}});
- fn("read", new Fn() {public Any fn(Any E) {return read();}});
fn("print", new Fn() {public Any fn(Any E) {
PrintStream S = (PrintStream) Out.cxr;
Any Z = NIL;
@@ -300,74 +359,62 @@ class wl {
fn("in", new Fn() {public Any fn(Any E) {
Any X = E.cdr;
- Any N = eval(X.car);
- String F = null;
- if(N.isStr()) F = (String) N.cxr;
- else if(N.isSym()) F = N.nm;
- else err(E, "File name expected");
+ String F = evStr(X.car);
In S = null;
+ Any Z = NIL;
try {
S = new In(new FileInputStream(F));
In I = (In) In.cxr;
In.cxr = S;
- Any Z = run(X.cdr);
+ Z = xrun(X.cdr);
In.cxr = I;
S.s.close();
- return Z;
} catch(FileNotFoundException e) {
err(E, "File not found");
} catch(IOException e) {
err(E, "Error closing input");
}
- return NIL; // make the compiler happy:-{
+ return Z;
}});
fn("out", new Fn() {public Any fn(Any E) {
Any X = E.cdr;
- Any N = eval(X.car);
- String F = null;
- if(N.isStr()) F = (String) N.cxr;
- else if(N.isSym()) F = N.nm;
- else err(E, "File name expected");
+ String F = evStr(X.car);
+ Any Z = NIL;
try {
FileOutputStream B = new FileOutputStream(F);
PrintStream S = new PrintStream(B);
OutputStream O = (OutputStream) Out.cxr;
Out.cxr = S;
- Any Z = run(X.cdr);
+ Z = xrun(X.cdr);
Out.cxr = O;
S.close();
- return Z;
} catch(FileNotFoundException e) {
err(E, "File not found");
}
- return NIL; // make the compiler happy:-{
- }});
- fn("load", new Fn() {public Any fn(Any E) {
- Any Z = NIL;
- for(Any X = E.cdr; NIL != X; X = X.cdr) {
- Any N = eval(X.car);
- String F = null;
- if(N.isStr()) F = (String) N.cxr;
- else if(N.isSym()) F = N.nm;
- else err(E, "File name expected");
- In S = null;
- try {
- S = new In(new FileInputStream(F));
- In I = (In) In.cxr;
- In.cxr = S;
- do Z = eval(read());
- while(null != peek());
- In.cxr = I;
- S.s.close();
- return Z;
- } catch(FileNotFoundException e) {
- err(E, "File not found");
- } catch(IOException e) {
- err(E, "Error closing input");
- }
- }
return Z;
}});
+ // fn("load", new Fn() {public Any fn(Any E) {
+ // Any Z = NIL;
+ // for(Any X = E.cdr; NIL != X; X = X.cdr) {
+ // String F = evStr(X.car);
+ // In S = null;
+ // try {
+ // S = new In(new FileInputStream(F));
+ // In I = (In) In.cxr;
+ // In.cxr = S;
+ // do Z = eval(read());
+ // while(null != peek());
+ // In.cxr = I;
+ // S.s.close();
+ // return Z;
+ // } catch(FileNotFoundException e) {
+ // err(E, "File not found");
+ // } catch(IOException e) {
+ // err(E, "Error closing input");
+ // }
+ // }
+ // return Z;
+ // }});
fn("def", new Fn() {public Any fn(Any E) {
Any X = E.cdr;
@@ -392,92 +439,166 @@ class wl {
return cons(eval(X.car), eval(X.cdr.car));
}});
- fn("gc", new Fn() {public Any fn(Any E) {
- Runtime r = Runtime.getRuntime();
- r.gc();
- return NIL;
+ fn("jclass", new Fn() {public Any fn(Any E) { // jclass 'sym
+ Any X = E.cdr;
+ String N = evStr(X.car);
+ Any Z = NIL;
+ try {
+ Class C = Class.forName(N);
+ Z = mkAny(C);
+ } catch(ClassNotFoundException e) {
+ }
+ return Z;
}});
- fn("heap", new Fn() {public Any fn(Any E) {
- Runtime R = Runtime.getRuntime();
- long A = R.freeMemory();
- long B = R.totalMemory();
- long C = R.maxMemory();
- long Z = B - A;
- if(NIL != E.cdr) {
- if(T == eval(E.cdr.car)) Z = A;
- else Z = C;
+ fn("jcall", new Fn() {public Any fn(Any E) { // jcall 'fn 'obj [arg ...]
+ Any I = E.cdr;
+ Any F = eval(I.car);
+ I = I.cdr;
+ Any O = eval(I.car);
+ Any A = I.cdr;
+ Any Z = NIL;
+ ArrayList<Object> a = new ArrayList();
+ ArrayList<Class> t = new ArrayList();
+ for(Any X = A; NIL != X; X = X.cdr) {
+ // TODO handle non-native?
+ Any Y = eval(X.car);
+ a.add(Y.cxr);
+ t.add(Y.cxr.getClass());
}
- return mkInt("" + Z / (1024 * 1024));
+ Object[] aa = a.toArray();
+ Class[] ta = (Class[]) t.toArray(new Class[aa.length]);
+ try {
+ Class c = O.cxr instanceof Class ? (Class) O.cxr : O.cxr.getClass();
+ Method m = c.getMethod(F.nm, ta);
+ Object r = m.invoke(O.cxr, aa);
+ Z = mkAny(r);
+ } catch(NoSuchMethodException e) {
+ err(E, "NoSuchMethodException");
+ } catch(IllegalAccessException e) {
+ err(E, "IllegalAccessException");
+ } catch(InvocationTargetException e) {
+ err(E, "InvocationTargetException");
+ }
+ return Z;
}});
+ fn("jnew", new Fn() {public Any fn(Any E) { // jnew 'cls [arg ...]
+ Any I = E.cdr;
+ Any C = eval(I.car);
+ Any A = I.cdr;
+ Any Z = NIL;
+ ArrayList<Object> a = new ArrayList();
+ ArrayList<Class> t = new ArrayList();
+ for(Any X = A; NIL != X; X = X.cdr) {
+ // TODO handle non-native?
+ Any Y = eval(X.car);
+ a.add(Y.cxr);
+ t.add(Y.cxr.getClass());
+ }
+ Object[] aa = a.toArray();
+ Class[] ta = (Class[]) t.toArray(new Class[aa.length]);
+ try {
+ Constructor c = ((Class) C.cxr).getConstructor(ta);
+ Object r = c.newInstance(aa);
+ Z = mkAny(r);
+ } catch(NoSuchMethodException e) {
+ err(E, "NoSuchMethodException");
+ } catch(InstantiationException e) {
+ err(E, "InstantiationException");
+ } catch(IllegalAccessException e) {
+ err(E, "IllegalAccessException");
+ } catch(InvocationTargetException e) {
+ err(E, "InvocationTargetException");
+ }
+ return Z;
+ }});
+ fn("jfield", new Fn() {public Any fn(Any E) { // jfield 'fld 'obj
+ Any X = E.cdr;
+ Any F = eval(X.car);
+ X = X.cdr;
+ Any O = eval(X.car);
+ Any Z = NIL;
+ try {
+ Class c = O.cxr instanceof Class ? (Class) O.cxr : O.cxr.getClass();
+ Field f = c.getField(F.nm);
+ Object r = f.get(O.cxr);
+ Z = mkAny(r);
+ } catch(NoSuchFieldException e) {
+ dbg("NoSuchFieldException", E);
+ } catch(IllegalAccessException e) {
+ dbg("IllegalAccessException", E);
+ }
+ return Z;
+ }});
+ // fn("gc", new Fn() {public Any fn(Any E) {
+ // Runtime r = Runtime.getRuntime();
+ // r.gc();
+ // return NIL;
+ // }});
+ // fn("heap", new Fn() {public Any fn(Any E) {
+ // Runtime R = Runtime.getRuntime();
+ // long A = R.freeMemory();
+ // long B = R.totalMemory();
+ // long C = R.maxMemory();
+ // long Z = B - A;
+ // if(NIL != E.cdr) {
+ // if(T == eval(E.cdr.car)) Z = A;
+ // else Z = C;
+ // }
+ // return mkInt("" + Z / (1024 * 1024));
+ // }});
}
-
- void repl() {
- PrintStream S = (PrintStream) Out.cxr;
- do {
- prompt();
- Any Z = eval(read());
- // TODO only on terminal
- S.print("-> ");
- print(Z);
- S.println();
- } while(null != peek());
- }
- void prompt() {
- // TODO only on terminal
- PrintStream S = (PrintStream) Out.cxr;
- S.print(": ");
- }
- Any read() {
- // TODO handle \n from user
- return read1();
- }
- Any read1() {
- Any Z = token();
- if(Qte == Z) Z = cons(Qte, read1());
- else if(Lp == Z) Z = readL();
- return Z;
- }
- Any readL() {
- // TODO circular list .
- // TODO cons .
- Any Z = NIL;
- Any X;
- while(null != (X = read1()) && Rp != X)
- Z = cons(X, Z);
- return flip(Z);
+
+ String evStr(Any E) {
+ Any X = eval(E);
+ String S = null;
+ if(X.isStr()) S = (String) X.cxr;
+ else if(X.isSym()) S = X.nm;
+ else err(E, "Expected str|sym");
+ return S;
}
+
void print(Any E) {
PrintStream S = (PrintStream) Out.cxr;
if(E.isSym()) S.print(E.nm);
- else if(E.isInt()) S.print(E.cxr);
+ //else if(E.isInt()) S.print(E.cxr);
else if(E.isCons()) {
- if(Qte == E.car) {
- S.print('\'');
- print(E.cdr);
- } else {
+ Any X = E;
+ // if(Qte == X.car) {
+ // S.print('\'');
+ // print(X.cdr);
+ // } else {
+ {
S.print('(');
- while(E.isCons()) {
- print(E.car);
- E = E.cdr;
- if(NIL != E) S.print(' ');
+ while(X.isCons()) {
+ print(X.car);
+ X = X.cdr;
+ if(NIL != X) S.print(' ');
+ if(E == X) {
+ S.print('.');
+ break;
+ }
}
- if(NIL != E) {
+ if(NIL != X && E != X) {
S.print(". ");
- print(E);
+ print(X);
}
S.print(')');
}
- } else if(E.isStr()) {
- S.print('"');
- String X = (String) E.cxr;
- for(int I = 0; I < X.length(); I++) {
- Character C = X.charAt(I);
- if('\\' == C) S.print("\\\\");
- else if('"' == C) S.print("\\\"");
- else S.print(C);
- }
- S.print('"');
- } else err(E, "Don't know how to print");
+ // } else if(E.isStr()) {
+ // S.print('"');
+ // String X = (String) E.cxr;
+ // for(int I = 0; I < X.length(); I++) {
+ // Character C = X.charAt(I);
+ // if('\\' == C) S.print("\\\\");
+ // else if('"' == C) S.print("\\\"");
+ // else S.print(C);
+ // }
+ // S.print('"');
+ } else {
+ S.print('[');
+ S.print(E.cxr);
+ S.print(']');
+ }
}
String str(Any E) {
@@ -487,47 +608,21 @@ class wl {
Out.cxr = S;
print(E);
Out.cxr = O;
+ String Z = null;
try {
- String Z = B.toString("UTF-8");
+ Z = B.toString(Enc);
S.close();
- return Z;
} catch(UnsupportedEncodingException e) {
- err(E, "Unsupported encoding");
- }
- return null; // make the compiler happy:-{
- }
- Any flip(Any E) {
- Any Z = NIL;
- while(E.isCons()) {
- Any X = E;
- E = E.cdr;
- X.cdr = Z;
- Z = X;
+ err(E, "Unsupported encoding " + Enc);
}
return Z;
}
public static void main(String args[]) {
wl X = new wl();
- X.repl();
+ X.run();
}
}
-// // TODO ap
-// function ap(E) { // apply
-// var Z;
-// var F = ev(E.car);
-// if(NIL === F.car) run(F.cdr);
-// else if(isSym(F.car)) {
-// if("@" == F.car.nm) {
-// // TODO
-// } else {
-// // TODO
-// }
-// } else if(isCons(F.car)) {
-// // TODO
-// } else throw "Function expected";
-// }
-
// // Sd["eq"] = function() {var Y = Os.pop(); var X = Os.pop(); Os.push(X == Y);};
// // Sd["lt"] = function() {var Y = Os.pop(); var X = Os.pop(); Os.push(X < Y);};