slige/compiler/lowerer_locals.ts

76 lines
2.0 KiB
TypeScript
Raw Normal View History

2024-12-10 13:36:41 +00:00
export interface Locals {
2024-12-11 02:11:00 +00:00
reserveAmount(id: number): void;
2024-12-10 13:36:41 +00:00
allocSym(ident: string): void;
symId(ident: string): number;
2024-12-11 02:11:00 +00:00
currentLocalIdCounter(): number;
2024-12-10 13:36:41 +00:00
}
export class LocalsFnRoot implements Locals {
private localsAmount = 0;
private symLocalMap: { [key: string]: number } = {};
2024-12-11 02:11:00 +00:00
private localIdCounter: number;
2024-12-10 13:36:41 +00:00
constructor(private parent?: Locals) {
2024-12-11 02:11:00 +00:00
this.localIdCounter = parent?.currentLocalIdCounter() ?? 0;
2024-12-10 13:36:41 +00:00
}
2024-12-11 02:11:00 +00:00
public reserveAmount(amount: number): void {
this.localsAmount = Math.max(amount, this.localsAmount);
2024-12-10 13:36:41 +00:00
}
public allocSym(ident: string) {
this.symLocalMap[ident] = this.localIdCounter;
this.localIdCounter++;
2024-12-11 02:11:00 +00:00
this.reserveAmount(this.localIdCounter);
2024-12-10 13:36:41 +00:00
}
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}'`);
}
2024-12-11 02:11:00 +00:00
public stackReserved(): number {
return this.localsAmount;
}
public currentLocalIdCounter(): number {
return this.localIdCounter;
}
2024-12-10 13:36:41 +00:00
}
export class LocalLeaf implements Locals {
private symLocalMap: { [key: string]: number } = {};
2024-12-11 02:11:00 +00:00
private localIdCounter: number;
2024-12-10 13:36:41 +00:00
constructor(private parent: Locals) {
2024-12-11 02:11:00 +00:00
this.localIdCounter = parent.currentLocalIdCounter();
2024-12-10 13:36:41 +00:00
}
2024-12-11 02:11:00 +00:00
public reserveAmount(amount: number): void {
this.parent.reserveAmount(amount);
2024-12-10 13:36:41 +00:00
}
public allocSym(ident: string) {
this.symLocalMap[ident] = this.localIdCounter;
this.localIdCounter++;
2024-12-11 02:11:00 +00:00
this.reserveAmount(this.localIdCounter);
2024-12-10 13:36:41 +00:00
}
public symId(ident: string): number {
if (ident in this.symLocalMap) {
return this.symLocalMap[ident];
}
return this.parent.symId(ident);
}
2024-12-11 02:11:00 +00:00
public currentLocalIdCounter(): number {
return this.localIdCounter;
}
2024-12-10 13:36:41 +00:00
}