mirror of
https://git.sfja.dk/Mikkel/slige.git
synced 2025-01-18 19:36:32 +00:00
76 lines
2.0 KiB
TypeScript
76 lines
2.0 KiB
TypeScript
export interface Locals {
|
|
reserveAmount(id: number): void;
|
|
allocSym(ident: string): void;
|
|
symId(ident: string): number;
|
|
|
|
currentLocalIdCounter(): number;
|
|
}
|
|
|
|
export class LocalsFnRoot implements Locals {
|
|
private localsAmount = 0;
|
|
private symLocalMap: { [key: string]: number } = {};
|
|
private localIdCounter: number;
|
|
|
|
constructor(private parent?: Locals) {
|
|
this.localIdCounter = parent?.currentLocalIdCounter() ?? 0;
|
|
}
|
|
|
|
public reserveAmount(amount: number): void {
|
|
this.localsAmount = Math.max(amount, this.localsAmount);
|
|
}
|
|
|
|
public allocSym(ident: string) {
|
|
this.symLocalMap[ident] = this.localIdCounter;
|
|
this.localIdCounter++;
|
|
this.reserveAmount(this.localIdCounter);
|
|
}
|
|
|
|
public symId(ident: string): number {
|
|
if (ident in this.symLocalMap) {
|
|
return this.symLocalMap[ident];
|
|
}
|
|
if (this.parent) {
|
|
return this.parent.symId(ident);
|
|
}
|
|
throw new Error(`undefined symbol '${ident}'`);
|
|
}
|
|
|
|
public stackReserved(): number {
|
|
return this.localsAmount;
|
|
}
|
|
|
|
public currentLocalIdCounter(): number {
|
|
return this.localIdCounter;
|
|
}
|
|
}
|
|
|
|
export class LocalLeaf implements Locals {
|
|
private symLocalMap: { [key: string]: number } = {};
|
|
private localIdCounter: number;
|
|
|
|
constructor(private parent: Locals) {
|
|
this.localIdCounter = parent.currentLocalIdCounter();
|
|
}
|
|
|
|
public reserveAmount(amount: number): void {
|
|
this.parent.reserveAmount(amount);
|
|
}
|
|
|
|
public allocSym(ident: string) {
|
|
this.symLocalMap[ident] = this.localIdCounter;
|
|
this.localIdCounter++;
|
|
this.reserveAmount(this.localIdCounter);
|
|
}
|
|
|
|
public symId(ident: string): number {
|
|
if (ident in this.symLocalMap) {
|
|
return this.symLocalMap[ident];
|
|
}
|
|
return this.parent.symId(ident);
|
|
}
|
|
|
|
public currentLocalIdCounter(): number {
|
|
return this.localIdCounter;
|
|
}
|
|
}
|