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(); } }