commit d68eb42502f07b3002cdad0f4f40adb9ec797687
parent 4b48fcb455bd30954d9e801d78ec2058fb31d4e3
Author: tomas <tomas@logand.com>
Date: Sat, 12 Sep 2009 11:59:10 +0200
all in one wl object
Diffstat:
M | index.org | | | 6 | ++++-- |
M | wl.js | | | 618 | +++++++++++++++++++++++++++++++++++++++---------------------------------------- |
2 files changed, 310 insertions(+), 314 deletions(-)
diff --git a/index.org b/index.org
@@ -31,8 +31,10 @@ function $$(Id) {return $(Id).textContent;}
</p>
<script>
function sandbox() {
- alert(str((new wlR).parse("one \"hi \\\"George\\\" go\" (12 3 (a . b) . 456) 7.8")));
- alert(str((new wlR).parse("(. (1 . 2))")));
+ var l = new wl;
+ alert(l.str(l.parse("one \"hi \\\"George\\\" go\" (12 3 (a b) 456) 7.8")));
+ alert(l.str(l.parse("one \"hi \\\"George\\\" go\" (12 3 (a . b) . 456) 7.8")));
+ alert(l.str(l.parse("(. (1 . 2))")));
}
</script>
<button onclick="javascript:sandbox();">Run</button> code from sandbox.
diff --git a/wl.js b/wl.js
@@ -1,34 +1,37 @@
// wl.js -- (c) 2009 Tomas Hlavaty
-function Cons(Car, Cdr) {
- this.car = Car;
- this.cdr = Cdr;
- return this;
-}
-function isCons(X) {return X && X.constructor === Cons;}
-function cons(Car, Cdr) {return new Cons(Car, Cdr);}
+function wl() {
+ var Me = this;
-function Sym(Nm, Val, Prop) {
- this.nm = Nm;
- this.car = Prop;
- this.cdr = Val;
- return this;
-}
-function isSym(X) {return X && X.constructor === Sym;}
-function sym(X) {return X.nm;}
+ function Cons(Car, Cdr) {
+ this.car = Car;
+ this.cdr = Cdr;
+ return this;
+ }
+ function isCons(X) {return X && X.constructor === Cons;}
+ function cons(Car, Cdr) {return new Cons(Car, Cdr);}
+
+ function Sym(Nm, Val, Prop) {
+ this.nm = Nm;
+ this.car = Prop;
+ this.cdr = Val;
+ return this;
+ }
+ function isSym(X) {return X && X.constructor === Sym;}
+ function sym(X) {return X.nm;}
-function car(X) {return X.car;}
-function cdr(X) {return X.cdr;}
+ function car(X) {return X.car;}
+ function cdr(X) {return X.cdr;}
-var NIL = new Sym("NIL");
-NIL.car = NIL;
-NIL.cdr = NIL;
+ var NIL = new Sym("NIL");
+ NIL.car = NIL;
+ NIL.cdr = NIL;
-function wlT() { // tokenizer
- var Me = this;
- Me.Qte = {};
- Me.Lp = {};
- Me.Rp = {};
+ var Qte = {};
+ var Lp = {};
+ var Rp = {};
+
+ // reader
function init(L) {
Me.L = L;
Me.N = L.length;
@@ -91,33 +94,23 @@ function wlT() { // tokenizer
case false: return undefined;
case "#": return comment();
case '"': xchar(); return text();
- case "'": xchar(); return Me.Qte;
- case "(": xchar(); Me.D++; return Me.Lp;
- case ")": xchar(); Me.D--; return Me.Rp;
+ case "'": xchar(); return Qte;
+ case "(": xchar(); Me.D++; return Lp;
+ case ")": xchar(); Me.D--; return Rp;
default: return symbol();
}
}
- wlT.prototype.init = init;
- wlT.prototype.peek = peek;
- wlT.prototype.token = token;
- return this;
-}
-function wlR(Sd) { // reader
- var Me = this;
- Me.Tk = new wlT;
- function init(L) {
- Me.Tk.init(L);
- }
+ // parser
function parse(L) {
- Me.Tk.init(L);
- var Os = [Me.Tk.Lp];
+ init(L);
+ var Os = [Lp];
function build() {
var Z = NIL;
var Dot;
while(0 < Os.length) {
var X = Os.pop();
- if(Me.Tk.Lp === X) return Dot ? cons(Dot, cons(Z, NIL)) : Z;
+ if(Lp === X) return Dot ? cons(Dot, cons(Z, NIL)) : Z;
Dot = false;
if(isSym(X) && "." == sym(X)) {
if(NIL === cdr(Z)) {
@@ -128,10 +121,10 @@ function wlR(Sd) { // reader
}
throw "Missing mark";
}
- while(Me.Tk.peek()) {
- var X = Me.Tk.token();
+ while(peek()) {
+ var X = token();
if(X) {
- if(Me.Tk.Rp === X) Os.push(build());
+ if(Rp === X) Os.push(build());
else Os.push(X);
}
}
@@ -139,195 +132,196 @@ function wlR(Sd) { // reader
if(0 < Os.length) throw "Incomplete input, left with " + Os;
return Z;
}
- wlR.prototype.init = init;
- wlR.prototype.parse = parse;
- return this;
-}
-function str(L) { // printer
- var A = [];
- if(typeof L == "number") A.push(L);
- else if(isSym(L)) A.push(sym(L));
- else if(isCons(L)) {
- A.push("(");
- while(isCons(L)) {
- A.push(str(car(L)));
- L = cdr(L);
- if(NIL !== L) A.push(" ");
- }
- if(NIL !== L) {
- A.push(". ");
- A.push(str(L));
- }
- A.push(")");
- } else {
- var Y = L.split("");
- for(var I = 0; I < Y.length; I++) {
- if(Y[I] == "\\") Y[I] = "\\\\";
- else if(Y[I] == '"') Y[I] = '\\"';
+ // printer
+ function str(L) {
+ var A = [];
+ if(typeof L == "number") A.push(L);
+ else if(isSym(L)) A.push(sym(L));
+ else if(isCons(L)) {
+ A.push("(");
+ while(isCons(L)) {
+ A.push(str(car(L)));
+ L = cdr(L);
+ if(NIL !== L) A.push(" ");
+ }
+ if(NIL !== L) {
+ A.push(". ");
+ A.push(str(L));
+ }
+ A.push(")");
+ } else {
+ var Y = L.split("");
+ for(var I = 0; I < Y.length; I++) {
+ if(Y[I] == "\\") Y[I] = "\\\\";
+ else if(Y[I] == '"') Y[I] = '\\"';
+ }
+ var S = Y.join("");
+ //var S = L.replace(/\"/g, "\\\"").replace(/\\/g, "\\\\");
+ A.push('"' + S + '"');
}
- var S = Y.join("");
- //var S = L.replace(/\"/g, "\\\"").replace(/\\/g, "\\\\");
- A.push('"' + S + '"');
+ return A.join("");
}
- return A.join("");
-}
+ wl.prototype.parse = parse;
+ wl.prototype.str = str;
+ return this;
+}
-function wl() {
- var Sd = {};
- var Rd = new wlR;
-
- Sd["car"] = function car(E) {return E.car;};
- Sd["cdr"] = function cdr(E) {return E.cdr;};
- Sd["cons"] = function cons(E) {return Rd.cons(E.car, E.cdr);};
- Sd["reverse"] = function reverse(E) {
- var Z = NIL;
- while(!isNil(E)) {
- Z = cons(E.car, Z);
- E = E.cdr;
- }
- return Z;
- };
- Sd["member"] = function member(E) {
- var F = E.car;
- var R = E.cdr;
- while(!isNil(R)) {
- if(!isNil(eq(F, R.car))) return R;
- R = R.cdr;
- }
- return NIL;
- };
- // Sd["caar"] = function caar(E) {return car(car(E));};
- // Sd["cadr"] = function cadr(E) {return car(cdr(E));};
- // Sd["cdar"] = function cdar(E) {return cdr(car(E));};
- // Sd["cddr"] = function cddr(E) {return cdr(cdr(E));};
- // Sd["caddr"] = function caddr(E) {return car(cdr(cdr(E)));};
- // Sd["cdddr"] = function cdddr(E) {return cdr(cdr(cdr(E)));};
- // Sd["cadddr"] = function cadddr(E) {return car(cdr(cdr(cdr(E))));};
- // Sd["cddddr"] = function cddddr(E) {return cdr(cdr(cdr(cdr(E))));};
-
- Sd["-"] = function(E) {var X = Os.pop(); Os.push(Os.pop() - X);};
- Sd["*"] = function(E) {Os.push(Os.pop() * Os.pop());};
- Sd["/"] = function(E) {var X = Os.pop(); Os.push(Os.pop() / X);};
- Sd["%"] = function(E) {var X = Os.pop(); Os.push(Os.pop() % X);};
-
- 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);};
-
- Sd["if"] = function() {
- var N = Os.pop();
- var P = Os.pop();
- var C = Os.pop();
- Es.push([false, C === true ? P : N]);
- };
-
- // Sd[".call"] = function() {
- // var N = Os.pop();
- // var K = Os.pop();
- // var D = Os.pop();
- // var X = [];
- // for(var I = 0; I < N; I++) X.unshift(Os.pop());
- // Os.push(D[K].apply(D, X));
- // };
- Sd[".math"] = function(E) {return Math;};
- Sd[".date"] = function(E) {return new Date();}; // TODO split new and Date
- Sd[".window"] = function(E) {return window;};
- // Sd[".callback"] = function() { // TODO event arg?
- // var X = Os.pop();
- // Os.push(function() {
- // Ps.run(X, true);
- // while(0 < Es.length)
- // Ps.step();
- // });
- // };
-
-
- Sd["list2array"] = function list2array(E) {
- var Z = [];
- while(!isNil(E)) {
- Z.push(E.car);
- E = E.cdr;
- }
- return Z;
- };
- // Sd["array2list"] = function array2list(A) {
- // var Z = NIL;
- // for(var I = A.length - 1; 0 <= I; I--)
- // Z = cons(A[I], Z);
- // return Z;
- // };
- // Sd["object2list"] = function object2list(O) {
- // var Z = NIL;
- // for(var I in O)
- // Z = cons(cons(I, O[I]), Z);
- // return Z;
- // };
-
- function parse() {
- var Z;
- var A = arguments;
- if(A.length)
- for(var I = 0; I < A.length; I++)
- Z = Rd.parse(A[I]);
- else Z = Rd.parse(A);
- return Z;
- }
- wl.prototype.parse = parse;
- return this;
-}
+// function wl() {
+// var Sd = {};
+// var Rd = new wlR;
+
+// Sd["car"] = function car(E) {return E.car;};
+// Sd["cdr"] = function cdr(E) {return E.cdr;};
+// Sd["cons"] = function cons(E) {return Rd.cons(E.car, E.cdr);};
+// Sd["reverse"] = function reverse(E) {
+// var Z = NIL;
+// while(!isNil(E)) {
+// Z = cons(E.car, Z);
+// E = E.cdr;
+// }
+// return Z;
+// };
+// Sd["member"] = function member(E) {
+// var F = E.car;
+// var R = E.cdr;
+// while(!isNil(R)) {
+// if(!isNil(eq(F, R.car))) return R;
+// R = R.cdr;
+// }
+// return NIL;
+// };
+// // Sd["caar"] = function caar(E) {return car(car(E));};
+// // Sd["cadr"] = function cadr(E) {return car(cdr(E));};
+// // Sd["cdar"] = function cdar(E) {return cdr(car(E));};
+// // Sd["cddr"] = function cddr(E) {return cdr(cdr(E));};
+// // Sd["caddr"] = function caddr(E) {return car(cdr(cdr(E)));};
+// // Sd["cdddr"] = function cdddr(E) {return cdr(cdr(cdr(E)));};
+// // Sd["cadddr"] = function cadddr(E) {return car(cdr(cdr(cdr(E))));};
+// // Sd["cddddr"] = function cddddr(E) {return cdr(cdr(cdr(cdr(E))));};
+
+// Sd["-"] = function(E) {var X = Os.pop(); Os.push(Os.pop() - X);};
+// Sd["*"] = function(E) {Os.push(Os.pop() * Os.pop());};
+// Sd["/"] = function(E) {var X = Os.pop(); Os.push(Os.pop() / X);};
+// Sd["%"] = function(E) {var X = Os.pop(); Os.push(Os.pop() % X);};
+
+// 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);};
+
+// Sd["if"] = function() {
+// var N = Os.pop();
+// var P = Os.pop();
+// var C = Os.pop();
+// Es.push([false, C === true ? P : N]);
+// };
+
+// // Sd[".call"] = function() {
+// // var N = Os.pop();
+// // var K = Os.pop();
+// // var D = Os.pop();
+// // var X = [];
+// // for(var I = 0; I < N; I++) X.unshift(Os.pop());
+// // Os.push(D[K].apply(D, X));
+// // };
+// Sd[".math"] = function(E) {return Math;};
+// Sd[".date"] = function(E) {return new Date();}; // TODO split new and Date
+// Sd[".window"] = function(E) {return window;};
+// // Sd[".callback"] = function() { // TODO event arg?
+// // var X = Os.pop();
+// // Os.push(function() {
+// // Ps.run(X, true);
+// // while(0 < Es.length)
+// // Ps.step();
+// // });
+// // };
+
+
+// Sd["list2array"] = function list2array(E) {
+// var Z = [];
+// while(!isNil(E)) {
+// Z.push(E.car);
+// E = E.cdr;
+// }
+// return Z;
+// };
+// // Sd["array2list"] = function array2list(A) {
+// // var Z = NIL;
+// // for(var I = A.length - 1; 0 <= I; I--)
+// // Z = cons(A[I], Z);
+// // return Z;
+// // };
+// // Sd["object2list"] = function object2list(O) {
+// // var Z = NIL;
+// // for(var I in O)
+// // Z = cons(cons(I, O[I]), Z);
+// // return Z;
+// // };
+
+// function parse() {
+// var Z;
+// var A = arguments;
+// if(A.length)
+// for(var I = 0; I < A.length; I++)
+// Z = Rd.parse(A[I]);
+// else Z = Rd.parse(A);
+// return Z;
+// }
+// wl.prototype.parse = parse;
+// return this;
+// }
-/// lisp
+// /// lisp
-// function format(N, S) {
-// var X = "" + N;
-// var L = X.length;
-// return X.slice(0, L - S) + "." + X.slice(L - S, L);
-// }
+// // function format(N, S) {
+// // var X = "" + N;
+// // var L = X.length;
+// // return X.slice(0, L - S) + "." + X.slice(L - S, L);
+// // }
-// function real(N, S) {
-// return N / Math.pow(10, S);
-// }
+// // function real(N, S) {
+// // return N / Math.pow(10, S);
+// // }
-var Syms = {};
+// var Syms = {};
-function mkSym(Nm, Val, Prop) {
- var X = new Sym(Nm, Val, Prop);
- Syms[Nm] = X;
- return X;
-}
+// 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 xget(Sym) {
+// return isSym(Sym) ? Sym._val : Sym;
+// }
-function xset(Sym, Val) {
- if(!isSym(Sym)) throw "Sym expected";
- Sym._val = Val;
- return Sym._val;
-}
+// function xset(Sym, Val) {
+// if(!isSym(Sym)) throw "Sym expected";
+// Sym._val = Val;
+// return Sym._val;
+// }
-//var NIL = mkSym("NIL");
-var T = mkSym("T");
+// //var NIL = mkSym("NIL");
+// var T = mkSym("T");
-//xset(NIL, NIL);
-xset(T, T);
-// TODO set props for NIL and 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] || (Syms[Sym] = mkSym(Sym, NIL, NIL));
-}
+// function intern(Sym) {
+// //if(!(Sym in Syms)) Syms[Sym] = mkSym(Sym, NIL, NIL);
+// return Syms[Sym] || (Syms[Sym] = mkSym(Sym, NIL, NIL));
+// }
-function isT(X) {
- return X === T;
-}
+// function isT(X) {
+// return X === T;
+// }
@@ -336,117 +330,117 @@ function isT(X) {
-function eq(X, Y) {
- if(X === Y) return T;
- //if(X == Y) return T;
- return NIL;
-}
+// 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 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 lsApply(Fn, Args) {
-}
+// function lsApply(Fn, Args) {
+// }
-function jsFn(Fn) {
- var F = function() {
- return lsApply(Fn, list2array(arguments));
- };
- return F;
-}
+// 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)));
-}
+// function jsApply() {
+// var Fn = arguments.shift();
+// var Args = arguments.shift();
+// var Rest = arguments;
+// return Fn.apply(list2array(Args).unshift.apply(list2array(Rest)));
+// }
-var Xeval = {};
+// var Xeval = {};
-function xdef(Nm, Fn) {
- if(!(Nm in Syms)) intern(Nm);
- Xeval[Nm] = Fn;
-}
+// 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)));
-}
+// 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"))));
-}
+// 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
+// // parser
-function isArray(A) {
- return A && A.constructor == Array;
-}
+// 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 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 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 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 xmsg(A) {
- var B = parse(A);
- var X = flatten(unparse(B)).join("");
- mk(w("test"), "pre", {}, {}, "'" + A + "' => " + X);
-}
+// function xmsg(A) {
+// var B = parse(A);
+// var X = flatten(unparse(B)).join("");
+// mk(w("test"), "pre", {}, {}, "'" + A + "' => " + X);
+// }