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));
+// }