diff --git a/compiler/middle/hir.ts b/compiler/middle/hir.ts deleted file mode 100644 index 4a7fae4..0000000 --- a/compiler/middle/hir.ts +++ /dev/null @@ -1,277 +0,0 @@ -import { HirId, IdentId } from "../ctx.ts"; -import { Span } from "../diagnostics.ts"; -import { Mod, Res } from "./res.ts"; - -export type Stmt = { - id: HirId; - kind: StmtKind; - span: Span; -}; - -export type StmtKind = - | { tag: "error" } - | { tag: "item" } & ItemStmt - | { tag: "let" } & LetStmt - | { tag: "return" } & ReturnStmt - | { tag: "break" } & BreakStmt - | { tag: "continue" } - | { tag: "assign" } & AssignStmt - | { tag: "expr" } & ExprStmt; - -export type ItemStmt = { item: Item }; - -export type LetStmt = { - pat: Pat; - ty?: Ty; - expr?: Expr; -}; - -export type ReturnStmt = { expr?: Expr }; -export type BreakStmt = { expr?: Expr }; - -export type AssignStmt = { - assignType: AssignType; - subject: Expr; - value: Expr; -}; - -export type AssignType = "=" | "+=" | "-="; - -export type ExprStmt = { expr: Expr }; - -export type Item = { - id: HirId; - kind: ItemKind; - span: Span; - ident: Ident; - pub: boolean; -}; - -export type ItemKind = - | { tag: "error" } - | { tag: "mod" } & ModItem - | { tag: "enum" } & EnumItem - | { tag: "struct" } & StructItem - | { tag: "fn" } & FnItem - | { tag: "use" } & UseItem - | { tag: "type_alias" } & TypeAliasItem; - -export type ModItem = { mod: Mod }; -export type EnumItem = { variants: Variant[] }; -export type StructItem = { data: VariantData }; - -export type FnItem = { - generics?: Generics; - params: Param[]; - returnTy?: Ty; - body: Block; -}; - -export type UseItem = { _: 0 }; -export type TypeAliasItem = { ty: Ty }; - -export type Variant = { - ident: Ident; - data: VariantData; - pub: boolean; - span: Span; -}; - -export type VariantData = { - kind: VariantDataKind; - span: Span; -}; - -export type VariantDataKind = - | { tag: "error" } - | { tag: "unit" } - | { tag: "tuple" } & TupleVariantData - | { tag: "struct" } & StructVariantData; - -export type TupleVariantData = { elems: VariantData[] }; -export type StructVariantData = { fields: FieldDef[] }; - -export type FieldDef = { - ident: Ident; - ty: Ty; - pub: boolean; - span: Span; -}; - -export type Param = { - pat: Pat; - ty: Ty; - span: Span; -}; - -export type Generics = { - params: GenericParam[]; -}; - -export type GenericParam = { - ident: Ident; - span: Span; -}; - -export type Expr = { - id: HirId; - kind: ExprKind; - span: Span; -}; - -export type ExprKind = - | { tag: "error" } - | { tag: "path" } & PathExpr - | { tag: "null" } - | { tag: "int" } & IntExpr - | { tag: "bool" } & BoolExpr - | { tag: "str" } & StringExpr - | { tag: "group" } & GroupExpr - | { tag: "array" } & ArrayExpr - | { tag: "repeat" } & RepeatExpr - | { tag: "struct" } & StructExpr - | { tag: "ref" } & RefExpr - | { tag: "deref" } & DerefExpr - | { tag: "elem" } & ElemExpr - | { tag: "field" } & FieldExpr - | { tag: "index" } & IndexExpr - | { tag: "call" } & CallExpr - | { tag: "unary" } & UnaryExpr - | { tag: "binary" } & BinaryExpr - | { tag: "block" } & BlockExpr - | { tag: "if" } & IfExpr - | { tag: "loop" } & LoopExpr - | { tag: "while" } & WhileExpr - | { tag: "for" } & ForExpr - | { tag: "c_for" } & CForExpr; - -export type PathExpr = { path: QPath }; -export type IntExpr = { value: number }; -export type BoolExpr = { value: boolean }; -export type StringExpr = { value: string }; -export type GroupExpr = { expr: Expr }; -export type ArrayExpr = { exprs: Expr[] }; -export type RepeatExpr = { expr: Expr; length: Expr }; -export type StructExpr = { path?: QPath; fields: ExprField[] }; -export type RefExpr = { expr: Expr; refType: RefType; mut: boolean }; -export type DerefExpr = { expr: Expr }; -export type ElemExpr = { expr: Expr; elem: number }; -export type FieldExpr = { expr: Expr; ident: Ident }; -export type IndexExpr = { expr: Expr; index: Expr }; -export type CallExpr = { expr: Expr; args: Expr[] }; -export type UnaryExpr = { unaryType: UnaryType; expr: Expr }; -export type BinaryExpr = { - binaryType: BinaryType; - left: Expr; - right: Expr; -}; -export type BlockExpr = { block: Block }; -export type IfExpr = { cond: Expr; truthy: Block; falsy?: Expr }; -export type LoopExpr = { body: Block }; -export type WhileExpr = { cond: Expr; body: Block }; -export type ForExpr = { pat: Pat; expr: Expr; body: Block }; -export type CForExpr = { - decl?: Stmt; - cond?: Expr; - incr?: Stmt; - body: Block; -}; - -export type RefType = "ref" | "ptr"; -export type UnaryType = "not" | "-"; -export type BinaryType = - | "+" - | "*" - | "==" - | "-" - | "/" - | "!=" - | "<" - | ">" - | "<=" - | ">=" - | "or" - | "and"; - -export type ExprField = { - ident: Ident; - expr: Expr; - span: Span; -}; - -export type Pat = { - id: HirId; - kind: PatKind; - span: Span; -}; - -export type PatKind = - | { tag: "error" } - | { tag: "bind" } & BindPat - | { tag: "path" } & PathPat; - -export type BindPat = { ident: Ident; mut: boolean }; -export type PathPat = { path: QPath }; - -export type Ty = { - id: HirId; - kind: TyKind; - span: Span; -}; - -export type TyKind = - | { tag: "error" } - | { tag: "null" } - | { tag: "int" } - | { tag: "bool" } - | { tag: "str" } - | { tag: "path" } & PathTy - | { tag: "ref" } & RefTy - | { tag: "ptr" } & PtrTy - | { tag: "slice" } & SliceTy - | { tag: "array" } & ArrayTy - | { tag: "anon_struct" } & AnonStructTy; - -export type PathTy = { path: QPath }; -export type RefTy = { ty: Ty; mut: boolean }; -export type PtrTy = { ty: Ty; mut: boolean }; -export type SliceTy = { ty: Ty }; -export type ArrayTy = { ty: Ty; length: Expr }; -export type TupleTy = { elems: Ty[] }; -export type AnonStructTy = { fields: AnonFieldDef[] }; - -export type AnonFieldDef = { - ident: Ident; - ty: Ty; - span: Span; -}; - -export type Block = { - id: HirId; - stmts: Stmt[]; - expr?: Expr; - span: Span; -}; - -export type QPath = - | { tag: "resolved"; path: Path } - | { tag: "type_relative"; ty: Ty; seg: PathSegment }; - -export type Path = { - segments: PathSegment[]; - res: Res; - span: Span; -}; - -export type PathSegment = { - ident: Ident; - res: Res; - genericArgs?: Ty[]; - inferArgs: boolean; - span: Span; -}; - -export type Ident = { - id: IdentId; - span: Span; -}; diff --git a/compiler/middle/hir_eq.ts b/compiler/middle/hir_eq.ts deleted file mode 100644 index 53502fb..0000000 --- a/compiler/middle/hir_eq.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { arrayEq, exhausted } from "../util.ts"; -import { Ident, Item, Stmt, VariantData } from "./hir.ts"; - -/// Shallow equality -export function stmtEq(a: Stmt, b: Stmt): boolean { - const [ak, bk] = [a.kind, b.kind]; - switch (ak.tag) { - case "error": - return ak.tag === bk.tag; - case "item": - return ak.tag === bk.tag && ak.item === bk.item; - case "let": - return ak.tag === bk.tag && ak.pat === bk.pat && ak.ty === bk.ty && - ak.expr === bk.expr; - case "return": - return ak.tag === bk.tag && ak.expr === bk.expr; - case "break": - return ak.tag === bk.tag && ak.expr === bk.expr; - case "continue": - return ak.tag === bk.tag; - case "assign": - return ak.tag === bk.tag && ak.assignType === bk.assignType && - ak.subject === bk.subject && ak.value === bk.value; - case "expr": - return ak.tag === bk.tag && ak.expr === bk.expr; - } - exhausted(ak); -} - -/// Shallow equality -export function itemEq(a: Item, b: Item): boolean { - const [ak, bk] = [a.kind, b.kind]; - switch (ak.tag) { - case "error": - return ak.tag === bk.tag; - case "mod_block": - return ak.tag === bk.tag && ak.block === bk.block; - case "mod_file": - return ak.tag === bk.tag && ak.filePath === bk.filePath; - case "enum": - return ak.tag === bk.tag && - arrayEq(ak.variants, bk.variants); - case "struct": - return ak.tag === bk.tag && variantDataEq(ak.data, bk.data); - case "fn": - return ak.tag === bk.tag; - case "use": - return ak.tag === bk.tag; - case "type_alias": - return ak.tag === bk.tag; - } - exhausted(ak); -} - -export function variantDataEq(a: VariantData, b: VariantData): boolean { - const [ak, bk] = [a.kind, b.kind]; - switch (ak.tag) { - case "error": - return ak.tag === bk.tag; - case "unit": - return ak.tag === bk.tag; - case "tuple": - return ak.tag === bk.tag && - arrayEq(ak.elems, bk.elems, variantDataEq); - case "struct": - return ak.tag === bk.tag && - arrayEq( - ak.fields, - bk.fields, - (a, b) => - identEq(a.ident, b.ident) && a.ty === b.ty && - a.pub === b.pub && a.span === b.span, - ); - } - exhausted(ak); -} - -export function identEq(a: Ident, b: Ident): boolean { - return a.id === b.id; -} diff --git a/compiler/middle/lower_ast.ts b/compiler/middle/lower_ast.ts deleted file mode 100644 index 5e992a1..0000000 --- a/compiler/middle/lower_ast.ts +++ /dev/null @@ -1,637 +0,0 @@ -import { Ctx, DefId, File, IdentId, idKey, Mod } from "../ctx.ts"; -import * as ast from "../ast/ast.ts"; -import { - Block, - Expr, - Ident, - Item, - Pat, - Path, - PathSegment, - QPath, - Stmt, - Ty, -} from "./hir.ts"; -import { exhausted, Res as Result, todo } from "../util.ts"; -import { Rib, RibKind } from "./rib.ts"; -import { Res } from "./res.ts"; - -export class AstLowerer { - private tyRibs: Rib[] = []; - private valRibs: Rib[] = []; - private currentFile!: File; - private currentMod!: Mod; - - public constructor( - private ctx: Ctx, - ) {} - - public lower() { - const file = this.ctx.entryFile(); - this.currentFile = file; - this.currentMod = this.ctx.internMod({ - defKind: { tag: "mod" }, - ident: this.ctx.internIdent("root"), - items: new Set(), - defs: new Map(), - }); - const ast = this.ctx.fileInfo(file).ast!; - this.lowerFile(ast); - } - - private lowerFile(file: ast.File) { - this.lowerStmts(file.stmts); - } - - private lowerStmts(stmts: ast.Stmt[]): Stmt[] { - return stmts.map((stmt) => this.lowerStmt(stmt)); - } - - private lowerStmt(stmt: ast.Stmt): Stmt { - const span = stmt.span; - const kind = stmt.kind; - switch (kind.tag) { - case "error": - return this.ctx.internStmt(kind, span); - case "item": - return this.ctx.internStmt({ - tag: "item", - item: this.lowerItem(kind.item), - }, span); - case "let": - return this.lowerLetStmt(stmt, kind); - case "return": - return this.ctx.internStmt({ - tag: "return", - expr: kind.expr && this.lowerExpr(kind.expr), - }, span); - case "break": - return this.ctx.internStmt({ - tag: "break", - expr: kind.expr && this.lowerExpr(kind.expr), - }, span); - case "continue": - return this.ctx.internStmt({ - tag: "continue", - }, span); - case "assign": - return this.ctx.internStmt({ - tag: "assign", - assignType: kind.assignType, - subject: this.lowerExpr(kind.subject), - value: this.lowerExpr(kind.value), - }, span); - case "expr": - return this.ctx.internStmt({ - tag: "expr", - expr: this.lowerExpr(kind.expr), - }, span); - } - exhausted(kind); - } - - private lowerLetStmt(stmt: ast.Stmt, kind: ast.LetStmt): Stmt { - const expr = kind.expr && this.lowerExpr(kind.expr); - const ty = kind.ty && this.lowerTy(kind.ty); - this.pushRib({ tag: "normal" }); - const pat = this.lowerPat(kind.pat); - return this.ctx.internStmt({ tag: "let", pat, ty, expr }, stmt.span); - } - - private lowerItem(item: ast.Item): Item { - const { ident, kind, pub, span } = item; - switch (kind.tag) { - case "error": - return this.ctx.internItem({ ident, kind, pub, span }); - case "mod_block": { - const parent = this.currentMod; - const mod = this.currentMod = this.ctx.internMod({ - parent, - ident: ident.id, - defKind: { tag: "mod" }, - items: new Set(), - defs: new Map(), - }); - const point = this.ribPoint(); - this.pushRib({ tag: "mod", mod }); - const _block = this.lowerBlock(kind.block); - this.returnToRibPoint(point); - this.currentMod = parent; - return this.ctx.internItem({ - ident, - kind: { tag: "mod", mod }, - pub, - span, - }); - } - case "mod_file": { - const parent = this.currentMod; - const mod = this.currentMod = this.ctx.internMod({ - parent, - ident: ident.id, - defKind: { tag: "mod" }, - items: new Set(), - defs: new Map(), - }); - const point = this.ribPoint(); - this.pushRib({ tag: "mod", mod }); - const parentFile = this.currentFile; - const fileInfo = this.ctx.fileInfo(kind.file!); - this.lowerFile(fileInfo.ast!); - this.returnToRibPoint(point); - this.currentFile = parentFile; - this.currentMod = parent; - if (this.tyRib().bindings.has(idKey(ident.id))) { - throw new Error(); - } - this.tyRib().bindings.set(idKey(ident.id), { - tag: "def", - id: mod.id, - kind: { tag: "mod" }, - }); - return this.ctx.internItem({ - ident, - kind: { tag: "mod", mod }, - pub, - span, - }); - } - case "enum": - return todo(); - case "struct": - return todo(); - case "fn": { - return this.ctx.internItem({ - ident, - kind: { ...todo() }, - pub, - span, - }); - } - case "use": - return todo(); - case "type_alias": - return todo(); - } - exhausted(kind); - } - - private lowerExpr(expr: ast.Expr): Expr { - const span = expr.span; - const kind = expr.kind; - switch (kind.tag) { - case "error": - return this.ctx.internExpr(kind, span); - case "path": - return this.ctx.internExpr({ - tag: "path", - path: this.lowerPath(kind.path, kind.qty), - }, span); - case "null": - return this.ctx.internExpr(kind, span); - case "int": - return this.ctx.internExpr(kind, span); - case "bool": - return this.ctx.internExpr(kind, span); - case "str": - return this.ctx.internExpr(kind, span); - case "group": - return this.ctx.internExpr({ - tag: "group", - expr: this.lowerExpr(kind.expr), - }, span); - case "array": - return this.ctx.internExpr({ - tag: "array", - exprs: kind.exprs.map((expr) => this.lowerExpr(expr)), - }, span); - case "repeat": - return this.ctx.internExpr({ - tag: "repeat", - expr: this.lowerExpr(kind.expr), - length: this.lowerExpr(kind.length), - }, span); - case "struct": - return this.ctx.internExpr({ - tag: "struct", - path: kind.path && this.lowerPath(kind.path), - fields: kind.fields.map(({ ident, expr, span }) => ({ - ident, - expr: this.lowerExpr(expr), - span, - })), - }, span); - case "ref": - return this.ctx.internExpr({ - tag: "ref", - expr: this.lowerExpr(kind.expr), - refType: kind.refType, - mut: kind.mut, - }, span); - case "deref": - return this.ctx.internExpr({ - tag: "deref", - expr: this.lowerExpr(kind.expr), - }, span); - case "elem": - return this.ctx.internExpr({ - tag: "elem", - expr: this.lowerExpr(kind.expr), - elem: kind.elem, - }, span); - case "field": - return this.ctx.internExpr({ - tag: "field", - expr: this.lowerExpr(kind.expr), - ident: kind.ident, - }, span); - case "index": - return this.ctx.internExpr({ - tag: "index", - expr: this.lowerExpr(kind.expr), - index: this.lowerExpr(kind.index), - }, span); - case "call": - return this.ctx.internExpr({ - tag: "call", - expr: this.lowerExpr(kind.expr), - args: kind.args.map((arg) => this.lowerExpr(arg)), - }, span); - case "unary": - return this.ctx.internExpr({ - tag: "unary", - expr: this.lowerExpr(kind.expr), - unaryType: kind.unaryType, - }, span); - case "binary": - return this.ctx.internExpr({ - tag: "binary", - left: this.lowerExpr(kind.left), - right: this.lowerExpr(kind.right), - binaryType: kind.binaryType, - }, span); - case "block": - return this.ctx.internExpr({ - tag: "block", - block: this.lowerBlock(kind.block), - }, span); - case "if": - return this.ctx.internExpr({ - tag: "if", - cond: this.lowerExpr(kind.cond), - truthy: this.lowerBlock(kind.truthy), - falsy: kind.falsy && this.lowerExpr(kind.falsy), - }, span); - case "loop": - return this.ctx.internExpr({ - tag: "loop", - body: this.lowerBlock(kind.body), - }, span); - case "while": - throw new Error("not implemented"); - case "for": - throw new Error("not implemented"); - case "c_for": - throw new Error("not implemented"); - } - exhausted(kind); - } - - private lowerPat(pat: ast.Pat): Pat { - const span = pat.span; - const kind = pat.kind; - switch (kind.tag) { - case "error": - return this.ctx.internPat(kind, span); - case "bind": { - const v = this.ctx.internPat(kind, span); - this.valRib().bindings.set(idKey(kind.ident.id), { - tag: "local", - id: v.id, - }); - return v; - } - case "path": - return this.ctx.internPat({ - tag: "path", - path: this.lowerPath(kind.path, kind.qty), - }, span); - } - exhausted(kind); - } - - private lowerTy(ty: ast.Ty): Ty { - const span = ty.span; - const kind = ty.kind; - switch (kind.tag) { - case "error": - return this.ctx.internTy(kind, span); - case "null": - return this.ctx.internTy(kind, span); - case "int": - return this.ctx.internTy(kind, span); - case "bool": - return this.ctx.internTy(kind, span); - case "str": - return this.ctx.internTy(kind, span); - case "path": - return this.ctx.internTy({ - tag: "path", - path: this.lowerPath(kind.path, kind.qty), - }, span); - case "ref": - return this.ctx.internTy({ - tag: "ref", - ty: this.lowerTy(kind.ty), - mut: kind.mut, - }, span); - case "ptr": - return this.ctx.internTy({ - tag: "ptr", - ty: this.lowerTy(kind.ty), - mut: kind.mut, - }, span); - case "slice": - return this.ctx.internTy({ - tag: "slice", - ty: this.lowerTy(kind.ty), - }, span); - case "array": - return this.ctx.internTy({ - tag: "array", - ty: this.lowerTy(kind.ty), - length: this.lowerExpr(kind.length), - }, span); - case "anon_struct": - return this.ctx.internTy({ - tag: "anon_struct", - fields: kind.fields.map(({ ident, ty, span }) => ({ - ident, - ty: this.lowerTy(ty), - span, - })), - }, span); - } - exhausted(kind); - } - - private lowerBlock(block: ast.Block): Block { - const point = this.ribPoint(); - this.pushRib({ tag: "block" }); - const stmts = block.stmts.map((stmt) => this.lowerStmt(stmt)); - const expr = block.expr && this.lowerExpr(block.expr); - this.returnToRibPoint(point); - return this.ctx.internBlock({ stmts, expr, span: block.span }); - } - - private lowerPath(path: ast.Path, qty?: ast.Ty): QPath { - if (qty) { - const ty = this.lowerTy(qty); - if (path.segments.length !== 1) { - throw new Error(); - } - const seg = path.segments[0]; - return { - tag: "type_relative", - ty, - seg: { - ident: seg.ident, - res: todo(), - genericArgs: seg.genericArgs && - seg.genericArgs.map((ty) => this.lowerTy(ty)), - inferArgs: false, - span: path.span, - }, - }; - } - const [res, segments] = this.resolvePathSegs(path.segments); - return { - tag: "resolved", - path: { segments, res, span: path.span }, - }; - } - - private resolvePathSegs(segs: ast.PathSegment[]): [Res, PathSegment[]] { - if (segs.length <= 1) { - const seg = segs[0]; - const res = this.resolveTyIdent(seg.ident); - return [res, [{ - ident: seg.ident, - res, - genericArgs: seg.genericArgs && - seg.genericArgs.map((ty) => this.lowerTy(ty)), - inferArgs: false, - span: seg.span, - }]]; - } - const seg = segs.at(-1)!; - const [innerRes, resSegs] = this.resolvePathSegs( - segs.slice(0, segs.length - 1), - ); - switch (innerRes.tag) { - case "error": - return [innerRes, [...resSegs, { - ident: seg.ident, - res: innerRes, - inferArgs: false, - span: seg.span, - }]]; - case "def": { - const error = (): [ - Res, - PathSegment[], - ] => [{ tag: "error" }, [...resSegs, { - ident: seg.ident, - res: innerRes, - inferArgs: false, - span: seg.span, - }]]; - - const irk = innerRes.kind; - switch (irk.tag) { - case "mod": { - const mod = this.ctx.getMod(innerRes.id); - const res = mod.defs.get(seg.ident.id); - if (!res) { - this.ctx.report({ - severity: "error", - file: this.currentFile, - msg: `module does not contain definition for '${ - this.ctx.identText(seg.ident.id) - }'`, - span: seg.span, - }); - return error(); - } - return [res, [...resSegs, { - ident: seg.ident, - res: innerRes, - inferArgs: false, - span: seg.span, - }]]; - } - case "struct": - return todo(); - case "enum": - return todo(); - case "ty_alias": - return todo(); - case "ty_param": - return todo(); - case "use": - return todo(); - case "fn": - case "variant": - case "ctor": - case "field": - this.ctx.report({ - severity: "error", - file: this.currentFile, - msg: `${irk.tag} contains zero members`, - span: seg.span, - }); - return error(); - } - exhausted(irk); - throw new Error(); - } - case "local": - throw new Error("should not be possible"); - } - exhausted(innerRes); - } - - private resolveTyIdent(ident: Ident): Res { - return this.findTyRibIdent(this.tyRibs.length - 1, ident); - } - - private findTyRibIdent(ribIdx: number, ident: Ident): Res { - const rib = this.tyRibs[ribIdx]; - if (rib.bindings.has(idKey(ident.id))) { - return rib.bindings.get(idKey(ident.id))!; - } - if (ribIdx === 0) { - const text = this.ctx.identText(ident.id); - this.ctx.report({ - severity: "error", - file: this.currentFile, - span: ident.span, - msg: `no type with name '${text}' in module`, - }); - return { tag: "error" }; - } - const res = this.findTyRibIdent(ribIdx - 1, ident); - const kind = rib.kind; - switch (kind.tag) { - case "normal": - return res; - case "fn": - return res; - case "item": - if (res.tag === "local") { - const text = this.ctx.identText(ident.id); - this.ctx.report({ - severity: "error", - file: this.currentFile, - span: ident.span, - msg: `cannot use local '${text}' here`, - }); - return { tag: "error" }; - } - return res; - case "mod": { - const text = this.ctx.identText(ident.id); - this.ctx.report({ - severity: "error", - file: this.currentFile, - span: ident.span, - msg: `no type with name '${text}' in module`, - }); - return { tag: "error" }; - } - case "block": - return res; - } - exhausted(kind); - } - - private resolveValIdent(ident: Ident): Res { - return this.findValRibIdent(this.valRibs.length - 1, ident); - } - - private findValRibIdent(ribIdx: number, ident: Ident): Res { - const rib = this.valRibs[ribIdx]; - if (rib.bindings.has(idKey(ident.id))) { - return rib.bindings.get(idKey(ident.id))!; - } - if (ribIdx === 0) { - const text = this.ctx.identText(ident.id); - this.ctx.report({ - severity: "error", - file: this.currentFile, - span: ident.span, - msg: `no value with name '${text}' in module`, - }); - return { tag: "error" }; - } - const res = this.findValRibIdent(ribIdx - 1, ident); - const kind = rib.kind; - switch (kind.tag) { - case "normal": - return res; - case "fn": - return res; - case "item": - if (res.tag === "local") { - const text = this.ctx.identText(ident.id); - this.ctx.report({ - severity: "error", - file: this.currentFile, - span: ident.span, - msg: `cannot use local '${text}' here`, - }); - return { tag: "error" }; - } - return res; - case "mod": { - const text = this.ctx.identText(ident.id); - this.ctx.report({ - severity: "error", - file: this.currentFile, - span: ident.span, - msg: `no value with name '${text}' in module`, - }); - return { tag: "error" }; - } - case "block": - return res; - } - exhausted(kind); - } - private tyRib(): Rib { - return this.tyRibs.at(-1)!; - } - - private valRib(): Rib { - return this.valRibs.at(-1)!; - } - - private pushRib(kind: RibKind) { - this.tyRibs.push({ kind, bindings: new Map() }); - this.valRibs.push({ kind, bindings: new Map() }); - } - - private popRib() { - this.tyRibs.pop(); - this.valRibs.pop(); - } - - private ribPoint(): number { - return this.valRibs.length; - } - - private returnToRibPoint(point: number) { - this.tyRibs = this.tyRibs.slice(0, point); - this.valRibs = this.valRibs.slice(0, point); - } -} diff --git a/compiler/middle/res.ts b/compiler/middle/res.ts deleted file mode 100644 index 2b9a7e4..0000000 --- a/compiler/middle/res.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { DefId, HirId } from "../ctx.ts"; - -// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/enum.RibKind.html -export type Res = - | { tag: "error" } - | { tag: "def"; kind: DefKind; id: DefId } - | { tag: "local"; id: HirId }; - -// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def/enum.DefKind.html -export type DefKind = - | { tag: "mod" } - | { tag: "struct" } - | { tag: "enum" } - | { tag: "variant" } - | { tag: "ty_alias" } - | { tag: "ty_param" } - | { tag: "fn" } - | { tag: "ctor" } - | { tag: "use" } - | { tag: "field" }; diff --git a/compiler/middle/rib.ts b/compiler/middle/rib.ts deleted file mode 100644 index eb97fb6..0000000 --- a/compiler/middle/rib.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { IdentId, Key, Mod } from "../ctx.ts"; -import { DefKind, Res } from "./res.ts"; - -// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.Rib.html -export type Rib = { - kind: RibKind; - bindings: Map, Res>; -}; - -// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/enum.RibKind.html -export type RibKind = - /// No restriction needs to be applied. - | { tag: "normal" } - /// We passed through a function, closure or coroutine signature. Disallow labels. - | { tag: "fn" } - /// We passed through an item scope. Disallow upvars. - | { tag: "item"; defKind: DefKind } - /// We passed through a module. - | { tag: "mod"; mod: Mod } - /// We passed through a block (same as module, see Rust). - | { tag: "block" };