113 lines
2.6 KiB
JavaScript
113 lines
2.6 KiB
JavaScript
var TopEnvironment = function() {
|
|
this.bindings = {'=': function(argl) {
|
|
return argl[0] === argl[1][0];
|
|
},
|
|
'+': function(argl) {
|
|
return argl[0] + argl[1][0];
|
|
},
|
|
'-': function(argl) {
|
|
return argl[0] - argl[1][0];
|
|
}
|
|
};
|
|
this.parent = undefined;
|
|
};
|
|
|
|
var ExtendedEnvironment = function(parent) {
|
|
this.bindings = {};
|
|
this.parent = parent;
|
|
};
|
|
|
|
|
|
var Closure = function(env, label) {
|
|
this.env = env;
|
|
this.label = label;
|
|
};
|
|
|
|
|
|
var _isFalse = function(x) { if(x) return false; return true; }
|
|
var _isPrimProc = function(x) { return typeof(x) === 'function'; };
|
|
var _applyPrimProc = function(p, argl) { return p(argl); }
|
|
var _closureEnv = function(c) { return c.env; }
|
|
var _closureEntry = function(c) { return c.label; }
|
|
var _makeClosure = function(l, e) { return new Closure(e, l); }
|
|
var _envDefine = function(n, v, e) {
|
|
e.bindings[n] = v;
|
|
};
|
|
var _envExtend = function(ns, vs, e) {
|
|
var e2 = new ExtendedEnvironment(e);
|
|
while(ns) {
|
|
e2.bindings[ns[0]] = vs[0];
|
|
ns = ns[1]; vs = vs[1];
|
|
}
|
|
return e2;
|
|
};
|
|
var _envLookup = function(n, e) {
|
|
while (e) {
|
|
if (e.bindings.hasOwnProperty(n)) {
|
|
return e.bindings[n];
|
|
}
|
|
e = e.parent;
|
|
}
|
|
throw new Error("Not bound: " + n);
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Lexical addressing
|
|
var _lexicalAddressLookup = function(depth, pos, env) {
|
|
// FIXME
|
|
};
|
|
|
|
var _lexicalAddressAssign = function(depth, pos, env, value) {
|
|
// FIXME
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
var _cons = function(x, y) { return [x, y]; }
|
|
var _list = function() {
|
|
var i;
|
|
var result;
|
|
for (i = arguments.length - 1; i >= 0; i--) {
|
|
result = [arguments[i], result];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
var MACHINE={callsBeforeTrampoline: 100,
|
|
env: new TopEnvironment(),
|
|
proc:undefined,
|
|
argl:undefined,
|
|
val:undefined,
|
|
cont:undefined,
|
|
stack: []};
|
|
|
|
|
|
// harness: (->) (->) -> void
|
|
var _harness = function(thunk, k) {
|
|
var toCall;
|
|
MACHINE.callsBeforeTrampoline = 100;
|
|
while(thunk) {
|
|
try {
|
|
toCall = thunk;
|
|
thunk = undefined;
|
|
toCall();
|
|
} catch (e) {
|
|
if (typeof(e) === 'function') {
|
|
thunk = e;
|
|
MACHINE.callsBeforeTrampoline = 100;
|
|
} else if (e === 'done') {
|
|
break;
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
k();
|
|
};
|