author | Alan Dipert
<alan@dipert.org> 2019-10-13 15:34:52 UTC |
committer | Alan Dipert
<alan@dipert.org> 2019-10-13 15:34:52 UTC |
parent | 6164cda10e8c1eb8a4ca672e44e25fe7b30f3915 |
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 + }; }] ]);