When compiling top level stuff put it in a store record, don't const them. More cleaning
This commit is contained in:
parent
a1caaf54e7
commit
13d582419e
4 changed files with 14 additions and 42 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -25,9 +25,6 @@ try {
|
|||
const parser = new Parser(tokens, cgCode);
|
||||
const { definitions: defs, typeDefinitions: typeDefs, classDefinitions: classDefs, instanceDeclarations: instances } = parser.parse();
|
||||
|
||||
// TODO remove once we're booting from store, files are backup
|
||||
if (!store.paletteHistory) store.paletteHistory = [];
|
||||
|
||||
compileAndRun(defs, typeDefs, classDefs, instances);
|
||||
|
||||
runAppCompiled(canvas, store);
|
||||
|
|
|
|||
|
|
@ -652,8 +652,6 @@ export class Parser {
|
|||
kind === 'open-paren' || kind === 'open-brace';
|
||||
}
|
||||
|
||||
private parsedConstraints: { className: string, typeVar: string }[] = [];
|
||||
|
||||
private parseType(): TypeAST {
|
||||
// Check for constraints: Num a, Eq b :: <type>
|
||||
const left = this.parseTypeApply();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import { prettyPrint } from './ast'
|
|||
import type { AST, Definition } from './ast'
|
||||
import { measure } from './ui';
|
||||
|
||||
const STORAGE_KEY = 'cg-definitions';
|
||||
const CHANGELOG_KEY = 'cg-changelog';
|
||||
|
||||
export const store: Record<string, any> = {};
|
||||
|
|
@ -153,7 +152,7 @@ export const _rt = {
|
|||
}
|
||||
|
||||
// Save standalone defs
|
||||
for (const def of definitions) {
|
||||
for (const def of definitions.values()) {
|
||||
const content = prettyPrint(def) + '\n';
|
||||
fetch('/api/save', {
|
||||
method: 'POST',
|
||||
|
|
@ -264,6 +263,9 @@ export const _rt = {
|
|||
|
||||
if (defs.length > 0) {
|
||||
const def = defs[0];
|
||||
const existing = definitions.get(def.name);
|
||||
if (existing?.module) def.module = existing.module;
|
||||
if (existing?.annotation && !def.annotation) def.annotation = existing.annotation;
|
||||
recompile(def.name, def.body!);
|
||||
definitions.set(def.name, def);
|
||||
const source = prettyPrint(def);
|
||||
|
|
@ -383,6 +385,7 @@ export function syncToAst(name: string) {
|
|||
name,
|
||||
body: valueToAst(store[name]),
|
||||
annotation: existing?.annotation,
|
||||
module: existing?.module,
|
||||
};
|
||||
definitions.set(name, newDef); // valueToAst(store[name]));
|
||||
// const source = prettyPrint({ kind: 'definition', name, body: definitions.get(name)! });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue