mirror of
https://git.sfja.dk/Mikkel/slige.git
synced 2025-01-18 10:56:30 +00:00
elaborate syms
This commit is contained in:
parent
01c80000ed
commit
3babacd58d
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
});
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user