git » jacl.git » commit 97aed2d

Preliminary (DECLARE (ASYNC)) for LAMBDA; JACL:AWAIT macro

author Alan Dipert
2020-02-24 03:19:05 UTC
committer Alan Dipert
2020-02-24 03:19:05 UTC
parent ce9ffdad317da4413db0bf15b3235e37b455ee83

Preliminary (DECLARE (ASYNC)) for LAMBDA; JACL:AWAIT macro

jacl.js +32 -3

diff --git a/jacl.js b/jacl.js
index 2fd1762..3313c6e 100644
--- a/jacl.js
+++ b/jacl.js
@@ -429,6 +429,12 @@ for (const kw of ['&OPTIONAL', '&REST', '&KEY', '&ALLOW-OTHER-KEYS', '&AUX']) {
   CLPKG.exportSymbol(kw);
 }
 
+// Declaration-related symbols
+CLPKG.intern('DECLARE');
+CLPKG.exportSymbol('DECLARE');
+JACLPKG.intern('ASYNC');
+JACLPKG.exportSymbol('ASYNC');
+
 // JS package constants
 const JSCONSTS = new Map([
   ['+FALSE+', false],
@@ -1240,8 +1246,16 @@ const analyzeSpecials = new Map([
     return node;
   }],
   [JACLPKG.intern('%LAMBDA'), (env, parent, form) => {
-    const [, list, ...body] = form;
-    const node = makeNode('lambda', { env: env, parent: parent, form: form });
+    let [, list, ...body] = form;
+    let declarations = [];
+    if (body.length > 0
+        && List.isProperList(body[0])
+        && (List.first(body[0]) === CLPKG.intern('DECLARE'))) {
+      [, declarations] = body[0];
+      declarations = List.toArray(List.rest(body[0]));
+      body = body.slice(1);
+    }
+    node = makeNode('lambda', { env: env, parent: parent, form: form, declarations: declarations });
     const { lambdaList, bodyEnv } = analyzeLambdaList(env.withContext('expr'), node, list);
     node.lambdaList = lambdaList;
     return merge(
@@ -1729,7 +1743,11 @@ const emitNode = (print, node) => {
       break;
     }
     case 'lambda': {
-      print('(function(');
+      if (node.declarations.find(x => List.first(x) === JACLPKG.intern('ASYNC'))) {
+        print('(async function(');
+      } else {
+        print('(function(');
+      }
       // Emit required argument names
       // TODO Move lambda list production to a function for use by macro ll,
       // destructuring-bind, etc. Similar to emitBlock.
@@ -2057,6 +2075,17 @@ JACLPKG.intern('.')
   };
 JACLPKG.exportSymbol('.');
 
+JACLPKG.intern('AWAIT')
+  .setMacro()
+  .fvalue = (env, form, expr) => {
+    return Cons.listOf(
+      JACLPKG.intern("%JS"),
+      env.context === 'stmt' ? `await ~{}` : `(await ~{})`,
+      expr
+    );
+  };
+JACLPKG.exportSymbol('AWAIT');
+
 JACLPKG.intern('ENABLE-JS-SYNTAX').fvalue = () => {
   READTABLE
     .val()