summaryrefslogtreecommitdiff
path: root/src/interpreter/SymbolTable.ts
blob: e2ff7e1c7ddcff4028678b8dd039bf5e8ceaf6d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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);
  }
}