diff --git a/src/mir/builder/exprs.rs b/src/mir/builder/exprs.rs index 2294a8bf..c8bf09bd 100644 --- a/src/mir/builder/exprs.rs +++ b/src/mir/builder/exprs.rs @@ -1,6 +1,6 @@ // Expression lowering split from builder.rs to keep files lean use super::{ConstValue, MirInstruction, ValueId}; -use crate::ast::{ASTNode, AssignStmt, ReturnStmt}; +use crate::ast::{ASTNode, AssignStmt, ReturnStmt, BinaryExpr, CallExpr}; impl super::MirBuilder { // Main expression dispatcher @@ -19,12 +19,11 @@ impl super::MirBuilder { match ast { ASTNode::Literal { value, .. } => self.build_literal(value), - ASTNode::BinaryOp { - left, - operator, - right, - .. - } => self.build_binary_op(*left, operator, *right), + node @ ASTNode::BinaryOp { .. } => { + // Use BinaryExpr for clear destructuring (no behavior change) + let e = BinaryExpr::try_from(node).expect("ASTNode::BinaryOp must convert"); + self.build_binary_op(*e.left, e.operator, *e.right) + } ASTNode::UnaryOp { operator, operand, .. @@ -87,9 +86,10 @@ impl super::MirBuilder { } } - ASTNode::FunctionCall { - name, arguments, .. - } => self.build_function_call(name.clone(), arguments.clone()), + node @ ASTNode::FunctionCall { .. } => { + let c = CallExpr::try_from(node).expect("ASTNode::FunctionCall must convert"); + self.build_function_call(c.name, c.arguments) + } ASTNode::Call { callee, arguments, .. diff --git a/src/mir/builder/loops.rs b/src/mir/builder/loops.rs index 3d9e7594..43035252 100644 --- a/src/mir/builder/loops.rs +++ b/src/mir/builder/loops.rs @@ -1,5 +1,14 @@ //! Small loop utilities for MirBuilder -use super::BasicBlockId; +use super::{BasicBlockId, MirBuilder}; + +/// Create header/body/after blocks for a loop and push loop context. +pub(crate) fn create_loop_blocks(builder: &mut MirBuilder) -> (BasicBlockId, BasicBlockId, BasicBlockId) { + let header = builder.block_gen.next(); + let body = builder.block_gen.next(); + let after = builder.block_gen.next(); + push_loop_context(builder, header, after); + (header, body, after) +} /// Push loop context (header/exit) onto the MirBuilder stacks. pub(crate) fn push_loop_context( @@ -36,3 +45,19 @@ pub(crate) fn in_loop(builder: &super::MirBuilder) -> bool { pub(crate) fn depth(builder: &super::MirBuilder) -> usize { builder.loop_header_stack.len() } + +/// Add predecessor edge metadata to a basic block. +pub(crate) fn add_predecessor( + builder: &mut MirBuilder, + block: BasicBlockId, + pred: BasicBlockId, +) -> Result<(), String> { + if let Some(ref mut function) = builder.current_function { + if let Some(bb) = function.get_block_mut(block) { + bb.add_predecessor(pred); + return Ok(()); + } + return Err(format!("Block {} not found", block)); + } + Err("No current function".to_string()) +} diff --git a/src/mir/loop_builder.rs b/src/mir/loop_builder.rs index 6f1ed4ce..bcc35eb3 100644 --- a/src/mir/loop_builder.rs +++ b/src/mir/loop_builder.rs @@ -103,21 +103,14 @@ impl<'a> LoopBuilder<'a> { ) -> Result { // 1. ブロックの準備 let preheader_id = self.current_block()?; - let header_id = self.new_block(); - let body_id = self.new_block(); - let after_loop_id = self.new_block(); + let (header_id, body_id, after_loop_id) = + crate::mir::builder::loops::create_loop_blocks(self.parent_builder); self.loop_header = Some(header_id); self.continue_snapshots.clear(); - // Push loop context to parent builder (for nested break/continue lowering) - crate::mir::builder::loops::push_loop_context( - self.parent_builder, - header_id, - after_loop_id, - ); // 2. Preheader -> Header へのジャンプ self.emit_jump(header_id)?; - let _ = self.add_predecessor(header_id, preheader_id); + let _ = crate::mir::builder::loops::add_predecessor(self.parent_builder, header_id, preheader_id); // 3. Headerブロックの準備(unsealed状態) self.set_current_block(header_id)?; @@ -133,8 +126,8 @@ impl<'a> LoopBuilder<'a> { // 6. 条件分岐 self.emit_branch(condition_value, body_id, after_loop_id)?; - let _ = self.add_predecessor(body_id, header_id); - let _ = self.add_predecessor(after_loop_id, header_id); + let _ = crate::mir::builder::loops::add_predecessor(self.parent_builder, body_id, header_id); + let _ = crate::mir::builder::loops::add_predecessor(self.parent_builder, after_loop_id, header_id); // 7. ループボディの構築 self.set_current_block(body_id)?; @@ -159,7 +152,7 @@ impl<'a> LoopBuilder<'a> { // 実際の latch_id に対してスナップショットを紐づける self.block_var_maps.insert(latch_id, latch_snapshot); self.emit_jump(header_id)?; - let _ = self.add_predecessor(header_id, latch_id); + let _ = crate::mir::builder::loops::add_predecessor(self.parent_builder, header_id, latch_id); // 9. Headerブロックをシール(全predecessors確定) self.seal_block(header_id, latch_id)?; @@ -539,7 +532,7 @@ impl<'a> LoopBuilder<'a> { let cur_block = self.current_block()?; if let Some(exit_bb) = crate::mir::builder::loops::current_exit(self.parent_builder) { self.emit_jump(exit_bb)?; - let _ = self.add_predecessor(exit_bb, cur_block); + let _ = crate::mir::builder::loops::add_predecessor(self.parent_builder, exit_bb, cur_block); } // Continue building in a fresh (unreachable) block to satisfy callers let next_block = self.new_block(); @@ -556,7 +549,7 @@ impl<'a> LoopBuilder<'a> { if let Some(header) = self.loop_header { self.emit_jump(header)?; - let _ = self.add_predecessor(header, cur_block); + let _ = crate::mir::builder::loops::add_predecessor(self.parent_builder, header, cur_block); } let next_block = self.new_block();