wl

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

commit b743a40c9b5e478711ba13c920b54d76e6294678
Author: tomas <tomas@logand.com>
Date:   Sat, 12 Sep 2009 00:22:51 +0200

Initial version

Diffstat:
Aindex.org | 33+++++++++++++++++++++++++++++++++
Awl.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)); +// }