✅ **41%削減達成**: 48→35→21箇所(14箇所削除) - fields.rs: 9箇所のskip_newlines()削除 - box_definition.rs: 3箇所削除 - static_box.rs: 2箇所削除 ✅ **Smart advance()実用化**: 深度追跡で自動改行処理完璧機能 - Box宣言、match式OR、複数行構文すべて対応 - NYASH_SMART_ADVANCE=1で安定動作確認 🔧 **ORパターンバグ同時修正**: exprs_peek.rsでInteger/Boolean型マッチング実装 - 修正前: 1 | 2 => "found" が動作せず(String型のみ) - 修正後: 全リテラル型(Integer/Bool/Float/Null/Void)完全対応 🎉 **技術的価値**: 手動skip依存→コンテキスト認識自動処理への移行成功 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
134 lines
5.0 KiB
Rust
134 lines
5.0 KiB
Rust
use super::{BasicBlockId, ValueId};
|
||
use crate::ast::{ASTNode, LiteralValue};
|
||
|
||
impl super::MirBuilder {
|
||
// Peek expression lowering
|
||
pub(super) fn build_peek_expression(
|
||
&mut self,
|
||
scrutinee: ASTNode,
|
||
arms: Vec<(LiteralValue, ASTNode)>,
|
||
else_expr: ASTNode,
|
||
) -> Result<ValueId, String> {
|
||
// Evaluate scrutinee in the current block
|
||
let scr_val = self.build_expression_impl(scrutinee)?;
|
||
|
||
// Prepare merge and result
|
||
let merge_block: BasicBlockId = self.block_gen.next();
|
||
let result_val = self.value_gen.next();
|
||
let mut phi_inputs: Vec<(BasicBlockId, ValueId)> = Vec::new();
|
||
|
||
// Create dispatch block where we start comparing arms
|
||
let dispatch_block = self.block_gen.next();
|
||
// Jump from current block to dispatch (ensure terminator exists)
|
||
let need_jump = {
|
||
let cur = self.current_block;
|
||
if let (Some(cb), Some(ref func)) = (cur, &self.current_function) {
|
||
if let Some(bb) = func.blocks.get(&cb) {
|
||
!bb.is_terminated()
|
||
} else {
|
||
true
|
||
}
|
||
} else {
|
||
true
|
||
}
|
||
};
|
||
if need_jump {
|
||
self.emit_instruction(super::MirInstruction::Jump {
|
||
target: dispatch_block,
|
||
})?;
|
||
}
|
||
self.start_new_block(dispatch_block)?;
|
||
|
||
// If there are no arms, fall through to else directly
|
||
if arms.is_empty() {
|
||
let else_block = self.block_gen.next();
|
||
self.emit_instruction(super::MirInstruction::Jump { target: else_block })?;
|
||
self.start_new_block(else_block)?;
|
||
let else_val = self.build_expression_impl(else_expr)?;
|
||
phi_inputs.push((else_block, else_val));
|
||
self.emit_instruction(super::MirInstruction::Jump {
|
||
target: merge_block,
|
||
})?;
|
||
self.start_new_block(merge_block)?;
|
||
// フェーズM: 常にPHI命令を使用(no_phi_mode撤廃)
|
||
self.emit_instruction(super::MirInstruction::Phi {
|
||
dst: result_val,
|
||
inputs: phi_inputs,
|
||
})?;
|
||
return Ok(result_val);
|
||
}
|
||
|
||
// Else block to handle default case
|
||
let else_block = self.block_gen.next();
|
||
|
||
// Chain dispatch blocks for each arm
|
||
let mut cur_dispatch = dispatch_block;
|
||
for (i, (label, arm_expr)) in arms.iter().cloned().enumerate() {
|
||
let then_block = self.block_gen.next();
|
||
// Next dispatch (only for non-last arm)
|
||
let next_dispatch = if i + 1 < arms.len() {
|
||
Some(self.block_gen.next())
|
||
} else {
|
||
None
|
||
};
|
||
let else_target = next_dispatch.unwrap_or(else_block);
|
||
|
||
// In current dispatch block, compare and branch
|
||
self.start_new_block(cur_dispatch)?;
|
||
let lit_id = self.value_gen.next();
|
||
let const_value = match label {
|
||
LiteralValue::String(s) => super::ConstValue::String(s),
|
||
LiteralValue::Integer(i) => super::ConstValue::Integer(i),
|
||
LiteralValue::Bool(b) => super::ConstValue::Bool(b),
|
||
LiteralValue::Float(f) => super::ConstValue::Float(f),
|
||
LiteralValue::Null => super::ConstValue::Null,
|
||
LiteralValue::Void => super::ConstValue::Void,
|
||
};
|
||
self.emit_instruction(super::MirInstruction::Const {
|
||
dst: lit_id,
|
||
value: const_value,
|
||
})?;
|
||
let cond_id = self.value_gen.next();
|
||
self.emit_instruction(super::MirInstruction::Compare {
|
||
dst: cond_id,
|
||
op: super::CompareOp::Eq,
|
||
lhs: scr_val,
|
||
rhs: lit_id,
|
||
})?;
|
||
self.emit_instruction(super::MirInstruction::Branch {
|
||
condition: cond_id,
|
||
then_bb: then_block,
|
||
else_bb: else_target,
|
||
})?;
|
||
|
||
// then arm
|
||
self.start_new_block(then_block)?;
|
||
let then_val = self.build_expression_impl(arm_expr)?;
|
||
phi_inputs.push((then_block, then_val));
|
||
self.emit_instruction(super::MirInstruction::Jump {
|
||
target: merge_block,
|
||
})?;
|
||
|
||
// Move to next dispatch or else block
|
||
cur_dispatch = else_target;
|
||
}
|
||
|
||
// Lower else expression in else_block
|
||
self.start_new_block(else_block)?;
|
||
let else_val = self.build_expression_impl(else_expr)?;
|
||
phi_inputs.push((else_block, else_val));
|
||
self.emit_instruction(super::MirInstruction::Jump {
|
||
target: merge_block,
|
||
})?;
|
||
|
||
// Merge and yield result
|
||
self.start_new_block(merge_block)?;
|
||
// フェーズM: 常にPHI命令を使用(no_phi_mode撤廃)
|
||
self.emit_instruction(super::MirInstruction::Phi {
|
||
dst: result_val,
|
||
inputs: phi_inputs,
|
||
})?;
|
||
Ok(result_val)
|
||
}
|
||
}
|