## リファクタリング内容
### ファイル構造変更
- `src/mir/loop_builder.rs` (1515行) 削除
- `src/mir/loop_builder/` ディレクトリ新設(6ファイル、1529行)
### 新規モジュール構成
1. **mod.rs** (6,293行 → 実際は約150行)
- モジュール定義とre-export
- LoopBuilder構造体定義
2. **loop_form.rs** (25,988行 → 実際は約650行)
- メインループlowering pipeline
- デバッグ/実験フラグ集約
3. **if_lowering.rs** (15,600行 → 実際は約390行)
- In-loop if lowering with JoinIR/PHI bridge
- **Phase 61-2コード完全保持**:
- JoinIR dry-run検証モード
- PhiSpec計算とA/B比較
4. **phi_ops.rs** (12,844行 → 実際は約320行)
- PHI emit helpers
- LoopFormOps/PhiBuilderOps impls
5. **control.rs** (4,261行 → 実際は約107行)
- break/continue capture
- predecessor bookkeeping
6. **statements.rs** (1,673行 → 実際は約42行)
- loop-body statement lowering entry point
7. **README.md** (752行 → 実際は約19行)
- モジュール責務とサブモジュール説明
### 設計原則
- **責務分離**: CFG構築/PHI生成/制御フロー/文処理を分離
- **Phase 61-2保持**: if_lowering.rsにJoinIR dry-run完全移行
- **phi_core委譲**: PHI構築ロジックは`phi_core`に委譲
## テスト結果
- Phase 61-2テスト: ✅ 2/2 PASS(dry-runフラグ、PhiSpec)
- loopformテスト: ✅ 14/14 PASS(退行なし)
- ビルド: ✅ 成功(エラー0件)
## 統計
- **純削減**: -1,521行(25ファイル変更)
- **loop_builder**: 1515行 → 1529行(+14行、6ファイル化)
- **可読性**: 巨大単一ファイル → 責務別モジュール
## ChatGPT設計・Claude確認
大規模リファクタリングをChatGPTが実施、Claudeが検証完了。
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
40 lines
1.6 KiB
Rust
40 lines
1.6 KiB
Rust
use super::{LoopBuilder, ValueId};
|
||
use crate::ast::ASTNode;
|
||
use crate::mir::utils::is_current_block_terminated;
|
||
use crate::mir::ConstValue;
|
||
|
||
impl<'a> LoopBuilder<'a> {
|
||
pub(super) fn build_statement(&mut self, stmt: ASTNode) -> Result<ValueId, String> {
|
||
// Preserve the originating span for loop-local control instructions (break/continue/phi).
|
||
self.parent_builder.current_span = stmt.span();
|
||
match stmt {
|
||
// Ensure nested bare blocks inside loops are lowered with loop-aware semantics
|
||
ASTNode::Program { statements, .. } => {
|
||
let mut last = None;
|
||
for s in statements.into_iter() {
|
||
last = Some(self.build_statement(s)?);
|
||
// フェーズS修正:統一終端検出ユーティリティ使用
|
||
if is_current_block_terminated(self.parent_builder)? {
|
||
break;
|
||
}
|
||
}
|
||
Ok(last.unwrap_or_else(|| {
|
||
let void_id = self.new_value();
|
||
// Emit a void const to keep SSA consistent when block is empty
|
||
let _ = self.emit_const(void_id, ConstValue::Void);
|
||
void_id
|
||
}))
|
||
}
|
||
ASTNode::If {
|
||
condition,
|
||
then_body,
|
||
else_body,
|
||
..
|
||
} => self.lower_if_in_loop(*condition, then_body, else_body),
|
||
ASTNode::Break { .. } => self.do_break(),
|
||
ASTNode::Continue { .. } => self.do_continue(),
|
||
other => self.parent_builder.build_expression(other),
|
||
}
|
||
}
|
||
}
|