wl

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

commit 7d4915d7392b8e071c4ccbffd179d0b48804a280
parent b8f1f048daff1b016c995c02056eff5c2ee08885
Author: tomas <tomas@logand.com>
Date:   Tue,  6 Oct 2009 21:09:48 +0200

eval and java ffi

Diffstat:
Mwl.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);};