commit b743a40c9b5e478711ba13c920b54d76e6294678
Author: tomas <tomas@logand.com>
Date:   Sat, 12 Sep 2009 00:22:51 +0200
Initial version
Diffstat:
| A | index.org |  |  | 33 | +++++++++++++++++++++++++++++++++ | 
| A | wl.js |  |  | 346 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
2 files changed, 379 insertions(+), 0 deletions(-)
diff --git a/index.org b/index.org
@@ -0,0 +1,33 @@
+#+title: lisp4web
+#+description: 
+#+keywords: 
+
+* lisp4web
+
+#+html: <div id="wl" style="display:none">
+#+include "wl.wl" src text
+#+html: </div>
+
+#+begin_html
+<script type="text/javascript" src="nopdf.js"></script>
+<style>canvas {width:12em;height:12em;border:1px dashed black}</style>
+<script type="text/javascript" src="wps.js"></script>
+<script>
+function $(Id) {return document.getElementById(Id);}
+function $$(Id) {return $(Id).textContent;}
+</script>
+<div id="out"></div>
+<p>Sandbox:</p>
+<p>
+<textarea id="sandbox" style="width:100%" rows="18">
+</textarea>
+</p>
+<script>
+function sandbox() {(new Wps).parse($$("wps"), "(xsandbox) .setGc", $("sandbox").value);}
+</script>
+<button onclick="javascript:sandbox();">Run</button> code from sandbox.
+#+end_html
+
+** Links
+
+- http://joeganley.com/code/jslisp.html
diff --git a/wl.js b/wl.js
@@ -0,0 +1,346 @@
+// ls -- Tomas Hlavaty 28feb2009
+
+function Cons(Car, Cdr) {
+    this.car = Car;
+    this.cdr = Cdr;
+    this._isCons = "b92e7eb4b4a84432696d4892e2c114b3";
+}
+
+function isCons(X) {
+    return X && X._isCons == "b92e7eb4b4a84432696d4892e2c114b3";
+}
+
+function cons(A, D) {
+    return new Cons(A, D);
+}
+
+function Sym(Nm, Val, Prop) {
+    this._nm = Nm;
+    this._val = Val;
+    this._prop = Prop;
+    this._isSym = "b32e74b4b5a844626967489282c194b0";
+}
+
+function isSym(X) {
+    return X && X._isSym == "b32e74b4b5a844626967489282c194b0";
+}
+
+var Syms = {};
+
+function mkSym(Nm, Val, Prop) {
+    var X = new Sym(Nm, Val, Prop);
+    Syms[Nm] = X;
+    return X;
+}
+
+function xget(Sym) {
+    return isSym(Sym) ? Sym._val : Sym;
+}
+
+function xset(Sym, Val) {
+    if(!isSym(Sym)) throw "Sym expected";
+    Sym._val = Val;
+    return Sym._val;
+}
+
+var NIL = mkSym("NIL");
+var T = mkSym("T");
+
+xset(NIL, NIL);
+xset(T, T);
+// TODO set props for NIL and T
+
+function intern(Sym) {
+    if(!(Sym in Syms)) Syms[Sym] = mkSym(Sym, NIL, NIL);
+    return Syms[Sym];
+}
+
+function isNil(X) {
+    return X === NIL;
+}
+
+function isT(X) {
+    return X === T;
+}
+
+function car(L) {
+    return isNil(L) ? NIL : L.car;
+}
+
+function cdr(L) {
+    return isNil(L) ? NIL : L.cdr;
+}
+
+function caar(L) {
+    return car(car(L));
+}
+
+function cadr(L) {
+    return car(cdr(L));
+}
+
+function cdar(L) {
+    return cdr(car(L));
+}
+
+function cddr(L) {
+    return cdr(cdr(L));
+}
+
+function caddr(L) {
+    return car(cdr(cdr(L)));
+}
+
+function cadddr(L) {
+    return car(cdr(cdr(cdr(L))));
+}
+
+function array2list(A) {
+    var L = NIL;
+    for(var I = A.length - 1; 0 <= I; I--) {
+        L = cons(A[I], L);
+    }
+    return L;
+}
+
+function list2array(L) {
+    var A = [];
+    while(!isNil(L)) {
+        A.push(L.car);
+        L = L.cdr;
+    }
+    return A;
+}
+
+function object2list(A) {
+    var L = NIL;
+    for(var I in A) {
+        L = cons(cons(I, A[I]), L);
+    }
+    return L;
+}
+
+function reverse(L) {
+    var X = NIL;
+    while(!isNil(L)) {
+        X = cons(L.car, X);
+        L = L.cdr;
+    }
+    return X;
+}
+
+function eq(X, Y) {
+    if(X === Y) return T;
+    //if(X == Y) return T;
+    return NIL;
+}
+
+function xdelete(A, L) {
+    var X = NIL;
+    while(!isNil(L)) {
+        if(isNil(eq(A, L.car))) X = cons(L.car, X);
+        L = L.cdr;
+    }
+    return reverse(X);
+}
+
+function member(A, L) {
+    while(!isNil(L)) {
+        if(!isNil(eq(A, L.car))) return L;
+        L = L.cdr;
+    }
+    return NIL;
+}
+
+function lsApply(Fn, Args) {
+}
+
+function jsFn(Fn) {
+    var F = function() {
+        return lsApply(Fn, list2array(arguments));
+    };
+    return F;
+}
+
+function jsApply() {
+    var Fn = arguments.shift();
+    var Args = arguments.shift();
+    var Rest = arguments;
+    return Fn.apply(list2array(Args).unshift.apply(list2array(Rest)));
+}
+
+var Xeval = {};
+
+function xdef(Nm, Fn) {
+    if(!(Nm in Syms)) intern(Nm);
+    Xeval[Nm] = Fn;
+}
+
+xdef("quote", function(E) {
+        return cdr(E); // or cdr?
+    });
+xdef("if", function(E) {
+        if(!isNil(xeval(cadr(E)))) return xeval(caddr(E));
+        else return xeval(cadddr(E));
+    });
+xdef("prog", function(E) {
+        var L = cdr(E);
+        var X = NIL;
+        while(!isNil(L)) {
+            X = xeval(L.car);
+            L = L.cdr;
+        }
+        return X;
+    });
+
+function xeval(E) {
+    if(isSym(E)) return xget(E);
+    else if(!isCons(E)) return E;
+    else if(car(E)._nm in Xeval) return Xeval[car(E)._nm](E);
+    else return xapply(xeval(car(E)), map(xeval, cdr(E)));
+}
+
+function initLisp() {
+    //xalert(xeval(NIL), xeval(T), xeval(12), xeval(12.3), xeval({x: "hi"}), xeval([1, 2]));
+    //xalert(xeval(cons(intern("quote"), cons("whoa", NIL))));
+    //xalert(xeval(cons(intern("quote"), cons("whoa", cons("b", NIL)))));
+    //xalert(intern("if"));
+    //xalert(object2list(Syms));
+    //xalert(object2list(Xeval));
+    //xalert(xeval(cons(intern("if"), cons(T, cons("yes", cons("no", NIL))))));
+    //xalert(xeval(cons(intern("if"), cons(NIL, cons("yes", cons("no", NIL))))));
+    //xalert(xeval(cons(intern("quote"), intern("whoa"))));
+}
+
+// parser
+
+function isWhite(C) {
+    return isNil(C) ? false : 0 <= " \t\n\r".indexOf(C);
+}
+
+function parse(S) { // TODO cons . notation
+    var L = S.split("");
+    function peek() {
+        return 0 < L.length ? L[0] : NIL;
+    }
+    function xchar() {
+        return 0 < L.length ? L.shift() : NIL;
+    }
+    function skip() {
+        while(isWhite(peek())) xchar();
+    }
+    function many() {
+        var X;
+        while(!isNil(peek()) && peek() != ")") {
+            var O = one();
+            if(O) {
+                X = cons(O, X ? X : NIL);
+            }
+        }
+        if(X) X = reverse(X);
+        return X;
+    }
+    function one() {
+        skip();
+        var X;
+        var C = peek();
+        if(!isNil(C) && C != ")") {
+            if(C == "(") {
+                xchar();
+                X = many() || NIL;
+                if(xchar() != ")") throw "Unbalanced parenthesis";
+            } else {
+                var Tok = [];
+                while(!isNil(peek()) && peek() != ")" && !isWhite(peek())) {
+                    Tok.push(xchar());
+                }
+                if(0 < Tok.length) {
+                    X = Tok.join("");
+                }
+            }
+        }
+        return X;
+    }
+    var X = many();
+    if(0 < L.length) throw "Parsing not completed";
+    return X ? X : NIL;
+}
+
+function unparse(X) {
+    var A = [];
+//     if(isNil(X)) {
+//         A.push("NIL");
+//     } else if(isT(X)) {
+//         A.push("T");
+    if(isSym(X)) {
+        A.push(X._nm); // TODO sym()
+    } else if(isCons(X)) {
+        A.push("(");
+        while(isCons(X)) {
+            A.push(unparse(X.car));
+            X = X.cdr;
+            if(!isNil(X)) A.push(" ");
+        }
+        if(!isNil(X)) {
+            A.push(". ");
+            A.push(unparse(X));
+        }
+        A.push(")");
+    } else {
+        A.push("\"" + X + "\"");
+    }
+    return A;
+}
+
+function isArray(A) {
+    return A && A.constructor == Array;
+}
+
+function flatten(A) {
+    var X = [];
+    function rec(B) {
+        var N = B.length;
+        var I;
+        for(I = 0; I < N; I++) {
+            if(isArray(B[I])) rec(B[I]);
+            else X.push(B[I]);
+        }
+    }
+    rec(A);
+    return X;
+}
+
+function lisp2string(Any) {
+    return flatten(unparse(Any)).join("");
+}
+
+function xalert() {
+    var X = [];
+    var N = arguments.length;
+    var I;
+    for(I = 0; I < N; I++) {
+        X.push(flatten(unparse(arguments[I])).join(""));
+    }
+    alert(X.join(" "));
+}
+
+function format(N, S) {
+    var X = "" + N;
+    var L = X.length;
+    return X.slice(0, L - S) + "." + X.slice(L - S, L);
+}
+
+// function initLisp() {
+// //     xalert(parse(""));
+// //     xalert(parse("  "));
+// //     xalert(parse("1"));
+// //     xalert(parse("NIL"));
+// //     xalert(parse("T"));
+// //     xalert(parse("()"));
+// //     xalert(parse("(cons 1 NIL)"));
+// //     xalert(parse("(cons T T)"));
+// //     xalert(parse("(list)"));
+// //     xalert(parse("(list 1 2)"));
+//     xalert(xeval(NIL), xeval(T), xeval(12), xeval(12.3), xeval({x: "hi"}));
+//     xalert(xeval(cons(intern("if"), NIL));
+// }