author | Alan Dipert
<alan@dipert.org> 2019-10-16 22:59:40 UTC |
committer | Alan Dipert
<alan@dipert.org> 2019-10-16 22:59:40 UTC |
parent | 8a1794063448f61c862bf3dde3e65eb3936a5d0b |
jacl.js | +55 | -4 |
diff --git a/jacl.js b/jacl.js index 76e7c62..08a8123 100644 --- a/jacl.js +++ b/jacl.js @@ -831,7 +831,7 @@ const parseCall = (env, parent, form) => { if (isLambdaForm(func)) { node.f = analyze(env, parent, func); } else if (func instanceof LispSymbol && env.localFuns.has(func.name)) { - node.f = makeNode("local", { env: env, parent: node, form: func, name: munge(func.name) }); + node.f = makeNode("local", { env: env, parent: node, form: func }); } else if (func instanceof LispSymbol) { node.f = makeNode("global", { env: env, parent: node, form: func, slot: "function" }); } @@ -857,13 +857,12 @@ const analyzeList = (env, parent, form) => { const analyzeSymbol = (env, parent, form) => { const node = makeNode(null, { env: env, parent: parent, form: form }); if (form.packageName === 'KEYWORD') { - node.op = "constant"; + node.op = "keyword"; } else if (form.packageName === 'JS' && !form.getPackage().isExported(form.name)) { node.op = "js-var"; node.name = form.name; } else if (env.localVals.has(form.name)) { node.op = "local"; - node.name = munge(form.name); } else { node.op = "global"; node.slot = "value"; @@ -913,13 +912,65 @@ const analyze = (env, parent, form) => { } }; +const emitWrap = (node, print, thunk) => { + if (node.env.context === "return") print("return "); + thunk(); + if (node.env.context !== "sval") print(";\n"); +} + +const emitNode = (node, print) => { + const { op, env, parent, form } = node; + switch (op) { + case "js-var": + print(node.name); + break; + case "keyword": + // TODO escape symbol name, reconsider how to compile keywords + print(`Package.kw('${form.name}', false)`); + break; + case "local": + print(munge(form.name)); + break; + case "global": + // TODO escape packageName, name + print(`Package.get('${form.packageName}').intern('${form.name}')`); + if (node.slot === 'value') { + print(".val()"); + } else if (node.slot === 'function') { + print(".func()"); + } else { + throw new Error(`Unknown global slot: ${node.slot}`); + } + break; + case "call": + // TODO + break; + default: + throw new Error(`Unknown op: ${op}`); + } +}; + +const emit = (() => { + let sb = ""; + return node => { + emitNode(node, x => { + sb += x; + return null; + }); + return sb; + }; +})(); + var buf = new BufferedStream(), rdr = new Reader(buf); (async function() { for await(const obj of rdr) { console.log("read:", obj); - console.log(analyze(emptyEnv, null, obj)); + const node = analyze(emptyEnv, null, obj); + console.log(node); + const code = emit(node) + console.log(code); //console.log("compiled:", compile(obj, null)); //console.log("evaled:", eval(compile(obj, null))); }