author | Alan Dipert
<alan@dipert.org> 2020-08-05 04:29:15 UTC |
committer | Alan Dipert
<alan@dipert.org> 2020-08-05 04:29:15 UTC |
parent | 062a0aac6120777ffe9ff863e1d7a330313a12f7 |
jacl.js | +15 | -8 |
diff --git a/jacl.js b/jacl.js index c9577e6..afe4d32 100644 --- a/jacl.js +++ b/jacl.js @@ -1579,6 +1579,7 @@ const parseCall = (env, parent, form) => { } else if (env.hasLocalFunction(func)) { node.f = makeNode('flocal', { env: env.withContext('expr'), + envId: env.functionEnvId(func), parent: node, form: func, children: [] @@ -1644,7 +1645,7 @@ class Env { static init(env) { // sym => envId env.locals = new Map(); - env.localFunctions = new Set(); + env.localFunctions = new Map(); // sym => tagbodyName env.tags = new Map(); env.context = 'expr'; @@ -1654,7 +1655,7 @@ class Env { clone() { const newEnv = new Env(false); newEnv.locals = new Map(this.locals); - newEnv.localFunctions = new Set(this.localFunctions); + newEnv.localFunctions = new Map(this.localFunctions); newEnv.tags = new Map(this.tags); newEnv.context = this.context; newEnv.counter = this.counter; @@ -1668,9 +1669,12 @@ class Env { ]); return newEnv; } - withLocalFunctions(syms) { + withLocalFunctions(syms, envId = this.counter()) { const newEnv = this.clone(); - newEnv.localFunctions = new Set([...this.localFunctions, ...syms]); + newEnv.localFunctions = new Map([ + ...this.localFunctions, + ...syms.map(sym => [sym, envId]) + ]); return newEnv; } newId() { @@ -1690,6 +1694,9 @@ class Env { hasLocal(sym) { return this.locals.has(sym); } + functionEnvId(sym) { + return this.locals.get(sym); + } hasLocalFunction(sym) { return this.localFunctions.has(sym); } @@ -1703,7 +1710,7 @@ class Env { } } -const emptyEnv = new Env(); +const emptyEnv = () => new Env(true); const analyze = (env, parent, form) => { if (form instanceof LispSymbol) { @@ -1870,7 +1877,7 @@ const emitNode = (print, node) => { break; case 'flocal': if (context === 'return') print('return '); - print(mungeSym(form, 'flocal')); + print(mungeSym(form, `flocal_${node.envId}`)); if (context !== 'expr') print(';\n'); break; case 'global': @@ -2363,7 +2370,7 @@ const startRepl = async () => { try { for await(const obj of replReader) { console.log("read", obj); - const node = optimize(analyze(emptyEnv, null, obj)); + const node = optimize(analyze(emptyEnv(), null, obj)); // console.log(node) const sb = new StringBuffer(); emitNode(sb.append.bind(sb), node); @@ -2386,7 +2393,7 @@ const fetchLoad = async (src) => { rdr = new Reader(ss); for await(const obj of rdr) { if (obj === EOF) break; - const node = optimize(analyze(emptyEnv.withContext('return'), null, obj)), + const node = optimize(analyze(emptyEnv().withContext('return'), null, obj)), sb = new StringBuffer(); emitNode(sb.append.bind(sb), node); await (new Function(sb.toString())());