git » jacl.git » commit 10739b6

gclosure fixes and ?deliver

author Alan Dipert
2020-07-24 14:30:41 UTC
committer Alan Dipert
2020-07-24 14:30:41 UTC
parent 8c61b0d5a7abea9cfea46cf963932a5f5bfd1b42

gclosure fixes and ?deliver

boot.lisp +1 -1
jacl.js +26 -6

diff --git a/boot.lisp b/boot.lisp
index c8f39de..4e1350a 100644
--- a/boot.lisp
+++ b/boot.lisp
@@ -50,7 +50,7 @@
                              ,labelname#)
               ,vname#)))
 
-(%js "~(~{}.fvalue = ~{})"
+(%js "(~{}.fvalue = ~{})"
      '%has-declare?
      (%lambda nil nil
        (body)
diff --git a/jacl.js b/jacl.js
index 7f922e0..6ac96a9 100644
--- a/jacl.js
+++ b/jacl.js
@@ -321,7 +321,7 @@ class LispSymbol {
 // then using LispStrings everywhere we currently use JS Strings
 class LispString extends Array {
   static fromString(str) {
-    return new LispString(...str.split(''));
+    return LispString.from(str.split(''));
   }
   toString() {
     return this.join('');
@@ -1954,10 +1954,13 @@ const emitNode = (print, node) => {
       break;
     }
     case 'lambda': {
+      if (context === 'expr' || context == 'return') {
+        print(`(`);
+      }
       if (node.declarations.find(x => List.first(x) === JACLPKG.intern('ASYNC'))) {
-        print(`(async function ${node.name}(`);
+        print(`async function ${node.name}(`);
       } else {
-        print(`(function ${node.name}(`);
+        print(`function ${node.name}(`);
       }
       // Emit required argument names
       // TODO Move lambda list production to a function for use by macro ll,
@@ -2115,7 +2118,11 @@ const emitNode = (print, node) => {
         print(';\n');
       }
       emitBlock(print, node.statements, node.ret);
-      print('})');
+      if (context === 'expr' || context == 'return') {
+        print('})');
+      } else {
+        print(`}\n`);
+      }
       break;
     } case 'call':
       if (context === 'return') print('return ');
@@ -2359,6 +2366,9 @@ const startRepl = async () => {
 };
 
 const loadLispScripts = async () => {
+  let urlParams = new URLSearchParams(window.location.search),
+      deliverAs = urlParams.get("deliver"),
+      compiledCode = "";
   for (let i = 0; i < document.head.childNodes.length; i++) {
     const child = document.head.childNodes[i];
     if (child.nodeName === 'SCRIPT' && child.src.endsWith('.lisp')) {
@@ -2368,18 +2378,28 @@ const loadLispScripts = async () => {
       const rdr = new Reader(ss);
       for await(const obj of rdr) {
         if (obj === EOF) break;
-        const node = optimize(analyze(emptyEnv, null, obj));
+        const node = optimize(analyze(emptyEnv.withContext('stmt'), null, obj));
         const sb = new StringBuffer();
         emitNode(sb.append.bind(sb), node);
+        if (deliverAs !== null) {
+          compiledCode += `\n${sb.toString()}`;
+        }
         // console.log(sb.toString());
         eval(sb.toString());
       }
       console.log(`;Loaded ${child.src} in ${(new Date())-start} ms`);
     }
   }
+  if (deliverAs !== null) {
+    let selfsrc = document.querySelector('script[data-name="jacl"]').src,
+        prelude = await (await fetch(selfsrc, {cache: "reload"})).text(),
+        file = new File([prelude + '\n' + compiledCode], deliverAs || "app.js", {type: "application/javascript;charset=utf-8"});
+    saveAs(file);
+  }
+
 };
 
-window.addEventListener('load', async () => {
+window.addEventListener('DOMContentLoaded', async () => {
   await loadLispScripts();
   //QUnit.start();
   await startRepl();