From 3babacd58dab6e9c00183c58b2f9a848e656353f Mon Sep 17 00:00:00 2001 From: sfja Date: Thu, 2 Jan 2025 17:54:46 +0100 Subject: [PATCH] elaborate syms --- compiler/ast.ts | 23 ++++++---- compiler/resolver.ts | 14 ++++-- compiler/resolver_syms.ts | 97 +++++++++++++++++++++++++++++++++------ 3 files changed, 107 insertions(+), 27 deletions(-) diff --git a/compiler/ast.ts b/compiler/ast.ts index 1a3901d..46f030d 100644 --- a/compiler/ast.ts +++ b/compiler/ast.ts @@ -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; diff --git a/compiler/resolver.ts b/compiler/resolver.ts index c811b28..b8afa4c 100644 --- a/compiler/resolver.ts +++ b/compiler/resolver.ts @@ -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, }); diff --git a/compiler/resolver_syms.ts b/compiler/resolver_syms.ts index 2ac04c9..6d7ee17 100644 --- a/compiler/resolver_syms.ts +++ b/compiler/resolver_syms.ts @@ -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(); + } }