git » jacl.git » commit a39ed0d

emit constants directly, implement quote

author Alan Dipert
2019-09-28 22:25:17 UTC
committer Alan Dipert
2019-09-28 22:25:17 UTC
parent 8b216dee710eabc9d0d57b7cdc30186bb2219edb

emit constants directly, implement quote

jacl.js +26 -12

diff --git a/jacl.js b/jacl.js
index 3c15a53..d4b72d3 100644
--- a/jacl.js
+++ b/jacl.js
@@ -240,26 +240,27 @@ Package.makePackage('KEYWORD');
 
 // CL package constants
 const CLCONSTS = new Map([
-  ['T', true],
-  ['NIL', null]
+  ['T', 'true'],
+  ['NIL', 'null']
 ]);
 
 for (const [k,v] of CLCONSTS) {
-  CLPKG.intern(k).value = v;
+  CLPKG.intern(k);
   CLPKG.exportSymbol(k);
 }
 
 // JS package constants
 const JSCONSTS = new Map([
-  ['+FALSE+', false],
-  ['+NAN+', NaN],
-  ['+NULL+', null],
-  ['+TRUE+', true],
-  ['+UNDEFINED+', undefined]
+  ['+FALSE+', 'false'],
+  ['+NAN+', 'NaN'],
+  ['+NULL+', 'null'],
+  ['+TRUE+', 'true'],
+  ['+UNDEFINED+', 'undefined'],
+  ['+THIS+', 'this']
 ]);
 
 for (const [k,v] of JSCONSTS) {
-  JSPKG.intern(k).value = v;
+  JSPKG.intern(k);
   JSPKG.exportSymbol(k);
 }
 
@@ -660,9 +661,11 @@ const compile = (form, env) => {
   } else if (form instanceof LispString) {
     return `(LispString.fromString("${form}"))`;
   } else if (form instanceof LispSymbol && form.packageName !== null) {
-    // TODO handle JS: and COMMON-LISP:{NIL,T} like constants here
-    // (emit directly, no symbol junk)
-    if (form.packageName === 'JS' && !JSCONSTS.has(form.name)) {
+    if (form.packageName === 'COMMON-LISP' && CLCONSTS.has(form.name)) {
+      return CLCONSTS.get(form.name);
+    } else if (form.packageName === 'JS' && JSCONSTS.has(form.name)) {
+      return JSCONSTS.get(form.name);
+    } else if (form.packageName === 'JS' && !JSCONSTS.has(form.name)) {
       return form.name;
     } else {
       return `LispSymbol.intern(${JSON.stringify(form.packageName)}, ${JSON.stringify(form.name)}).val()`;
@@ -683,6 +686,17 @@ const compile = (form, env) => {
       return `${compile(func, env)}(` +
         args.map(x => compile(x, env)).join(',') +
         `)`;
+    } else if (CLPKG.intern('QUOTE') === op) {
+      if (arg1 instanceof LispSymbol) {
+        return `LispSymbol.intern(${JSON.stringify(arg1.packageName)}, ${JSON.stringify(arg1.name)})`;
+      } else if (arg1 instanceof Cons) {
+        let car = compile(Cons.listOf(CLPKG.intern('QUOTE'), arg1.car)),
+            cdr = compile(Cons.listOf(CLPKG.intern('QUOTE'), arg1.cdr))
+        return `(new Cons(${car},${cdr}))`;
+      } else {
+        return compile(arg1, env);
+      }
+      return compile(arg1, env);
     } else if (op instanceof LispSymbol) {
       return `LispSymbol.intern('${op.packageName}', '${op.name}').func()(` +
         args.map(x => compile(x, env)).join(',') +