From cc4ba445a7ccec87ff987a27008781c995afb045 Mon Sep 17 00:00:00 2001 From: sfja Date: Wed, 29 Apr 2026 23:06:47 +0200 Subject: [PATCH] add mir_lowerer --- src/lir.ts | 32 +++++++++-------- src/mir_lower.ts | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 15 deletions(-) create mode 100644 src/mir_lower.ts diff --git a/src/lir.ts b/src/lir.ts index 5e72e5f..5c0cc35 100644 --- a/src/lir.ts +++ b/src/lir.ts @@ -96,6 +96,23 @@ export type TyKind = | { tag: "Ptr" } | { tag: "Array"; ty: Ty; length: number }; +export class Builder { + constructor( + private bb: BasicBlock, + private cx: Context, + ) {} + + createInt(ty: Ty, value: number): Inst { + return this.push(ty, { tag: "Int", value }); + } + + private push(ty: Ty, kind: InstKind): Inst { + const inst = this.cx.createInst(this.bb, ty, kind); + this.bb.insts.push(inst); + return inst; + } +} + export class Context { private tys = new Map(); private instsHashIds = new Map(); @@ -219,18 +236,3 @@ export class Context { } } } - -export class Builder { - constructor( - private bb: BasicBlock, - private cx: Context, - ) {} - - createInt(ty: Ty, value: number) { - this.push(ty, { tag: "Int", value }); - } - - private push(ty: Ty, kind: InstKind) { - this.bb.insts.push(this.cx.createInst(this.bb, ty, kind)); - } -} diff --git a/src/mir_lower.ts b/src/mir_lower.ts new file mode 100644 index 0000000..7baf08e --- /dev/null +++ b/src/mir_lower.ts @@ -0,0 +1,94 @@ +import * as mir from "./mir.ts"; +import * as lir from "./lir.ts"; +import { Ty } from "./ty.ts"; + +export class MirModuleLowerer { + private cx = new lir.Context(); + + constructor( + private mod: lir.Mod, + ) {} + + lowerFn(mirFn: mir.Fn) { + const lirFn = new lir.Fn(this.mod); + const fnLowerer = new MirFnLowerer(mirFn, lirFn, this.cx); + fnLowerer.lower(); + } +} + +class MirFnLowerer { + private insts = new Map(); + + constructor( + private mirFn: mir.Fn, + private lirFn: lir.Fn, + private cx: lir.Context, + ) {} + + lower() { + for (const mirBb of this.mirFn.bbs) { + const lirBb = new lir.BasicBlock(this.lirFn); + const builder = new lir.Builder(lirBb, this.cx); + for (const mirInst of mirBb.insts) { + const lirInst = this.lowerInst(mirInst, builder); + this.insts.set(mirInst, lirInst); + } + } + } + + private lowerInst(inst: mir.Inst, builder: lir.Builder): lir.Inst { + switch (inst.kind.tag) { + case "Error": + throw new Error(); + case "Void": + break; + case "Int": { + const ty = this.lowerTy(inst.ty); + return builder.createInt(ty, inst.kind.value); + } + case "Bool": + case "Str": + case "Array": + case "Fn": + case "Param": + case "GetElemPtr": + case "Slice": + case "Call": + case "Alloca": + case "Load": + case "Store": + case "Jump": + case "Branch": + case "Return": + case "Not": + case "Negate": + case "Eq": + case "Ne": + case "Lt": + case "Gt": + case "Lte": + case "Gte": + case "BitOr": + case "BitXor": + case "BitAnd": + case "Shl": + case "Shr": + case "Add": + case "Sub": + case "Mul": + case "Div": + case "Rem": + case "Len": + case "DebugPrint": + throw new Error(`not handled (${inst.kind.tag})`); + } + } + + private lowerTy(ty: Ty): lir.Ty { + switch (ty.kind.tag) { + default: + throw new Error(`not handled (${ty.kind.tag})`); + } + } +} +