Skip to content

Instantly share code, notes, and snippets.

@wshager
Last active June 24, 2018 13:09
Show Gist options
  • Save wshager/10306c54806cbd13c6b5786f7ca39e6a to your computer and use it in GitHub Desktop.
Save wshager/10306c54806cbd13c6b5786f7ca39e6a to your computer and use it in GitHub Desktop.
function compile(o, cx) {
// initial evaluation context inherits from external cx or configuration object
cx = new Context(cx);
// track initial evaluation context in quotation scope
const quots = [cx];
// this is a reduction into a single result (a callable context)
return o.reduce((cx, node) => {
const type = node.type;
if (isClose(type)) {
// handle node close:
// contains reference to the node that closes...
if (isQuotNode(node.node)) {
// handle quotation close:
// if we're in a quotation context, close it
const dest = quots.pop();
// get the current target from the scope array (uses https://github.com/keithamus/proposal-array-last)
// target is either a quotation or the initial evaluation context
const target = quots.last();
target.append(dest);
} else {
// find the current target
const target = quots.last();
if (isVarNode(node.node)) {
// handle var or param:
const count = node.node.count();
if (count > 1 && node.node.depth == 1) {
// handle private top-level declaration: simply add as export
target.addExport(count);
} else {
target.addVar(count);
}
} else if (isModuleNode(node.node)) {
// handle module insertion:
target.addModule(node.node);
} else if (isImportNode(node.node)) {
// handle import:
target.addImport(node.node);
} else if (isExportNode(node.node)) {
// handle export:
// expect type to be compiled to a single Call
target.addExport(node.node.count());
} else if (isPartialNode(node.node)) {
// handle partial:
// append partial sentinel for papply-any to stack
target.append($_);
} else {
// retrieve call from last open
target.addCall(node.node.name, node.node.count());
}
}
} else if (isDirect(type)) {
// handle direct call of inline quotation or function reference:
// e.g.
// add#2(3,4)
// OR
// {add($(1),$(2))}(3,4)
// should call last on stack
// NOTE these may be chained!
target.addDirect(node.node);
} else if (isLeaf(type)) {
// handle leaf (Datum):
// find the current target
const target = quots.last();
// NOTE comments are emitted, but should be ignored
target.addDatum(node.type, node.value);
} else if (isBranch(type)) {
if (isQuotNode(node)) {
// handle quotation:
// open new quotation scope (closure)
quots.push(new Quot(cx));
}
}
return cx;
}, cx); //.map(cx => cx.apply());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment