slige/compiler/resolver_syms.ts

124 lines
2.8 KiB
TypeScript
Raw Normal View History

2024-12-29 05:39:22 +01:00
import type { Sym } from "./ast.ts";
2024-12-10 14:36:41 +01:00
export type SymMap = { [ident: string]: Sym };
2024-12-29 05:39:22 +01:00
type GetRes = { ok: true; sym: Sym } | { ok: false };
2024-12-10 14:36:41 +01:00
export interface Syms {
define(ident: string, sym: Sym): void;
definedLocally(ident: string): boolean;
2024-12-29 05:39:22 +01:00
get(ident: string): GetRes;
2024-12-10 14:36:41 +01:00
}
2024-12-29 05:39:22 +01:00
export class EntryModSyms implements Syms {
2024-12-10 14:36:41 +01:00
private syms: SymMap = {};
public constructor() {}
2024-12-10 14:36:41 +01:00
public define(ident: string, sym: Sym) {
if (sym.type === "let") {
this.define(ident, {
...sym,
type: "let_static",
});
return;
}
this.syms[ident] = sym;
}
public definedLocally(ident: string): boolean {
return ident in this.syms;
}
2024-12-29 05:39:22 +01:00
public get(ident: string): GetRes {
2024-12-10 14:36:41 +01:00
if (ident in this.syms) {
return { ok: true, sym: this.syms[ident] };
}
return { ok: false };
}
}
2024-12-29 05:39:22 +01:00
export class ModSyms implements Syms {
2024-12-10 14:36:41 +01:00
private syms: SymMap = {};
2024-12-29 05:39:22 +01:00
public constructor(private parent: Syms) {
this.syms["super"] = {
type: "mod",
ident: "super",
syms: this.parent,
};
}
2024-12-10 14:36:41 +01:00
public define(ident: string, sym: Sym) {
if (sym.type === "let") {
this.define(ident, {
...sym,
type: "let_static",
});
return;
}
this.syms[ident] = sym;
}
public definedLocally(ident: string): boolean {
return ident in this.syms;
}
2024-12-29 05:39:22 +01:00
public get(ident: string): GetRes {
2024-12-10 14:36:41 +01:00
if (ident in this.syms) {
return { ok: true, sym: this.syms[ident] };
}
2024-12-29 05:39:22 +01:00
return { ok: false };
2024-12-10 14:36:41 +01:00
}
}
export class FnSyms implements Syms {
private syms: SymMap = {};
public constructor(private parent: Syms) {}
public define(ident: string, sym: Sym) {
if (sym.type === "let") {
this.define(ident, {
...sym,
type: "closure",
inner: sym,
});
return;
}
this.syms[ident] = sym;
}
public definedLocally(ident: string): boolean {
return ident in this.syms;
}
2024-12-29 05:39:22 +01:00
public get(ident: string): GetRes {
2024-12-10 14:36:41 +01:00
if (ident in this.syms) {
return { ok: true, sym: this.syms[ident] };
}
return this.parent.get(ident);
}
}
export class LeafSyms implements Syms {
private syms: SymMap = {};
public constructor(private parent: Syms) {}
public define(ident: string, sym: Sym) {
this.syms[ident] = sym;
}
public definedLocally(ident: string): boolean {
return ident in this.syms;
}
2024-12-29 05:39:22 +01:00
public get(ident: string): GetRes {
2024-12-10 14:36:41 +01:00
if (ident in this.syms) {
return { ok: true, sym: this.syms[ident] };
}
return this.parent.get(ident);
}
}