feat(joinir): Phase 192-impl ComplexAddendNormalizer implementation

- New module: complex_addend_normalizer.rs (320 lines, 5 unit tests)
- Transforms `result = result * 10 + f(x)` into temp variable pattern
- Pattern2 preprocessing integration (~40 lines added)
- Zero changes to emission layers (reuses Phase 191 + Phase 190)

Tests:
- Unit tests: 5/5 passing (normalization logic)
- Regression: phase190/191 tests all pass
- Demo: phase192_normalization_demo.hako → 123

Limitation: Full E2E requires Phase 193 (MethodCall in init)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-09 04:20:28 +09:00
parent b7bf4a721e
commit 4f94309548
7 changed files with 705 additions and 6 deletions

View File

@ -240,9 +240,43 @@ impl MirBuilder {
break_condition_node.clone()
};
// Phase 192: Normalize complex addend patterns in loop body
// This transforms patterns like `result = result * 10 + digits.indexOf(ch)`
// into `local temp = digits.indexOf(ch); result = result * 10 + temp`
use crate::mir::join_ir::lowering::complex_addend_normalizer::{
ComplexAddendNormalizer, NormalizationResult
};
let mut normalized_body = Vec::new();
let mut has_normalization = false;
for node in _body {
match ComplexAddendNormalizer::normalize_assign(node) {
NormalizationResult::Normalized { temp_def, new_assign, temp_name } => {
eprintln!(
"[pattern2/phase192] Normalized complex addend: temp='{}' inserted before update",
temp_name
);
normalized_body.push(temp_def);
normalized_body.push(new_assign);
has_normalization = true;
}
NormalizationResult::Unchanged => {
normalized_body.push(node.clone());
}
}
}
// Use normalized body for analysis (only if normalization occurred)
let analysis_body = if has_normalization {
&normalized_body
} else {
_body
};
// Phase 176-3: Analyze carrier updates from loop body
use crate::mir::join_ir::lowering::loop_update_analyzer::LoopUpdateAnalyzer;
let carrier_updates = LoopUpdateAnalyzer::analyze_carrier_updates(_body, &carrier_info.carriers);
let carrier_updates = LoopUpdateAnalyzer::analyze_carrier_updates(analysis_body, &carrier_info.carriers);
eprintln!(
"[cf_loop/pattern2] Phase 176-3: Analyzed {} carrier updates",
@ -304,7 +338,7 @@ impl MirBuilder {
&env,
&carrier_info,
&carrier_updates,
_body, // Phase 191: Pass body AST for init lowering
analysis_body, // Phase 191/192: Pass normalized body AST for init lowering
Some(&mut body_local_env), // Phase 191: Pass mutable body-local environment
) {
Ok((module, meta)) => (module, meta),