feat(joinir): Phase 40-3.5 route switching implementation

- Add collect_assigned_vars_via_joinir() in if_phi.rs (65 lines)
  - Wrapper using Phase 40-1 JoinIR infrastructure
  - Converts ASTNode to JSON and calls JoinIR analysis
- Add route switching in loop_builder.rs
  - Check HAKO_JOINIR_ARRAY_FILTER env flag
  - Route A: Legacy collect_assigned_vars path
  - Route B: JoinIR collect_assigned_vars_via_joinir path
- Add A/B tests in phase40_array_ext_filter_test.rs
  - phase40_ab_route_switching: Basic assignment detection
  - phase40_ab_nested_if: Nested if assignment detection
- All 5 Phase 40 tests PASS

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-28 10:51:34 +09:00
parent 29058d2c9a
commit c7975d4bd9
4 changed files with 214 additions and 23 deletions

View File

@ -1061,19 +1061,31 @@ impl<'a> LoopBuilder<'a> {
.debug_push_region(format!("join#{}", join_id) + "/join");
// 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(),
};
crate::mir::phi_core::if_phi::collect_assigned_vars(&then_prog, &mut vars);
if let Some(es) = &else_body {
let else_prog = ASTNode::Program {
statements: es.clone(),
span: crate::ast::Span::unknown(),
// Phase 40-3.5: JoinIR route switching
let vars: std::collections::BTreeSet<String> =
if crate::config::env::use_joinir_for_array_filter() {
// Route B: JoinIR Frontend経由
crate::mir::phi_core::if_phi::collect_assigned_vars_via_joinir(
&then_body,
else_body.as_ref(),
)
} else {
// Route A: Legacy AST→MIR経由
let mut vars = std::collections::BTreeSet::new();
let then_prog = ASTNode::Program {
statements: then_body.clone(),
span: crate::ast::Span::unknown(),
};
crate::mir::phi_core::if_phi::collect_assigned_vars(&then_prog, &mut vars);
if let Some(es) = &else_body {
let else_prog = ASTNode::Program {
statements: es.clone(),
span: crate::ast::Span::unknown(),
};
crate::mir::phi_core::if_phi::collect_assigned_vars(&else_prog, &mut vars);
}
vars
};
crate::mir::phi_core::if_phi::collect_assigned_vars(&else_prog, &mut vars);
}
// Phase 26-E: PhiBuilderBox 統合
// Ops構造体: PhiMergeOpsLegacyと PhiBuilderOpsの両対応