92 lines
2.0 KiB
TypeScript
92 lines
2.0 KiB
TypeScript
import { IdentId, idKey, Key } from "../ctx.ts";
|
|
|
|
type Ident = Key<IdentId>;
|
|
|
|
export class Ribs {
|
|
private tyRibs: Rib[] = [];
|
|
private valRibs: Rib[] = [];
|
|
|
|
private constructor() {}
|
|
|
|
public static withRootMod(): Ribs {
|
|
const ribs = new Ribs();
|
|
ribs.pushRib({ tag: "mod", mod: { items: new Map() } });
|
|
return ribs;
|
|
}
|
|
|
|
public pushRib(kind: RibKind) {
|
|
this.tyRibs.push({ bindings: new Map(), kind });
|
|
this.valRibs.push({ bindings: new Map(), kind });
|
|
}
|
|
|
|
public hasTy(ident: IdentId): boolean {
|
|
return this.tyRibs.at(-1)!.bindings.has(idKey(ident));
|
|
}
|
|
|
|
public defTy(ident: IdentId, res: Res) {
|
|
this.tyRibs.at(-1)!.bindings.set(idKey(ident), res);
|
|
}
|
|
|
|
public hasVal(ident: IdentId): boolean {
|
|
return this.valRibs.at(-1)!.bindings.has(idKey(ident));
|
|
}
|
|
|
|
public defVal(ident: IdentId, res: Res) {
|
|
this.valRibs.at(-1)!.bindings.set(idKey(ident), res);
|
|
}
|
|
|
|
public checkpoint(): number {
|
|
return this.tyRibs.length;
|
|
}
|
|
|
|
public returnToCheckpoint(checkpoint: number) {
|
|
this.tyRibs = this.tyRibs.slice(checkpoint, this.tyRibs.length);
|
|
this.valRibs = this.valRibs.slice(checkpoint, this.valRibs.length);
|
|
}
|
|
|
|
public nearestMod(): Mod {
|
|
return [
|
|
this.tyRibs
|
|
.toReversed()
|
|
.find((r) => r.kind.tag === "mod")!,
|
|
]
|
|
.map((r) => (r.kind.tag === "mod" && r.kind.mod) as Mod)[0];
|
|
}
|
|
}
|
|
|
|
export type Mod = {
|
|
parent?: Mod;
|
|
items: Map<Ident, Res>;
|
|
};
|
|
|
|
export type Rib = {
|
|
bindings: Map<Ident, Res>;
|
|
kind: RibKind;
|
|
};
|
|
|
|
export type RibKind =
|
|
| { tag: "normal" }
|
|
| { tag: "fn" }
|
|
| { tag: "item" }
|
|
| { tag: "mod"; mod: Mod };
|
|
|
|
export type Res =
|
|
| { tag: "def"; def: Def }
|
|
| { tag: "local"; id: number };
|
|
|
|
export type Def = {
|
|
type: DefType;
|
|
id: number;
|
|
};
|
|
|
|
export type DefType =
|
|
| "mod"
|
|
| "enum"
|
|
| "struct"
|
|
| "variant"
|
|
| "ty_alias"
|
|
| "ty_param"
|
|
| "fn"
|
|
| "use"
|
|
| "field";
|