summaryrefslogtreecommitdiff
path: root/src/interpreter/SymbolTable.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/interpreter/SymbolTable.ts')
-rw-r--r--src/interpreter/SymbolTable.ts49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/interpreter/SymbolTable.ts b/src/interpreter/SymbolTable.ts
new file mode 100644
index 0000000..e2ff7e1
--- /dev/null
+++ b/src/interpreter/SymbolTable.ts
@@ -0,0 +1,49 @@
+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);
+ }
+}