This commit is contained in:
sfja 2025-01-29 23:18:30 +01:00
parent b02c5e223f
commit 63d4406551
4 changed files with 65 additions and 49 deletions

View File

@ -7,6 +7,7 @@ import {
Span,
} from "./diagnostics.ts";
import * as hir from "./middle/hir.ts";
import { Mod } from "./middle/res.ts";
export class Ctx {
private fileIds = new Ids<File>();
@ -81,9 +82,9 @@ export class Ctx {
//
private hirIds = new Ids<hir.HirId>();
private hirIds = new Ids<HirId>();
private stmts = new Map<Key<hir.HirId>, hir.Stmt>();
private stmts = new Map<Key<HirId>, hir.Stmt>();
/// don't intern the same thing twice
public internStmt(kind: hir.StmtKind, span: Span): hir.Stmt {
@ -93,7 +94,7 @@ export class Ctx {
return v;
}
private exprs = new Map<Key<hir.HirId>, hir.Expr>();
private exprs = new Map<Key<HirId>, hir.Expr>();
/// don't intern the same thing twice
public internExpr(kind: hir.ExprKind, span: Span): hir.Expr {
@ -103,7 +104,7 @@ export class Ctx {
return v;
}
private pats = new Map<Key<hir.HirId>, hir.Pat>();
private pats = new Map<Key<HirId>, hir.Pat>();
/// don't intern the same thing twice
public internPat(kind: hir.PatKind, span: Span): hir.Pat {
@ -113,7 +114,7 @@ export class Ctx {
return v;
}
private tys = new Map<Key<hir.HirId>, hir.Ty>();
private tys = new Map<Key<HirId>, hir.Ty>();
/// don't intern the same thing twice
public internTy(kind: hir.TyKind, span: Span): hir.Ty {
@ -123,7 +124,7 @@ export class Ctx {
return v;
}
private blocks = new Map<Key<hir.HirId>, hir.Block>();
private blocks = new Map<Key<HirId>, hir.Block>();
/// don't intern the same thing twice
public internBlock(block: Omit<hir.Block, "id">): hir.Block {
@ -135,20 +136,31 @@ export class Ctx {
//
private defIds = new Ids<hir.DefId>();
private defIds = new Ids<DefId>();
private defs = new Map<Key<hir.DefId>, hir.HirId>();
private defs = new Map<Key<DefId>, HirId>();
public addHirIdDef(hirId: hir.HirId): hir.DefId {
public addHirIdDef(hirId: HirId): DefId {
const id = this.defIds.nextThenStep();
this.defs.set(idKey(id), hirId);
return id;
}
public defHirId(id: hir.DefId): hir.HirId {
public defHirId(id: DefId): HirId {
return this.defs.get(idKey(id))!;
}
private modDefs = new Map<Key<DefId>, Mod>();
private modItemMaps = new Map<Key<DefId>, Map<Key<IdentId>, DefId>>();
public modDef(id: DefId): Mod {
return this.modDefs.get(idKey(id))!;
}
public mod(id: DefId, ident: IdentId): DefId | undefined {
return this.modItemMaps.get(idKey(id))!.get(idKey(ident));
}
//
public filePosLineText(file: File, pos: Pos): string {

View File

@ -1,7 +1,6 @@
export type { DefId, HirId } from "../ctx.ts";
import { HirId, IdentId } from "../ctx.ts";
import { Span } from "../diagnostics.ts";
import { Res } from "./rib.ts";
import { Res } from "./res.ts";
export type Stmt = {
id: HirId;
@ -261,6 +260,7 @@ export type QPath =
export type Path = {
segments: PathSegment[];
res: Res;
span: Span;
};

View File

@ -13,7 +13,8 @@ import {
Ty,
} from "./hir.ts";
import { exhausted, Res as Result, todo } from "../util.ts";
import { Res, Rib } from "./rib.ts";
import { Rib } from "./rib.ts";
import { Res } from "./res.ts";
export class AstLowerer {
private ribs: Rib[] = [];
@ -292,6 +293,10 @@ export class AstLowerer {
private lowerBlock(block: ast.Block): Block {
const point = this.ribPoint();
this.pushRib({
kind: { tag: "mod", mod: { kind: { tag: "block" } } },
bindings: new Map(),
});
const stmts = block.stmts.map((stmt) => this.lowerStmt(stmt));
const expr = block.expr && this.lowerExpr(block.expr);
this.returnToRibPoint(point);
@ -318,11 +323,10 @@ export class AstLowerer {
},
};
}
const res = this.resolvePathSegs(path.segments);
const [res, segments] = this.resolvePathSegs(path.segments);
return {
path: {
segments
}
tag: "resolved",
path: { segments, res, span: path.span },
};
}
@ -330,28 +334,41 @@ export class AstLowerer {
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: }]]
return [res, [{
ident: seg.ident,
res,
genericArgs: seg.genericArgs &&
seg.genericArgs.map((ty) => this.lowerTy(ty)),
inferArgs: false,
span: seg.span,
}]];
}
const innerRes = this.resolvePathSegs(segs.slice(1));
const seg = segs.at(-1)!;
const [innerRes, resSegs] = this.resolvePathSegs(
segs.slice(0, segs.length - 1),
);
switch (innerRes.tag) {
case "error":
return innerRes;
return [innerRes, [...resSegs, {
ident: seg.ident,
res: innerRes,
inferArgs: false,
span: seg.span,
}]];
case "def": {
const irk = innerRes.kind;
switch (irk.tag) {
case "mod":
case "mod": {
const mod = this.ctx.modDef(innerRes.id);
const def = this.ctx.modItem();
return todo();
}
case "struct":
return todo();
case "enum":
return todo();
case "variant":
return todo();
case "ty_alias":
return todo();
case "ty_param":
return todo();
case "fn":
return todo();
case "ctor":
@ -362,7 +379,7 @@ export class AstLowerer {
return todo();
}
exhausted(irk);
return todo();
throw new Error();
}
case "local":
throw new Error("should not be possible");

View File

@ -1,5 +1,5 @@
import { DefId, HirId, IdentId } from "../ctx.ts";
import { Mod } from "../main.ts";
import { IdentId } from "../ctx.ts";
import { DefKind, Mod, Res } from "./res.ts";
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.Rib.html
export type Rib = {
@ -9,26 +9,13 @@ export type Rib = {
// 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 }
| { tag: "mod"; mod: Mod };
// 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" };
/// We passed through a module.
| { tag: "mod"; mod: Mod }
/// We passed through a block (same as module, see Rust).
| { tag: "block" };