50 lines
978 B
TypeScript
50 lines
978 B
TypeScript
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);
|
|
}
|
|
}
|