When compiling top level stuff put it in a store record, don't const them. More cleaning

This commit is contained in:
Dustin Swan 2026-04-02 16:58:33 -06:00
parent a1caaf54e7
commit 13d582419e
No known key found for this signature in database
GPG key ID: 30D46587E2100467
4 changed files with 14 additions and 42 deletions

View file

@ -5,11 +5,10 @@ import { typecheck } from './typechecker';
let matchCounter = 0;
type CompileCtx = {
useStore: boolean;
bound: Set<string>;
topLevel: Set<string>;
};
const defaultCtx: CompileCtx = { useStore: true, bound: new Set(), topLevel: new Set() };
const defaultCtx: CompileCtx = { bound: new Set(), topLevel: new Set() };
export const definitions: Map<string, Definition> = new Map();
export const dependencies: Map<string, Set<string>> = new Map();
@ -30,7 +29,7 @@ export function compile(ast: AST, ctx: CompileCtx = defaultCtx): string {
if (ctx.bound.has(ast.name)) {
return sanitizeName(ast.name);
}
return sanitize(ast.name, ctx);
return sanitize(ast.name);
}
case 'lambda': {
@ -155,9 +154,8 @@ export function compile(ast: AST, ctx: CompileCtx = defaultCtx): string {
}
}
function sanitize(name: string, { useStore, topLevel }: CompileCtx): string {
if (!useStore && topLevel.has(name)) return sanitizeName(name);
return `store[${JSON.stringify(name)}]`
function sanitize(name: string): string {
return `store[${JSON.stringify(name)}]`;
}
function sanitizeName(name: string): string {
@ -289,37 +287,14 @@ export function compileAndRun(defs: Definition[], typeDefs: TypeDefinition[] = [
for (const def of defs) {
if (!def.body) continue;
const ctx: CompileCtx = { useStore: false, topLevel, bound: new Set() };
const compiled = `const ${sanitizeName(def.name)} = ${compile(def.body, ctx)};`;
const ctx: CompileCtx = { topLevel, bound: new Set() };
const compiled = `store[${JSON.stringify(def.name)}] = ${compile(def.body, ctx)};`;
compiledDefs.push(compiled);
try {
new Function('store', compiled);
} catch (e) {
console.error(`=== BROKEN: ${def.name} ===`);
console.error(compiled);
throw e;
}
}
const defsWithBody = defs.filter(d => d.body);
const lastName = defs[defs.length - 1].name;
const defNames = defsWithBody.map(d => sanitizeName(d.name)).join(', ');
const code = `${compiledDefs.join('\n')}
return { ${defNames}, __result: ${sanitizeName(lastName)} };`;
const code = compiledDefs.join('\n');
const fn = new Function('store', code);
const allDefs = fn(store);
// Populate store
for (const [name, value] of Object.entries(allDefs)) {
if (name !== '__result') {
store[name] = value;
}
}
return allDefs.__result;
fn(store);
}
export function freeVars(ast: AST, bound: Set<string> = new Set()): Set<string> {
@ -411,8 +386,7 @@ function patternVars(pattern: Pattern): string[] {
export function recompile(name: string, newAst: AST) {
const existing = definitions.get(name);
definitions.set(name, { kind: 'definition', name, body: newAst, annotation: existing?.annotation });;
// definitions.set(name, newAst);
definitions.set(name, { kind: 'definition', name, body: newAst, annotation: existing?.annotation, module: existing?.module });
const topLevel = new Set(definitions.keys());
const free = freeVars(newAst);