126 lines
3.7 KiB
TypeScript
126 lines
3.7 KiB
TypeScript
import { Ctx, DefId, IdentId } from "../ctx.ts";
|
|
import * as ast from "../ast/ast.ts";
|
|
import { ExprId, Ident, ItemId, PatId, StmtId, TyId } from "./hir.ts";
|
|
import { exhausted, Res as Result, todo } from "../util.ts";
|
|
|
|
export class AstLowerer {
|
|
private ribs: Rib[] = [];
|
|
|
|
public constructor(
|
|
private ctx: Ctx,
|
|
) {}
|
|
|
|
public lower() {
|
|
const file = this.ctx.entryFile();
|
|
const ast = this.ctx.fileInfo(file).ast!;
|
|
this.lowerFile(ast);
|
|
}
|
|
|
|
private lowerFile(file: ast.File) {
|
|
this.lowerStmts(file.stmts);
|
|
}
|
|
|
|
private lowerStmts(stmts: ast.Stmt[]): StmtId[] {
|
|
return stmts.map((stmt) => this.lowerStmt(stmt));
|
|
}
|
|
|
|
private lowerStmt(stmt: ast.Stmt): StmtId {
|
|
const kind = stmt.kind;
|
|
switch (kind.tag) {
|
|
case "error":
|
|
return this.ctx.internStmt(kind, stmt.span);
|
|
case "item":
|
|
return this.ctx.internStmt({
|
|
tag: "item",
|
|
item: this.lowerItem(kind.item),
|
|
}, stmt.span);
|
|
case "let":
|
|
return this.lowerLetStmt(stmt, kind);
|
|
case "return":
|
|
return this.ctx.internStmt({
|
|
tag: "return",
|
|
expr: kind.expr && this.lowerExpr(kind.expr),
|
|
}, stmt.span);
|
|
case "break":
|
|
return this.ctx.internStmt({
|
|
tag: "break",
|
|
expr: kind.expr && this.lowerExpr(kind.expr),
|
|
}, stmt.span);
|
|
case "continue":
|
|
return this.ctx.internStmt({
|
|
tag: "continue",
|
|
}, stmt.span);
|
|
case "assign":
|
|
return this.ctx.internStmt({
|
|
tag: "assign",
|
|
assignType: kind.assignType,
|
|
subject: this.lowerExpr(kind.subject),
|
|
value: this.lowerExpr(kind.value),
|
|
}, stmt.span);
|
|
case "expr":
|
|
return this.ctx.internStmt({
|
|
tag: "expr",
|
|
expr: this.lowerExpr(kind.expr),
|
|
}, stmt.span);
|
|
}
|
|
exhausted(kind);
|
|
}
|
|
|
|
private lowerLetStmt(stmt: ast.Stmt, kind: ast.LetStmt): StmtId {
|
|
return this.ctx.internStmt({
|
|
tag: "let",
|
|
pat: this.lowerPat(kind.pat),
|
|
ty: kind.ty && this.lowerTy(kind.ty),
|
|
expr: kind.expr && this.lowerExpr(kind.expr),
|
|
}, stmt.span);
|
|
}
|
|
|
|
private lowerItem(item: ast.Item): ItemId {
|
|
return todo();
|
|
}
|
|
|
|
private lowerPat(pat: ast.Pat): PatId {
|
|
return todo();
|
|
}
|
|
|
|
private lowerTy(ty: ast.Ty): TyId {
|
|
return todo();
|
|
}
|
|
|
|
private lowerExpr(expr: ast.Expr): ExprId {
|
|
return todo();
|
|
}
|
|
}
|
|
|
|
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/struct.Rib.html
|
|
type Rib = {
|
|
kind: RibKind;
|
|
bindings: Map<IdentId, Res>;
|
|
};
|
|
|
|
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/enum.RibKind.html
|
|
type RibKind =
|
|
| { tag: "normal" }
|
|
| { tag: "fn" }
|
|
| { tag: "item"; defKind: DefKind }
|
|
| { tag: "mod" };
|
|
|
|
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_resolve/late/enum.RibKind.html
|
|
type Res =
|
|
| { tag: "error" }
|
|
| { tag: "def"; kind: DefKind; id: DefId }
|
|
| { tag: "local"; id: DefId };
|
|
|
|
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def/enum.DefKind.html
|
|
type DefKind =
|
|
| { type: "mod" }
|
|
| { type: "struct" }
|
|
| { type: "enum" }
|
|
| { type: "variant" }
|
|
| { type: "ty_alias" }
|
|
| { type: "ty_param" }
|
|
| { type: "fn" }
|
|
| { type: "ctor" }
|
|
| { type: "use" }
|
|
| { type: "field" };
|