feat(phi): Phase 25.1 - BTreeMap移行 (21ファイル、80%決定性達成)

## 修正内容

### Core MIR/PHI (5ファイル)
- builder.rs: variable_map, value_types, value_origin_newbox
- context.rs: 3つのマップ
- loop_builder.rs: 3箇所
- loop_snapshot_manager.rs: snapshot マップ
- loop_snapshot_merge.rs: 2箇所

### MIR関連 (4ファイル)
- function.rs: FunctionMetadata.value_types
- resolver.rs: CalleeResolverBox
- guard.rs: CalleeGuardBox
- loop_common.rs: apply_increment_before_continue

### JSON Bridge (5ファイル)
- json_v0_bridge/lowering.rs
- json_v0_bridge/lowering/expr.rs
- json_v0_bridge/lowering/if_else.rs
- json_v0_bridge/lowering/merge.rs
- json_v0_bridge/lowering/try_catch.rs
- json_v0_bridge/mod.rs

### Printer & Providers (4ファイル)
- printer.rs, printer_helpers.rs
- host_providers/mir_builder.rs
- backend/mir_interpreter/handlers/extern_provider.rs

### Tests (3ファイル)
- phi_core/conservative.rs
- tests/json_program_loop.rs
- tests/mir_stage1_using_resolver_verify.rs (2テスト有効化)

## テスト結果
- mir_stage1_using_resolver_resolve_with_modules_map_verifies: 80%成功率
- 完全な決定性は未達成 (HashMap 86箇所、HashSet 63箇所が残存)

🐱 Generated with Claude Code
This commit is contained in:
nyash-codex
2025-11-22 05:33:40 +09:00
parent 6815065e72
commit 7812c3d4c1
38 changed files with 583 additions and 479 deletions

View File

