slige/compiler/resolver_syms.ts

193 lines
4.4 KiB
TypeScript
Raw Permalink 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 {
2025-01-02 17:54:46 +01:00
define(ident: string, sym: Sym): Sym;
2024-12-10 14:36:41 +01:00
definedLocally(ident: string): boolean;
2024-12-29 05:39:22 +01:00
get(ident: string): GetRes;
2025-01-02 17:54:46 +01:00
getPub(ident: string): GetRes;
rootMod(): Sym;
pathString(): string;
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 = {};
2025-01-02 17:54:46 +01:00
public constructor(private modName: string) {}
2024-12-10 14:36:41 +01:00
2025-01-02 17:54:46 +01:00
public define(ident: string, sym: Sym): Sym {
2024-12-10 14:36:41 +01:00
if (sym.type === "let") {
2025-01-02 17:54:46 +01:00
return this.define(ident, {
2024-12-10 14:36:41 +01:00
...sym,
type: "let_static",
});
}
this.syms[ident] = sym;
2025-01-02 17:54:46 +01:00
return sym;
2024-12-10 14:36:41 +01:00
}
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 };
}
2025-01-02 17:54:46 +01:00
public getPub(ident: string): GetRes {
if (ident in this.syms) {
return { ok: true, sym: this.syms[ident] };
}
return { ok: false };
}
public rootMod(): Sym {
return {
type: "mod",
ident: this.modName,
fullPath: this.modName,
syms: this,
};
}
public pathString(): string {
return this.modName;
}
2024-12-10 14:36:41 +01:00
}
2024-12-29 05:39:22 +01:00
export class ModSyms implements Syms {
2024-12-10 14:36:41 +01:00
private syms: SymMap = {};
2025-01-02 17:54:46 +01:00
public constructor(private parent: Syms, private modName: string) {
2024-12-29 05:39:22 +01:00
this.syms["super"] = {
type: "mod",
ident: "super",
2025-01-02 17:54:46 +01:00
fullPath: this.pathString(),
2024-12-29 05:39:22 +01:00
syms: this.parent,
};
}
2024-12-10 14:36:41 +01:00
2025-01-02 17:54:46 +01:00
public define(ident: string, sym: Sym): Sym {
2024-12-10 14:36:41 +01:00
if (sym.type === "let") {
2025-01-02 17:54:46 +01:00
return this.define(ident, {
2024-12-10 14:36:41 +01:00
...sym,
type: "let_static",
});
}
2025-01-02 17:54:46 +01:00
return this.syms[ident] = sym;
2024-12-10 14:36:41 +01:00
}
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
}
2025-01-02 17:54:46 +01:00
public getPub(ident: string): GetRes {
if (ident in this.syms) {
return { ok: true, sym: this.syms[ident] };
}
return { ok: false };
}
public rootMod(): Sym {
return this.parent.rootMod();
}
public pathString(): string {
return `${this.parent.pathString()}::${this.modName}`;
}
2024-12-10 14:36:41 +01:00
}
export class FnSyms implements Syms {
private syms: SymMap = {};
public constructor(private parent: Syms) {}
2025-01-02 17:54:46 +01:00
public define(ident: string, sym: Sym): Sym {
2024-12-10 14:36:41 +01:00
if (sym.type === "let") {
2025-01-02 17:54:46 +01:00
return this.define(ident, {
2024-12-10 14:36:41 +01:00
...sym,
type: "closure",
inner: sym,
});
}
this.syms[ident] = sym;
2025-01-02 17:54:46 +01:00
return sym;
2024-12-10 14:36:41 +01:00
}
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);
}
2025-01-02 17:54:46 +01:00
public getPub(ident: string): GetRes {
if (ident in this.syms) {
return { ok: true, sym: this.syms[ident] };
}
return { ok: false };
}
public rootMod(): Sym {
return this.parent.rootMod();
}
public pathString(): string {
return this.parent.pathString();
}
2024-12-10 14:36:41 +01:00
}
export class LeafSyms implements Syms {
private syms: SymMap = {};
public constructor(private parent: Syms) {}
2025-01-02 17:54:46 +01:00
public define(ident: string, sym: Sym): Sym {
2024-12-10 14:36:41 +01:00
this.syms[ident] = sym;
2025-01-02 17:54:46 +01:00
return sym;
2024-12-10 14:36:41 +01:00
}
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);
}
2025-01-02 17:54:46 +01:00
public getPub(ident: string): GetRes {
if (ident in this.syms) {
return { ok: true, sym: this.syms[ident] };
}
return { ok: false };
}
public rootMod(): Sym {
return this.parent.rootMod();
}
public pathString(): string {
return this.parent.pathString();
}
2024-12-10 14:36:41 +01:00
}