Files
hakorune/src/mir/builder/exprs_peek.rs
Selfhosting Dev ad62066172 feat: 改行処理革命Phase 2-B完了 - Box宣言系skip_newlines()完全削除
 **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>
2025-09-23 11:22:16 +09:00

134 lines
5.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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