@ -26,7 +26,7 @@ use crate::mir::control_form::{is_control_form_trace_on, ControlForm, IfShape, L
use crate::mir::phi_core::loop_snapshot_merge::LoopSnapshotMergeBox;
use crate::mir::phi_core::loopform_builder::{LoopFormBuilder, LoopFormOps};
use crate::mir::phi_core::phi_input_collector::PhiInputCollector;
use std::collections::HashMap;
use std::collections::{BTreeMap, BTreeSet}; // Phase 25.1: 決定性確保
// Phase 15 段階的根治戦略:制御フローユーティリティ
use super::utils::{capture_actual_predecessor_and_jump, is_current_block_terminated};
@ -46,8 +46,9 @@ pub struct LoopBuilder<'a> {
parent_builder: &'a mut super::builder::MirBuilder,
/// ブロックごとの変数マップ(スコープ管理)
/// Phase 25.1: BTreeMap → BTreeMap決定性確保
#[allow(dead_code)]
block_var_maps: HashMap<BasicBlockId, HashMap<String, ValueId>>,
block_var_maps: BTreeMap<BasicBlockId, BTreeMap<String, ValueId>>,
/// ループヘッダーIDcontinue 先の既定値として使用)
loop_header: Option<BasicBlockId>,
@ -58,10 +59,10 @@ pub struct LoopBuilder<'a> {
continue_target: Option<BasicBlockId>,
/// continue文からの変数スナップショット
continue_snapshots: Vec<(BasicBlockId, HashMap<String, ValueId>)>,
continue_snapshots: Vec<(BasicBlockId, BTreeMap<String, ValueId>)>,
/// break文からの変数スナップショットexit PHI生成用
exit_snapshots: Vec<(BasicBlockId, HashMap<String, ValueId>)>,
exit_snapshots: Vec<(BasicBlockId, BTreeMap<String, ValueId>)>,
// フェーズM: no_phi_modeフィールド削除常にPHI使用
}
@ -167,7 +168,7 @@ impl<'a> LoopBuilder<'a> {
pub fn new(parent: &'a mut super::builder::MirBuilder) -> Self {
Self {
parent_builder: parent,
block_var_maps: HashMap::new(),
block_var_maps: BTreeMap::new(),
loop_header: None,
continue_target: None,
continue_snapshots: Vec::new(),
@ -481,7 +482,7 @@ impl<'a> LoopBuilder<'a> {
// Phase 25.2: LoopSnapshotMergeBox を使って整理
self.set_current_block(continue_merge_id)?;
let merged_snapshot: HashMap<String, ValueId> = if !raw_continue_snaps.is_empty() {
let merged_snapshot: BTreeMap<String, ValueId> = if !raw_continue_snaps.is_empty() {
if trace_loop_phi {
eprintln!(
"[loop-phi/continue-merge] Generating PHI nodes for {} continue paths",
@ -490,7 +491,7 @@ impl<'a> LoopBuilder<'a> {
}
// すべての continue snapshot に現れる変数を収集
let mut all_vars: HashMap<String, Vec<(BasicBlockId, ValueId)>> = HashMap::new();
let mut all_vars: BTreeMap<String, Vec<(BasicBlockId, ValueId)>> = BTreeMap::new();
for (continue_bb, snapshot) in &raw_continue_snaps {
for (var_name, &value) in snapshot {
all_vars
@ -501,7 +502,7 @@ impl<'a> LoopBuilder<'a> {
}
// 各変数について PHI ードを生成Phase 26-B-3: PhiInputCollector使用
let mut merged = HashMap::new();
let mut merged = BTreeMap::new();
for (var_name, inputs) in all_vars {
// Phase 26-B-3: Use PhiInputCollector
let mut collector = PhiInputCollector::new();
@ -550,7 +551,7 @@ impl<'a> LoopBuilder<'a> {
}
merged
} else {
HashMap::new()
BTreeMap::new()
};
self.emit_jump(header_id)?;
@ -564,7 +565,7 @@ impl<'a> LoopBuilder<'a> {
// Phase 25.3: Continue merge PHI実装Task先生の発見
// - continueが無いループでも、Latchブロックの値をHeader PHIに伝播する必要がある
// - これにより、Exit PHIがHeader PHI経由で正しい値を受け取れる
let continue_snaps: Vec<(BasicBlockId, HashMap<String, ValueId>)> = {
let continue_snaps: Vec<(BasicBlockId, BTreeMap<String, ValueId>)> = {
// まず、merged_snapshotcontinue merge PHI結果を追加
let mut snaps = if !merged_snapshot.is_empty() {
vec![(continue_merge_id, merged_snapshot.clone())]
@ -603,7 +604,8 @@ impl<'a> LoopBuilder<'a> {
// Phase 25.1h: ControlForm統合版に切り替え
// continue / break のターゲットブロックをユニーク化して収集
let mut break_set: HashSet<BasicBlockId> = HashSet::new();
// Phase 25.1: HashSet → BTreeSet決定性確保
let mut break_set: BTreeSet<BasicBlockId> = BTreeSet::new();
for (bb, _) in &self.exit_snapshots {
break_set.insert(*bb);
}
@ -835,7 +837,7 @@ impl<'a> LoopBuilder<'a> {
// =============================================================
// Variable Map Utilities — snapshots and rebinding
// =============================================================
fn get_current_variable_map(&self) -> HashMap<String, ValueId> {
fn get_current_variable_map(&self) -> BTreeMap<String, ValueId> { // Phase 25.1: BTreeMap化
self.parent_builder.variable_map.clone()
}
@ -1009,7 +1011,7 @@ impl<'a> LoopBuilder<'a> {
}
}
}
let mut else_var_map_end_opt: Option<HashMap<String, ValueId>> = None;
let mut else_var_map_end_opt: Option<BTreeMap<String, ValueId>> = None;
if let Some(es) = else_body.clone() {
for s in es.into_iter() {
let _ = self.build_statement(s)?;
@ -1032,7 +1034,8 @@ impl<'a> LoopBuilder<'a> {
self.parent_builder
.debug_push_region(format!("join#{}", join_id) + "/join");
let mut vars: std::collections::HashSet<String> = std::collections::HashSet::new();
// Phase 25.1: HashSet → BTreeSet決定性確保
let mut vars: std::collections::BTreeSet<String> = std::collections::BTreeSet::new();
let then_prog = ASTNode::Program {
statements: then_body.clone(),
span: crate::ast::Span::unknown(),