git » jacl.git » commit 430e33c

wip emit

author Alan Dipert
2019-10-16 22:59:40 UTC
committer Alan Dipert
2019-10-16 22:59:40 UTC
parent 8a1794063448f61c862bf3dde3e65eb3936a5d0b

wip emit

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)));
   }