export class UndefinedSymbolError extends Error {} export class SymbolTable { private knownSymbols: Set<string>; private parent: SymbolTable | null; private depth: number; constructor(parent: SymbolTable | null = null) { this.knownSymbols = new Set(); this.parent = parent; this.depth = parent ? parent.getDepth() + 1 : 0; } public getDepth() { return this.depth; } public add(name: string) { this.knownSymbols.add(name); } public get(name: string): number { if (this.knownSymbols.has(name)) { return 1; } if (this.parent) { return 1 + this.parent.get(name); } throw new UndefinedSymbolError(`Undefined variable: ${name}`); } public has(name: string): boolean { if (this.knownSymbols.has(name)) { return true; } if (this.parent) { return this.parent.has(name); } return false; } public createChild(): SymbolTable { return new SymbolTable(this); } }