author | Alan Dipert
<alan@dipert.org> 2019-11-10 14:05:44 UTC |
committer | Alan Dipert
<alan@dipert.org> 2019-11-10 14:05:44 UTC |
parent | 2d12963505dba09d76533c08e8255e12aa8de63b |
jacl.js | +16 | -5 |
diff --git a/jacl.js b/jacl.js index 2a84251..c058183 100644 --- a/jacl.js +++ b/jacl.js @@ -1179,26 +1179,27 @@ const analyzeSpecials = new Map([ // after the tag // First pass: gather tags and statements, don't analyze - const newEnv = env.withContext('statement'); const tags = new Map(); let currentTag = null, currentStmts = []; for (const x of tagsStmts) { if (isTag(x)) { tags.set(currentTag, currentStmts); - if (currentTag !== null) newEnv.tagbodyTags.add(currentTag); currentTag = asTagName(x); currentStmts = []; } else { currentStmts.push(x); } } - if (currentTag !== null) newEnv.tagbodyTags.add(currentTag); tags.set(currentTag, currentStmts); const node = makeNode('tagbody', { env: env, parent: parent, form: form }); + const childEnv = env + .withContext('statement') + .withTags(Array.from(tags.keys()).filter(x => x !== null)); + // Second pass: analyze statements - const ana = analyze.bind(null, newEnv, node); + const ana = analyze.bind(null, childEnv, node); for (const [tag, stmts] of tags) tags.set(tag, stmts.map(ana)); node.prelude = tags.get(null); tags.delete(null); @@ -1210,7 +1211,7 @@ const analyzeSpecials = new Map([ const [, tag] = form; if (!isTag(tag)) throw new Error(`Invalid GO tag`); const tagName = asTagName(tag); - if (!env.tagbodyTags.has(tagName)) + if (!env.hasTag(tagName)) throw new Error(`Non-existent GO tag: ${tagName}`); return makeNode('go', { env: env, @@ -1296,12 +1297,14 @@ class Env { } static init(env) { env.locals = new Set(); + env.tags = new Set(); env.context = 'sval'; return env; } clone() { const newEnv = new Env(false); newEnv.locals = new Set(this.locals); + newEnv.tags = new Set(this.tags); newEnv.context = this.context; return newEnv; } @@ -1310,9 +1313,17 @@ class Env { newEnv.locals = new Set([...this.locals, ...syms]); return newEnv; } + withTags(syms) { + const newEnv = this.clone(); + newEnv.tags = new Set([...this.tags, ...syms]); + return newEnv; + } hasLocal(sym) { return this.locals.has(sym); } + hasTag(sym) { + return this.tags.has(sym); + } withContext(context) { const newEnv = this.clone(); newEnv.context = context;