wl

Unnamed repository; edit this file 'description' to name the repository.
git clone https://logand.com/git/wl.git/
Log | Files | Refs | LICENSE

commit 7335d5822c39a73f69e4e8bc48a8b1437f630149
parent 7d4915d7392b8e071c4ccbffd179d0b48804a280
Author: tomas <tomas@logand.com>
Date:   Tue,  6 Oct 2009 21:11:06 +0200

better parser, eval (cons too) and java ffi

Diffstat:
Mwl.java | 667++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 392 insertions(+), 275 deletions(-)

diff --git a/wl.java b/wl.java @@ -1,45 +1,31 @@ // wl.java -- (c) 2009 Tomas Hlavaty +import java.io.UnsupportedEncodingException; +import java.io.ByteArrayOutputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.io.PrintStream; import java.util.HashMap; +import java.math.BigInteger; import java.io.InputStream; -import java.io.IOException; -import java.io.FileInputStream; -import java.io.OutputStream; -import java.io.PrintStream; -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 implements Runnable { 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); @@ -48,7 +34,6 @@ class wl implements Runnable { 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); @@ -62,50 +47,115 @@ class wl implements Runnable { } void err(Object X, String M) { - if(X instanceof Any) throw new RuntimeException(M + ": " + str((Any) X)); + if(null != X && X instanceof Any) + throw new RuntimeException(M + ": " + str((Any) X)); throw new RuntimeException(M + ": " + X); } - void err(String M) {throw new RuntimeException(M);} + static void err(String M) {throw new RuntimeException(M);} - public static interface Fn { + static public interface Fn { public Any fn(Any E); } - static class Any { + static interface Any { + public String nm(); + public Any car(); + public Any cdr(); + public Object cxr(); + public Any set(Any a); + public Any con(Any d); + public Object obj(Object x); + public boolean isCons(); + public boolean isSym(); + public boolean isIsym(); + public boolean isObj(); + public boolean isOfn(); + public boolean isOstr(); + public boolean isOnum(); + public boolean isOobj(); + } + static class Cons implements Any { + public Any car, cdr; + public Cons(Any a, Any d) {car = a; cdr = d;} + public String nm() {err("No Cons.nm"); return null;} + public Any car() {return car;} + public Any cdr() {return cdr;} + public Object cxr() {err("No Cons.cxr"); return null;} + public Any set(Any a) {car = a; return car;} + public Any con(Any d) {cdr = d; return cdr;} + public Object obj(Object x) {err("No Cons.obj"); return null;} + public boolean isCons() {return true;}; + public boolean isSym() {return false;}; + public boolean isIsym() {return false;}; + public boolean isObj() {return false;}; + public boolean isOfn() {return false;}; + public boolean isOstr() {return false;}; + public boolean isOnum() {return false;}; + public boolean isOobj() {return false;}; + } + static interface Sym extends Any {} + static class Isym implements Sym { public String nm; public Any car, cdr; + public Isym(String n, Any a, Any d) {nm = n; car = a; cdr = d;} + public String nm() {return nm;} + public Any car() {return car;} + public Any cdr() {return cdr;} + public Object cxr() {err("No Isym.cxr"); return null;} + public Any set(Any a) {car = a; return car;} + public Any con(Any d) {cdr = d; return cdr;} + public Object obj(Object x) {err("No Isym.obj"); return null;} + public boolean isCons() {return false;}; + public boolean isSym() {return true;}; + public boolean isIsym() {return true;}; + public boolean isObj() {return false;}; + public boolean isOfn() {return false;}; + public boolean isOstr() {return false;}; + public boolean isOnum() {return false;}; + public boolean isOobj() {return false;}; + } + static class Obj implements Any { public Object cxr; - public Any(String n, Any a, Any d, Object x) { - nm = n; car = a; cdr = d; cxr = x; - } - 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 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, 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);} + public Obj(Object x) {cxr = x;} + public String nm() {err("No Obj.nm"); return null;} + public Any car() {err("No Obj.car"); return null;} + public Any cdr() {err("No Obj.cdr"); return null;} + public Object cxr() {return cxr;} + public Any set(Any a) {err("No Obj.set"); return null;} + public Any con(Any d) {err("No Obj.con"); return null;} + public Object obj(Object x) {cxr = x; return cxr;} + public boolean isCons() {return false;}; + public boolean isSym() {return false;}; + public boolean isIsym() {return false;}; + public boolean isObj() {return true;}; + public boolean isOfn() {return cxr instanceof Fn;}; + public boolean isOstr() {return cxr instanceof String;}; + public boolean isOnum() {return cxr instanceof BigInteger;}; + public boolean isOobj() {return !isOfn() && !isOstr() && !isOnum();}; + } - final static Any NIL = new Any("NIL", null, null, null); - final static Any T = new Any("T", NIL, null, null); + static Any mkCons(Any a, Any d) {return new Cons(a, d);} + static Any mkIsym(String n, Any a, Any d) {return new Isym(n, a, d);} + static Any mkObj(Object x) {return new Obj(x);} + static Any mkOint(String x) {return mkObj(new BigInteger(x));} + static Any mkOfix(String x) {err("mkOfix not implemented"); return null;} + + final static Any NIL = mkIsym("NIL", null, null); + final static Any T = mkIsym("T", NIL, null); static { - NIL.car = NIL; - NIL.cdr = NIL; - T.cdr = T; + NIL.set(NIL); + NIL.con(NIL); + T.con(T); } // reader - final static Any Lp = new Any(null, null, null, null); - final static Any Rp = new Any(null, null, null, null); + final static Any Lp = mkObj(null); + final static Any Rp = mkObj(null); - //final Any Qte = new Any("quote", NIL, NIL, null); - final Any Dot = new Any(".", NIL, NIL, null); + final Any Qte = mkIsym("quote", NIL, NIL); + final Any Dot = mkIsym(".", NIL, NIL); + final Any At = mkIsym("@", NIL, NIL); class In { Character c; @@ -113,11 +163,11 @@ class wl implements Runnable { public In(InputStream S) {c = null; s = S;} } - final Any In = new Any("*In", null, null, new In(System.in)); - final Any Out = new Any("*Out", null, null, System.out); + final Any In = mkIsym("*In", NIL, mkObj(new In(System.in))); + final Any Out = mkIsym("*Out", NIL, mkObj(System.out)); Character peek() { - In I = (In) In.cxr; + In I = (In) In.cdr().cxr(); try { if(null == I.c) I.c = (char) I.s.read(); } catch(Exception e) {} // TODO eof vs error? @@ -125,7 +175,7 @@ class wl implements Runnable { } Character xchar() { peek(); - In I = (In) In.cxr; + In I = (In) In.cdr().cxr(); Character Z = I.c; I.c = null; return Z; @@ -137,51 +187,64 @@ class wl implements Runnable { xchar(); } Any symbol() { - //dbg("symbol"); Character C = xchar(); - if(charIn(C, "() \t\n")) 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")) + while((null != (C = peek())) && !charIn(C, "()\" \t\n\r")) L.append(xchar()); String M = L.toString(); - //dbg("symbol: " + M); return intern(M); } + Any text() { + StringBuffer L = new StringBuffer(); + while(null != peek() && '"' != 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 mkObj(L.toString()); //.replace(/\r\n/g, "\n"); + return NIL; + } Any read1(boolean Top) { - //dbg("read1: " + Top); skip(); Any Z = null; Character X = peek(); if(null != X) { - //dbg("read1: '" + X + "'"); switch(X) { case '(': xchar(); Z = readL(); break; case ')': xchar(); if(Top) err("Reader overflow"); Z = Rp; break; + case '"': xchar(); Z = text(); break; + case '\'': xchar(); Z = mkCons(Qte, read1(false)); break; + case '`': xchar(); Z = eval(read1(false)); break; default: Z = symbol(); } } - //dbg("read1", Z); return Z; } Any readL() { - Level++; - //dbg("readL"); - Any A = cons(NIL, NIL); + Any A = mkCons(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; + Z.con(D ? X : mkCons(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; + if(null == X) err("Reader underflow"); + if(D) Z.con(A.cdr()); + return A.cdr(); } public void run() { Any Z = null; @@ -198,75 +261,144 @@ class wl implements Runnable { HashMap<String, Any> Sd = new HashMap<String, Any>(); Any intern(String Nm) { - if(!Sd.containsKey(Nm)) Sd.put(Nm, new Any(Nm, NIL, NIL, null)); + if(!Sd.containsKey(Nm)) Sd.put(Nm, mkIsym(Nm, NIL, NIL)); return Sd.get(Nm); } - - - - Any xrun(Any E) { Any Z = NIL; while(NIL != E) { - Z = eval(E.car); - E = E.cdr; + Z = eval(E.car()); + E = E.cdr(); } return Z; } Any eval(Any E) { - //dbg("eval", E); Any Z = NIL; - if(E.isInt()) 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; + if(E.isCons()) Z = apply(E); + else if(E.isIsym()) Z = E.cdr(); + else if(E.isObj()) 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"); + Any F = eval(E.car()); + if(F.isCons()) Z = applyC(E, F); + else if(F.isSym()) Z = applyC(E, F); + else if(F.isOfn()) Z = ((Fn) F.cxr()).fn(E); + else if(F.isObj()) Z = japplyC(E, F); + else err(E, "Don't know how to apply"); 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); + 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 saveV(Any Fa, Any A) { + Any O = NIL; + if(Fa.isIsym()) { + if(NIL != Fa) { + O = mkCons(Fa.cdr(), NIL); + Fa.con(A); + } // TODO @ + } else if(Fa.isCons()) { + Any B = mkCons(NIL, NIL); + Any Z = B; + while(Fa.isCons()) { + Any X = Fa.car(); + Fa = Fa.cdr(); + if(!X.isIsym()) err(X, "Isym expected in saveV"); + Z.con(mkCons(X.cdr(), NIL)); + Z = Z.cdr(); + X.con(eval(A.car())); + A = A.cdr(); + } + if(NIL != Fa) { + if(!Fa.isIsym()) err(Fa, "Isym expected in saveV"); + Z.con(mkCons(Fa.cdr(), NIL)); + Fa.con(A); + } // TODO (X Y . @) + O = B.cdr(); + } else err(Fa, "Don't know how to saveV"); + return O; + } + void restoreV(Any Fa, Any O) { + if(Fa.isIsym()) { + if(NIL != Fa) Fa.con(O.car()); + // TODO @ + } else if(Fa.isCons()) { + while(Fa.isCons()) { + Any X = Fa.car(); + Fa = Fa.cdr(); + if(!X.isIsym()) err(X, "Isym expected in restoreV"); + X.con(O.car()); + O = O.cdr(); + } + if(NIL != Fa) { + if(!Fa.isIsym()) err(Fa, "Isym expected in saveV"); + Fa.con(O.car()); + } // TODO (X Y . @) + } else err(Fa, "Don't know how to restoreV"); + } + Any japplyC(Any E, Any O) { // 'obj 'meth [arg ...] + Any I = E.cdr(); + Any F = 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 { + Object o = O.cxr(); + Class c = o instanceof Class ? (Class) o : o.getClass(); + Method m = c.getMethod(F.nm(), ta); + Object r = m.invoke(o, aa); + Z = mkObj(r); + } catch(NoSuchMethodException e) { + err(E, "NoSuchMethodException"); + } catch(IllegalAccessException e) { + err(E, "IllegalAccessException"); + } catch(InvocationTargetException e) { + err(E, "InvocationTargetException"); + } return Z; } void fn(String Nm, Fn F) { Any Z = Sd.get(Nm); - if(null != Z) Z.cxr = F; - else Sd.put(Nm, new Any(Nm, null, null, F)); + if(null != Z) Z.con(mkObj(F)); + else Sd.put(Nm, mkIsym(Nm, NIL, mkObj(F))); } public wl() { Sd.put("NIL", NIL); Sd.put("T", T); - //Sd.put("quote", Qte); + Sd.put("quote", Qte); Sd.put(".", Dot); + Sd.put("@", At); Sd.put("*In", In); Sd.put("*Out", Out); + Sd.put("java.lang.Class", mkObj(java.lang.Class.class)); - 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("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); @@ -320,79 +452,79 @@ class wl implements Runnable { fn("loop", new Fn() {public Any fn(Any E) { // TODO @ while(true) { - for(Any X = E.cdr; NIL != X.cdr; X = X.cdr) { - Any Y = X.car; + for(Any X = E.cdr(); NIL != X.cdr(); X = X.cdr()) { + Any Y = X.car(); if(Y.isCons() && NIL == Y) { - Y = Y.cdr; - if(NIL == eval(Y.car)) return xrun(Y.cdr); + 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); + Y = Y.cdr(); + if(NIL != eval(Y.car())) return xrun(Y.cdr()); } else eval(Y); } } }}); fn("==", new Fn() {public Any fn(Any E) { - Any X = E.cdr; - return eval(X.car) == eval(X.cdr.car) ? T : NIL; + Any X = E.cdr(); + return eval(X.car()) == eval(X.cdr().car()) ? T : NIL; }}); fn("peek", new Fn() {public Any fn(Any E) { Character X = peek(); - return null == X ? NIL : mkStr(X.toString()); + return null == X ? NIL : mkObj(X.toString()); }}); fn("char", new Fn() {public Any fn(Any E) { Character X = xchar(); - return null == X ? NIL : mkStr(X.toString()); + return null == X ? NIL : mkObj(X.toString()); }}); fn("print", new Fn() {public Any fn(Any E) { - PrintStream S = (PrintStream) Out.cxr; + PrintStream S = (PrintStream) Out.cdr().cxr(); Any Z = NIL; int I = 0; - for(Any X = E.cdr; NIL != X; X = X.cdr) { + for(Any X = E.cdr(); NIL != X; X = X.cdr()) { if(0 < I++) S.print(' '); - Z = eval(X.car); + Z = eval(X.car()); print(Z); } return Z; }}); - fn("in", new Fn() {public Any fn(Any E) { - Any X = E.cdr; - 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; - Z = xrun(X.cdr); - In.cxr = I; - S.s.close(); - } catch(FileNotFoundException e) { - err(E, "File not found"); - } catch(IOException e) { - err(E, "Error closing input"); - } - return Z; - }}); - fn("out", new Fn() {public Any fn(Any E) { - Any X = E.cdr; - 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; - Z = xrun(X.cdr); - Out.cxr = O; - S.close(); - } catch(FileNotFoundException e) { - err(E, "File not found"); - } - return Z; - }}); + // fn("in", new Fn() {public Any fn(Any E) { + // Any X = E.cdr; + // 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; + // Z = xrun(X.cdr); + // In.cxr = I; + // S.s.close(); + // } catch(FileNotFoundException e) { + // err(E, "File not found"); + // } catch(IOException e) { + // err(E, "Error closing input"); + // } + // return Z; + // }}); + // fn("out", new Fn() {public Any fn(Any E) { + // Any X = E.cdr; + // 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; + // Z = xrun(X.cdr); + // Out.cxr = O; + // S.close(); + // } catch(FileNotFoundException e) { + // err(E, "File not found"); + // } + // return Z; + // }}); // fn("load", new Fn() {public Any fn(Any E) { // Any Z = NIL; // for(Any X = E.cdr; NIL != X; X = X.cdr) { @@ -417,89 +549,90 @@ class wl implements Runnable { // }}); fn("def", new Fn() {public Any fn(Any E) { - Any X = E.cdr; - Any N = eval(X.car); + Any X = E.cdr(); + Any N = eval(X.car()); if(!N.isSym()) err(E, "Symbol expected"); - if(!Sd.containsKey(N.nm)) err(E, "Symbol not interned"); - Any V = eval(X.cdr.car); - Sd.get(N.nm).cdr = V; + if(!Sd.containsKey(N.nm())) err(E, "Symbol not interned"); + Any V = eval(X.cdr().car()); + Sd.get(N.nm()).con(V); return N; }}); fn("val", new Fn() {public Any fn(Any E) { Any Z = NIL; - Any X = eval(E.cdr.car); - if(X.isSym()) Z = X.cdr; - else if(X.isStr()) Z = X; - else if(X.isCons()) Z = X.car; - else err(E, "Expected sym|str|cell"); + Any X = eval(E.cdr().car()); + if(X.isCons()) Z = X.car(); + else if(X.isSym()) Z = X.cdr(); + else if(X.isObj()) Z = X; + else err(E, "Don't know how to val"); return Z; }}); fn("cons", new Fn() {public Any fn(Any E) { - Any X = E.cdr; - return cons(eval(X.car), eval(X.cdr.car)); + Any X = E.cdr(); + return mkCons(eval(X.car()), eval(X.cdr().car())); }}); - 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("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()); - } - 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("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 = mkObj(C); + // } catch(ClassNotFoundException e) { + // } + // return Z; + // }}); + // 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()); + // } + // Object[] aa = a.toArray(); + // Class[] ta = (Class[]) t.toArray(new Class[aa.length]); + // try { + // Object o = O.cxr(); + // Class c = o instanceof Class ? (Class) o : o.getClass(); + // Method m = c.getMethod(F.nm(), ta); + // Object r = m.invoke(o, aa); + // Z = mkObj(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 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) { + 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()); + 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); + Constructor c = ((Class) C.cxr()).getConstructor(ta); Object r = c.newInstance(aa); - Z = mkAny(r); + Z = mkObj(r); } catch(NoSuchMethodException e) { err(E, "NoSuchMethodException"); } catch(InstantiationException e) { @@ -511,67 +644,49 @@ class wl implements Runnable { } 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); + fn("jfield", new Fn() {public Any fn(Any E) { // jfield 'obj 'fld ['val] + // TODO set 'val + Any X = E.cdr(); + Any O = eval(X.car()); + X = X.cdr(); + Any F = 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); + Object o = O.cxr(); + Class c = o instanceof Class ? (Class) o : o.getClass(); + Field f = c.getField(F.nm()); + Object r = f.get(o); + Z = mkObj(r); } catch(NoSuchFieldException e) { - dbg("NoSuchFieldException", E); + err(E, "NoSuchFieldException"); } catch(IllegalAccessException e) { - dbg("IllegalAccessException", E); + err(E, "IllegalAccessException"); } 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)); - // }}); } 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"); + if(X.isSym()) S = X.nm(); + else if(X.isOstr()) S = (String) X.cxr(); + else err(E, "Don't know how to evStr"); 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.isCons()) { + PrintStream S = (PrintStream) Out.cdr().cxr(); + if(E.isCons()) { Any X = E; - // if(Qte == X.car) { - // S.print('\''); - // print(X.cdr); - // } else { - { + if(Qte == X.car()) { + S.print('\''); + print(X.cdr()); + } else { S.print('('); while(X.isCons()) { - print(X.car); - X = X.cdr; + print(X.car()); + X = X.cdr(); if(NIL != X) S.print(' '); if(E == X) { S.print('.'); @@ -584,30 +699,32 @@ class wl implements Runnable { } 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 { + } else if(E.isIsym()) S.print(E.nm()); + else if(E.isOnum()) S.print(E.cxr()); + else if(E.isOstr()) { + 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 if(E.isObj()) { S.print('['); - S.print(E.cxr); + S.print(E.cxr()); S.print(']'); - } + } else err(E, "Don't know how to print"); } String str(Any E) { ByteArrayOutputStream B = new ByteArrayOutputStream(); PrintStream S = new PrintStream(B); - PrintStream O = (PrintStream) Out.cxr; - Out.cxr = S; + Any O = Out.cdr(); + Out.con(mkObj(S)); print(E); - Out.cxr = O; + Out.con(O); String Z = null; try { Z = B.toString(Enc);