mirror of
https://git.sfja.dk/Mikkel/slige.git
synced 2025-01-18 10:36:31 +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: "mod"; ident: string; mod: Mod }
|
||||||
| { type: "break"; expr?: Expr }
|
| { type: "break"; expr?: Expr }
|
||||||
| { type: "return"; expr?: Expr }
|
| { type: "return"; expr?: Expr }
|
||||||
| {
|
| FnStmtKind
|
||||||
type: "fn";
|
|
||||||
ident: string;
|
|
||||||
genericParams?: GenericParam[];
|
|
||||||
params: Param[];
|
|
||||||
returnType?: EType;
|
|
||||||
body: Expr;
|
|
||||||
vtype?: VType;
|
|
||||||
}
|
|
||||||
| { type: "let"; param: Param; value: Expr }
|
| { type: "let"; param: Param; value: Expr }
|
||||||
| { type: "type_alias"; param: Param }
|
| { type: "type_alias"; param: Param }
|
||||||
| { type: "assign"; assignType: AssignType; subject: Expr; value: Expr }
|
| { type: "assign"; assignType: AssignType; subject: Expr; value: Expr }
|
||||||
| { type: "expr"; expr: 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 AssignType = "=" | "+=" | "-=";
|
||||||
|
|
||||||
export type StmtDetails = {
|
export type StmtDetails = {
|
||||||
@ -116,11 +119,13 @@ export type Param = {
|
|||||||
ident: string;
|
ident: string;
|
||||||
etype?: EType;
|
etype?: EType;
|
||||||
pos: Pos;
|
pos: Pos;
|
||||||
|
sym?: Sym;
|
||||||
vtype?: VType;
|
vtype?: VType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Sym = {
|
export type Sym = {
|
||||||
ident: string;
|
ident: string;
|
||||||
|
fullPath: string;
|
||||||
pos?: Pos;
|
pos?: Pos;
|
||||||
} & SymKind;
|
} & SymKind;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ export class Resolver implements AstVisitor<[Syms]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public resolve(stmts: Stmt[]): VisitRes {
|
public resolve(stmts: Stmt[]): VisitRes {
|
||||||
const syms = new EntryModSyms();
|
const syms = new EntryModSyms("root");
|
||||||
this.scout(stmts, syms);
|
this.scout(stmts, syms);
|
||||||
visitStmts(stmts, this, syms);
|
visitStmts(stmts, this, syms);
|
||||||
return "stop";
|
return "stop";
|
||||||
@ -37,9 +37,10 @@ export class Resolver implements AstVisitor<[Syms]> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const ident = stmt.kind.ident;
|
const ident = stmt.kind.ident;
|
||||||
syms.define(ident, {
|
stmt.kind.sym = syms.define(ident, {
|
||||||
ident: stmt.kind.ident,
|
ident: stmt.kind.ident,
|
||||||
type: "fn",
|
type: "fn",
|
||||||
|
fullPath: `${syms.pathString()}::${ident}`,
|
||||||
pos: stmt.pos,
|
pos: stmt.pos,
|
||||||
stmt,
|
stmt,
|
||||||
});
|
});
|
||||||
@ -52,6 +53,7 @@ export class Resolver implements AstVisitor<[Syms]> {
|
|||||||
syms.define(ident, {
|
syms.define(ident, {
|
||||||
ident,
|
ident,
|
||||||
type: "type_alias",
|
type: "type_alias",
|
||||||
|
fullPath: `${syms.pathString()}::${ident}`,
|
||||||
pos: stmt.kind.param.pos,
|
pos: stmt.kind.param.pos,
|
||||||
stmt,
|
stmt,
|
||||||
param: stmt.kind.param,
|
param: stmt.kind.param,
|
||||||
@ -64,7 +66,7 @@ export class Resolver implements AstVisitor<[Syms]> {
|
|||||||
if (stmt.kind.type !== "mod") {
|
if (stmt.kind.type !== "mod") {
|
||||||
throw new Error("expected let statement");
|
throw new Error("expected let statement");
|
||||||
}
|
}
|
||||||
const modSyms = new ModSyms(syms);
|
const modSyms = new ModSyms(syms, stmt.kind.ident);
|
||||||
const { mod, ident } = stmt.kind;
|
const { mod, ident } = stmt.kind;
|
||||||
this.scout(mod.ast, modSyms);
|
this.scout(mod.ast, modSyms);
|
||||||
visitStmts(mod.ast, this, modSyms);
|
visitStmts(mod.ast, this, modSyms);
|
||||||
@ -76,6 +78,7 @@ export class Resolver implements AstVisitor<[Syms]> {
|
|||||||
syms.define(ident, {
|
syms.define(ident, {
|
||||||
type: "mod",
|
type: "mod",
|
||||||
ident,
|
ident,
|
||||||
|
fullPath: `${syms.pathString()}::${ident}`,
|
||||||
pos: stmt.pos,
|
pos: stmt.pos,
|
||||||
syms: modSyms,
|
syms: modSyms,
|
||||||
});
|
});
|
||||||
@ -93,9 +96,10 @@ export class Resolver implements AstVisitor<[Syms]> {
|
|||||||
this.reportAlreadyDefined(ident, stmt.pos, syms);
|
this.reportAlreadyDefined(ident, stmt.pos, syms);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
syms.define(ident, {
|
stmt.kind.param.sym = syms.define(ident, {
|
||||||
ident,
|
ident,
|
||||||
type: "let",
|
type: "let",
|
||||||
|
fullPath: ident,
|
||||||
pos: stmt.kind.param.pos,
|
pos: stmt.kind.param.pos,
|
||||||
stmt,
|
stmt,
|
||||||
param: stmt.kind.param,
|
param: stmt.kind.param,
|
||||||
@ -123,6 +127,7 @@ export class Resolver implements AstVisitor<[Syms]> {
|
|||||||
fnScopeSyms.define(param.ident, {
|
fnScopeSyms.define(param.ident, {
|
||||||
ident: param.ident,
|
ident: param.ident,
|
||||||
type: "generic",
|
type: "generic",
|
||||||
|
fullPath: param.ident,
|
||||||
pos: param.pos,
|
pos: param.pos,
|
||||||
stmt,
|
stmt,
|
||||||
genericParam: param,
|
genericParam: param,
|
||||||
@ -137,6 +142,7 @@ export class Resolver implements AstVisitor<[Syms]> {
|
|||||||
fnScopeSyms.define(param.ident, {
|
fnScopeSyms.define(param.ident, {
|
||||||
ident: param.ident,
|
ident: param.ident,
|
||||||
type: "fn_param",
|
type: "fn_param",
|
||||||
|
fullPath: param.ident,
|
||||||
pos: param.pos,
|
pos: param.pos,
|
||||||
param,
|
param,
|
||||||
});
|
});
|
||||||
|
@ -5,25 +5,28 @@ export type SymMap = { [ident: string]: Sym };
|
|||||||
type GetRes = { ok: true; sym: Sym } | { ok: false };
|
type GetRes = { ok: true; sym: Sym } | { ok: false };
|
||||||
|
|
||||||
export interface Syms {
|
export interface Syms {
|
||||||
define(ident: string, sym: Sym): void;
|
define(ident: string, sym: Sym): Sym;
|
||||||
definedLocally(ident: string): boolean;
|
definedLocally(ident: string): boolean;
|
||||||
get(ident: string): GetRes;
|
get(ident: string): GetRes;
|
||||||
|
getPub(ident: string): GetRes;
|
||||||
|
rootMod(): Sym;
|
||||||
|
pathString(): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EntryModSyms implements Syms {
|
export class EntryModSyms implements Syms {
|
||||||
private syms: SymMap = {};
|
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") {
|
if (sym.type === "let") {
|
||||||
this.define(ident, {
|
return this.define(ident, {
|
||||||
...sym,
|
...sym,
|
||||||
type: "let_static",
|
type: "let_static",
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
this.syms[ident] = sym;
|
this.syms[ident] = sym;
|
||||||
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
public definedLocally(ident: string): boolean {
|
public definedLocally(ident: string): boolean {
|
||||||
@ -36,28 +39,48 @@ export class EntryModSyms implements Syms {
|
|||||||
}
|
}
|
||||||
return { ok: false };
|
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 {
|
export class ModSyms implements Syms {
|
||||||
private syms: SymMap = {};
|
private syms: SymMap = {};
|
||||||
|
|
||||||
public constructor(private parent: Syms) {
|
public constructor(private parent: Syms, private modName: string) {
|
||||||
this.syms["super"] = {
|
this.syms["super"] = {
|
||||||
type: "mod",
|
type: "mod",
|
||||||
ident: "super",
|
ident: "super",
|
||||||
|
fullPath: this.pathString(),
|
||||||
syms: this.parent,
|
syms: this.parent,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public define(ident: string, sym: Sym) {
|
public define(ident: string, sym: Sym): Sym {
|
||||||
if (sym.type === "let") {
|
if (sym.type === "let") {
|
||||||
this.define(ident, {
|
return this.define(ident, {
|
||||||
...sym,
|
...sym,
|
||||||
type: "let_static",
|
type: "let_static",
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
this.syms[ident] = sym;
|
return this.syms[ident] = sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
public definedLocally(ident: string): boolean {
|
public definedLocally(ident: string): boolean {
|
||||||
@ -70,6 +93,21 @@ export class ModSyms implements Syms {
|
|||||||
}
|
}
|
||||||
return { ok: false };
|
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 {
|
export class FnSyms implements Syms {
|
||||||
@ -77,16 +115,16 @@ export class FnSyms implements Syms {
|
|||||||
|
|
||||||
public constructor(private parent: Syms) {}
|
public constructor(private parent: Syms) {}
|
||||||
|
|
||||||
public define(ident: string, sym: Sym) {
|
public define(ident: string, sym: Sym): Sym {
|
||||||
if (sym.type === "let") {
|
if (sym.type === "let") {
|
||||||
this.define(ident, {
|
return this.define(ident, {
|
||||||
...sym,
|
...sym,
|
||||||
type: "closure",
|
type: "closure",
|
||||||
inner: sym,
|
inner: sym,
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
this.syms[ident] = sym;
|
this.syms[ident] = sym;
|
||||||
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
public definedLocally(ident: string): boolean {
|
public definedLocally(ident: string): boolean {
|
||||||
@ -99,6 +137,21 @@ export class FnSyms implements Syms {
|
|||||||
}
|
}
|
||||||
return this.parent.get(ident);
|
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 {
|
export class LeafSyms implements Syms {
|
||||||
@ -106,8 +159,9 @@ export class LeafSyms implements Syms {
|
|||||||
|
|
||||||
public constructor(private parent: Syms) {}
|
public constructor(private parent: Syms) {}
|
||||||
|
|
||||||
public define(ident: string, sym: Sym) {
|
public define(ident: string, sym: Sym): Sym {
|
||||||
this.syms[ident] = sym;
|
this.syms[ident] = sym;
|
||||||
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
public definedLocally(ident: string): boolean {
|
public definedLocally(ident: string): boolean {
|
||||||
@ -120,4 +174,19 @@ export class LeafSyms implements Syms {
|
|||||||
}
|
}
|
||||||
return this.parent.get(ident);
|
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