elaborate syms

This commit is contained in:
sfja 2025-01-02 17:54:46 +01:00
parent 6351bc1e71
commit 8367399a2c
3 changed files with 107 additions and 27 deletions

View File

@ -21,20 +21,23 @@ export type StmtKind =
| { type: "mod"; ident: string; mod: Mod }
| { type: "break"; expr?: Expr }
| { type: "return"; expr?: Expr }
| {
type: "fn";
ident: string;
genericParams?: GenericParam[];
params: Param[];
returnType?: EType;
body: Expr;
vtype?: VType;
}
| FnStmtKind
| { type: "let"; param: Param; value: Expr }
| { type: "type_alias"; param: Param }
| { type: "assign"; assignType: AssignType; subject: Expr; value: Expr }
| { type: "expr"; expr: Expr };
export type FnStmtKind = {
type: "fn";
ident: string;
genericParams?: GenericParam[];
params: Param[];
returnType?: EType;
body: Expr;
sym?: Sym;
vtype?: VType;
};
export type AssignType = "=" | "+=" | "-=";
export type StmtDetails = {
@ -116,11 +119,13 @@ export type Param = {
ident: string;
etype?: EType;
pos: Pos;
sym?: Sym;
vtype?: VType;
};
export type Sym = {
ident: string;
fullPath: string;
pos?: Pos;
} & SymKind;

View File

@ -23,7 +23,7 @@ export class Resolver implements AstVisitor<[Syms]> {
}
public resolve(stmts: Stmt[]): VisitRes {
const syms = new EntryModSyms();
const syms = new EntryModSyms("root");
this.scout(stmts, syms);
visitStmts(stmts, this, syms);
return "stop";
@ -37,9 +37,10 @@ export class Resolver implements AstVisitor<[Syms]> {
return;
}
const ident = stmt.kind.ident;
syms.define(ident, {
stmt.kind.sym = syms.define(ident, {
ident: stmt.kind.ident,
type: "fn",
fullPath: `${syms.pathString()}::${ident}`,
pos: stmt.pos,
stmt,
});
@ -52,6 +53,7 @@ export class Resolver implements AstVisitor<[Syms]> {
syms.define(ident, {
ident,
type: "type_alias",
fullPath: `${syms.pathString()}::${ident}`,
pos: stmt.kind.param.pos,
stmt,
param: stmt.kind.param,
@ -64,7 +66,7 @@ export class Resolver implements AstVisitor<[Syms]> {
if (stmt.kind.type !== "mod") {
throw new Error("expected let statement");
}
const modSyms = new ModSyms(syms);
const modSyms = new ModSyms(syms, stmt.kind.ident);
const { mod, ident } = stmt.kind;
this.scout(mod.ast, modSyms);
visitStmts(mod.ast, this, modSyms);
@ -76,6 +78,7 @@ export class Resolver implements AstVisitor<[Syms]> {
syms.define(ident, {
type: "mod",
ident,
fullPath: `${syms.pathString()}::${ident}`,
pos: stmt.pos,
syms: modSyms,
});
@ -93,9 +96,10 @@ export class Resolver implements AstVisitor<[Syms]> {
this.reportAlreadyDefined(ident, stmt.pos, syms);
return;
}
syms.define(ident, {
stmt.kind.param.sym = syms.define(ident, {
ident,
type: "let",
fullPath: ident,
pos: stmt.kind.param.pos,
stmt,
param: stmt.kind.param,
@ -123,6 +127,7 @@ export class Resolver implements AstVisitor<[Syms]> {
fnScopeSyms.define(param.ident, {
ident: param.ident,
type: "generic",
fullPath: param.ident,
pos: param.pos,
stmt,
genericParam: param,
@ -137,6 +142,7 @@ export class Resolver implements AstVisitor<[Syms]> {
fnScopeSyms.define(param.ident, {
ident: param.ident,
type: "fn_param",
fullPath: param.ident,
pos: param.pos,
param,
});

View File

@ -5,25 +5,28 @@ export type SymMap = { [ident: string]: Sym };
type GetRes = { ok: true; sym: Sym } | { ok: false };
export interface Syms {
define(ident: string, sym: Sym): void;
define(ident: string, sym: Sym): Sym;
definedLocally(ident: string): boolean;
get(ident: string): GetRes;
getPub(ident: string): GetRes;
rootMod(): Sym;
pathString(): string;
}
export class EntryModSyms implements Syms {
private syms: SymMap = {};
public constructor() {}
public constructor(private modName: string) {}
public define(ident: string, sym: Sym) {
public define(ident: string, sym: Sym): Sym {
if (sym.type === "let") {
this.define(ident, {
return this.define(ident, {
...sym,
type: "let_static",
});
return;
}
this.syms[ident] = sym;
return sym;
}
public definedLocally(ident: string): boolean {
@ -36,28 +39,48 @@ export class EntryModSyms implements Syms {
}
return { ok: false };
}
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;
}
}
export class ModSyms implements Syms {
private syms: SymMap = {};
public constructor(private parent: Syms) {
public constructor(private parent: Syms, private modName: string) {
this.syms["super"] = {
type: "mod",
ident: "super",
fullPath: this.pathString(),
syms: this.parent,
};
}
public define(ident: string, sym: Sym) {
public define(ident: string, sym: Sym): Sym {
if (sym.type === "let") {
this.define(ident, {
return this.define(ident, {
...sym,
type: "let_static",
});
return;
}
this.syms[ident] = sym;
return this.syms[ident] = sym;
}
public definedLocally(ident: string): boolean {
@ -70,6 +93,21 @@ export class ModSyms implements Syms {
}
return { ok: false };
}
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}`;
}
}
export class FnSyms implements Syms {
@ -77,16 +115,16 @@ export class FnSyms implements Syms {
public constructor(private parent: Syms) {}
public define(ident: string, sym: Sym) {
public define(ident: string, sym: Sym): Sym {
if (sym.type === "let") {
this.define(ident, {
return this.define(ident, {
...sym,
type: "closure",
inner: sym,
});
return;
}
this.syms[ident] = sym;
return sym;
}
public definedLocally(ident: string): boolean {
@ -99,6 +137,21 @@ export class FnSyms implements Syms {
}
return this.parent.get(ident);
}
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();
}
}
export class LeafSyms implements Syms {
@ -106,8 +159,9 @@ export class LeafSyms implements Syms {
public constructor(private parent: Syms) {}
public define(ident: string, sym: Sym) {
public define(ident: string, sym: Sym): Sym {
this.syms[ident] = sym;
return sym;
}
public definedLocally(ident: string): boolean {
@ -120,4 +174,19 @@ export class LeafSyms implements Syms {
}
return this.parent.get(ident);
}
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();
}
}