git » jacl.git » commit e4fd8e7

analyze %GO

author Alan Dipert
2019-10-13 15:34:52 UTC
committer Alan Dipert
2019-10-13 15:34:52 UTC
parent 6164cda10e8c1eb8a4ca672e44e25fe7b30f3915

analyze %GO

jacl.js +15 -4

diff --git a/jacl.js b/jacl.js
index f4a2b7b..214bf8c 100644
--- a/jacl.js
+++ b/jacl.js
@@ -713,6 +713,10 @@ const analyzeBlock = (env, forms) => {
 };
 
 const stringy = x => x instanceof String || typeof x === 'string' || x instanceof LispString;
+const isTag = x => x instanceof LispSymbol
+  || typeof x === 'number'
+  || x instanceof Number;
+const asTagName = x => x instanceof LispSymbol ? x.name : x.valueOf();
 const analyzeSpecials = new Map([
   [JACLPKG.intern("%DOT"), (env, form) => {
     const [, target, field] = form;
@@ -769,10 +773,6 @@ const analyzeSpecials = new Map([
   }],
   [JACLPKG.intern("%TAGBODY"), (env, form) => {
     const [, ...tagsStmts] = form;
-    const isTag = x => x instanceof LispSymbol 
-      || typeof x === 'number'
-      || x instanceof Number;
-    const asTagName = x => x instanceof LispSymbol ? x.name : x.valueOf();
     // Map from tag names (string or int) to arrays of statements
     // Any statements that appear before a tag are stored with the null tag
     // Tags/statements are processed in multiple passes because any parent tag
@@ -808,6 +808,17 @@ const analyzeSpecials = new Map([
     };
   }],
   [JACLPKG.intern("%GO"), (env, form) => {
+    const [, tag] = form;
+    if (!isTag(tag)) throw new Error(`Invalid GO tag`);
+    const tagName = asTagName(tag);
+    if (!env.tagbodyTags.has(tagName))
+      throw new Error(`Non-existent GO tag: ${tagName}`);
+    return {
+      op: "go",
+      env: env,
+      form: form,
+      tagName: tagName
+    };
   }]
 ]);