From 317e6af0bf2bac9f11a803bce4aedff37d28ac70 Mon Sep 17 00:00:00 2001 From: Moe Charm Date: Mon, 25 Aug 2025 20:16:42 +0900 Subject: [PATCH] MIR: add loop_api facade trait and simple lowering helper; implement LoopBuilderApi for legacy MirBuilder to enable adapter-based migration. --- src/mir/loop_api.rs | 72 +++++++++++++++++++++++++++++++++++++++++++++ src/mir/mod.rs | 1 + 2 files changed, 73 insertions(+) create mode 100644 src/mir/loop_api.rs diff --git a/src/mir/loop_api.rs b/src/mir/loop_api.rs new file mode 100644 index 00000000..0ad75fc9 --- /dev/null +++ b/src/mir/loop_api.rs @@ -0,0 +1,72 @@ +/*! + * Loop Builder Facade (Minimal API) + * + * Goal: Decouple loop construction from concrete MirBuilder types by exposing + * a small trait that both legacy (mir::builder::MirBuilder) and modularized + * builders can implement. This enables shared helpers and gradual migration. + * + * Note: Only legacy MirBuilder is wired for now to keep WIP modularized code + * out of the main build. The modularized builder can implement this trait + * later without changing callers. + */ + +use super::{BasicBlockId, MirInstruction, ValueId}; + +/// Minimal API for constructing loops and emitting instructions +pub trait LoopBuilderApi { + /// Allocate a new basic block id + fn new_block(&mut self) -> BasicBlockId; + /// Get current block id + fn current_block(&self) -> Result; + /// Switch current block, creating it if needed + fn start_new_block(&mut self, block: BasicBlockId) -> Result<(), String>; + /// Emit an instruction to the current block + fn emit(&mut self, inst: MirInstruction) -> Result<(), String>; + /// Allocate a new SSA value id + fn new_value(&mut self) -> ValueId; +} + +/// Helper: simplified loop lowering usable by any LoopBuilderApi implementor +pub fn build_simple_loop( + lb: &mut L, + condition: ValueId, + build_body: &mut dyn FnMut(&mut L) -> Result<(), String>, +) -> Result { + let header = lb.new_block(); + let body = lb.new_block(); + let after = lb.new_block(); + + // Jump to header + lb.emit(MirInstruction::Jump { target: header })?; + + // Header: branch on provided condition + lb.start_new_block(header)?; + lb.emit(MirInstruction::Branch { condition, then_bb: body, else_bb: after })?; + + // Body + lb.start_new_block(body)?; + build_body(lb)?; + lb.emit(MirInstruction::Jump { target: header })?; + + // After: return void value + lb.start_new_block(after)?; + let void_id = lb.new_value(); + lb.emit(MirInstruction::Const { dst: void_id, value: super::instruction::ConstValue::Void })?; + Ok(void_id) +} + +// === Legacy wiring: implement LoopBuilderApi for mir::builder::MirBuilder === +impl LoopBuilderApi for super::builder::MirBuilder { + fn new_block(&mut self) -> BasicBlockId { self.block_gen.next() } + fn current_block(&self) -> Result { + self.current_block.ok_or_else(|| "No current block".to_string()) + } + fn start_new_block(&mut self, block: BasicBlockId) -> Result<(), String> { + super::builder::MirBuilder::start_new_block(self, block) + } + fn emit(&mut self, inst: MirInstruction) -> Result<(), String> { + super::builder::MirBuilder::emit_instruction(self, inst) + } + fn new_value(&mut self) -> ValueId { self.value_gen.next() } +} + diff --git a/src/mir/mod.rs b/src/mir/mod.rs index f26cf75d..dfed2302 100644 --- a/src/mir/mod.rs +++ b/src/mir/mod.rs @@ -11,6 +11,7 @@ pub mod basic_block; pub mod function; pub mod builder; pub mod loop_builder; // SSA loop construction with phi nodes +pub mod loop_api; // Minimal LoopBuilder facade (adapter-ready) pub mod verification; pub mod ownership_verifier_simple; // Simple ownership forest verification for current MIR pub mod printer;