refactor(joinir): Phase 222.5 - Modularization & Determinism

Phase 222.5-B: ConditionEnv API Unification
- Remove deprecated build_loop_param_only() (v1)
- Unify build_with_captures() to use JoinValueSpace (v2 API)
- Code reduction: -17 lines
- Tests: 5/5 PASS

Phase 222.5-C: exit_binding.rs Modularization
- Split into 4 modules following Phase 33 pattern:
  - exit_binding_validator.rs (171 lines)
  - exit_binding_constructor.rs (165 lines)
  - exit_binding_applicator.rs (163 lines)
  - exit_binding.rs orchestrator (364 lines, -71 reduction)
- Single responsibility per module
- Tests: 16/16 PASS

Phase 222.5-D: HashMap → BTreeMap for Determinism
- Convert 13 critical locations to BTreeMap:
  - exit_binding (3), carrier_info (2), pattern_pipeline (1)
  - loop_update_analyzer (2), loop_with_break/continue (2)
  - pattern4_carrier_analyzer (1), condition_env (2)
- Deterministic iteration guaranteed in JoinIR pipeline
- Inventory document: phase222-5-d-hashmap-inventory.md
- Tests: 849/856 PASS (7 pre-existing failures)
- Determinism verified: 3-run consistency test PASS

Overall Impact:
- Code quality: Single responsibility, function-based design
- Determinism: JoinIR pipeline now uses BTreeMap uniformly
- Tests: All Phase 222.5 tests passing
- Documentation: Complete inventory & implementation plan

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-10 13:59:23 +09:00
parent e3b36aa83a
commit 948cc68889
16 changed files with 788 additions and 180 deletions

View File

@ -22,7 +22,7 @@
use crate::ast::{ASTNode, BinaryOperator, LiteralValue};
use crate::mir::join_ir::lowering::carrier_info::CarrierVar;
use crate::mir::join_ir::BinOpKind;
use std::collections::HashMap;
use std::collections::BTreeMap; // Phase 222.5-D: HashMap → BTreeMap for determinism
/// Update expression for a carrier variable
#[derive(Debug, Clone)]
@ -81,8 +81,8 @@ impl LoopUpdateAnalyzer {
pub fn analyze_carrier_updates(
body: &[ASTNode],
carriers: &[CarrierVar],
) -> HashMap<String, UpdateExpr> {
let mut updates = HashMap::new();
) -> BTreeMap<String, UpdateExpr> { // Phase 222.5-D: HashMap → BTreeMap for determinism
let mut updates = BTreeMap::new();
// Extract carrier names for quick lookup
let carrier_names: Vec<&str> = carriers.iter().map(|c| c.name.as_str()).collect();
@ -100,7 +100,7 @@ impl LoopUpdateAnalyzer {
fn scan_nodes(
nodes: &[ASTNode],
carrier_names: &[&str],
updates: &mut HashMap<String, UpdateExpr>,
updates: &mut BTreeMap<String, UpdateExpr>, // Phase 222.5-D: HashMap → BTreeMap for determinism
) {
for node in nodes {
match node {