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:
@ -456,6 +456,145 @@ result = result * 10 + temp_result_addend
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## Section 9: Implementation Complete (2025-12-09)
|
||||
|
||||
### 9.1 Implementation Summary
|
||||
|
||||
**Status**: ✅ Phase 192-impl Complete
|
||||
|
||||
**Deliverables**:
|
||||
1. ✅ `ComplexAddendNormalizer` module implemented (`src/mir/join_ir/lowering/complex_addend_normalizer.rs`)
|
||||
2. ✅ 5 unit tests all passing (method call, simple variable, wrong LHS, no multiplication, subtraction)
|
||||
3. ✅ Pattern2 integration complete (preprocessing before carrier update analysis)
|
||||
4. ✅ Existing tests verified (phase190/191 tests still pass)
|
||||
5. ✅ Documentation updated
|
||||
|
||||
### 9.2 Actual Implementation
|
||||
|
||||
**File**: `src/mir/join_ir/lowering/complex_addend_normalizer.rs`
|
||||
|
||||
**API**:
|
||||
```rust
|
||||
pub enum NormalizationResult {
|
||||
Unchanged,
|
||||
Normalized { temp_def: ASTNode, new_assign: ASTNode, temp_name: String },
|
||||
}
|
||||
|
||||
impl ComplexAddendNormalizer {
|
||||
pub fn normalize_assign(assign: &ASTNode) -> NormalizationResult;
|
||||
}
|
||||
```
|
||||
|
||||
**Integration Point** (Pattern2 - line 243-279):
|
||||
```rust
|
||||
// Phase 192: Normalize complex addend patterns in loop body
|
||||
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 } => {
|
||||
normalized_body.push(temp_def); // local temp = <complex_expr>
|
||||
normalized_body.push(new_assign); // lhs = lhs * base + temp
|
||||
has_normalization = true;
|
||||
}
|
||||
NormalizationResult::Unchanged => {
|
||||
normalized_body.push(node.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let analysis_body = if has_normalization { &normalized_body } else { _body };
|
||||
// Pass analysis_body to LoopUpdateAnalyzer and lower_loop_with_break_minimal
|
||||
```
|
||||
|
||||
### 9.3 AST Transformation Example
|
||||
|
||||
**Before**:
|
||||
```nyash
|
||||
result = result * 10 + digits.indexOf(ch)
|
||||
```
|
||||
|
||||
**After** (Normalized AST):
|
||||
```nyash
|
||||
local temp_result_addend = digits.indexOf(ch)
|
||||
result = result * 10 + temp_result_addend
|
||||
```
|
||||
|
||||
**AST Structure**:
|
||||
```
|
||||
[
|
||||
Local { variables: ["temp_result_addend"], initial_values: [MethodCall(...)] },
|
||||
Assignment { target: "result", value: BinOp(Add, BinOp(Mul, "result", 10), "temp_result_addend") }
|
||||
]
|
||||
```
|
||||
|
||||
### 9.4 Test Results
|
||||
|
||||
**Unit Tests** (5/5 passing):
|
||||
- ✅ `test_normalize_complex_addend_method_call` - Core normalization pattern
|
||||
- ✅ `test_normalize_simple_variable_unchanged` - No-op for simple patterns
|
||||
- ✅ `test_normalize_wrong_lhs_unchanged` - Reject invalid patterns
|
||||
- ✅ `test_normalize_no_multiplication_unchanged` - Reject non-accumulation patterns
|
||||
- ✅ `test_normalize_subtraction_complex_addend` - Subtraction variant
|
||||
|
||||
**Integration Tests** (regression verified):
|
||||
- ✅ `phase190_atoi_impl.hako` → 12 (no regression)
|
||||
- ✅ `phase190_parse_number_impl.hako` → 123 (no regression)
|
||||
- ✅ `phase191_body_local_atoi.hako` → 123 (no regression)
|
||||
- ✅ `phase192_normalization_demo.hako` → 123 (new demo test)
|
||||
|
||||
### 9.5 Current Limitations (Phase 193+ Work)
|
||||
|
||||
**Limitation**: Full E2E flow with MethodCall in temp variables requires extending `LoopBodyLocalInitLowerer` (Phase 186).
|
||||
|
||||
**Current Behavior**:
|
||||
```nyash
|
||||
local temp = digits.indexOf(ch) // ❌ Phase 186 error: "Unsupported init expression: method call"
|
||||
```
|
||||
|
||||
**Phase 186 Scope**: Only supports int/arithmetic operations (`+`, `-`, `*`, `/`, constants, variables)
|
||||
|
||||
**Future Work** (Phase 193+):
|
||||
- Extend `LoopBodyLocalInitLowerer::lower_init_expr()` to handle:
|
||||
- `ASTNode::MethodCall` (e.g., `digits.indexOf(ch)`)
|
||||
- `ASTNode::Call` (e.g., `parseInt(s)`)
|
||||
- Add emission logic for method call results in JoinIR
|
||||
- Add UpdateEnv resolution for method call temps
|
||||
|
||||
**Workaround**: For now, complex addend normalization works at the AST level, but lowering requires manual temp extraction outside the loop.
|
||||
|
||||
### 9.6 Design Principles Validated
|
||||
|
||||
✅ **箱化 (Box-First)**:
|
||||
- ComplexAddendNormalizer is a pure AST transformer (single responsibility)
|
||||
- No emission logic mixed in (delegation to existing Phase 191/190 infrastructure)
|
||||
|
||||
✅ **Fail-Fast**:
|
||||
- Unsupported patterns return `NormalizationResult::Unchanged`
|
||||
- Phase 186 limitation explicitly documented
|
||||
|
||||
✅ **Reusability**:
|
||||
- Normalizer works with any BinaryOp pattern (Add/Subtract)
|
||||
- Integration point is clean (10 lines in Pattern2)
|
||||
|
||||
✅ **Minimal Changes**:
|
||||
- Zero changes to emission layers (CarrierUpdateEmitter, LoopBodyLocalInitLowerer)
|
||||
- Only preprocessing added to Pattern2 (before carrier analysis)
|
||||
|
||||
### 9.7 Trace Output
|
||||
|
||||
When running a test with complex addend pattern:
|
||||
```
|
||||
[pattern2/phase192] Normalized complex addend: temp='temp_result_addend' inserted before update
|
||||
[cf_loop/pattern2] Phase 176-3: Analyzed 1 carrier updates
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Revision History
|
||||
|
||||
- **2025-12-09**: Initial design document (Section 1-8)
|
||||
- **2025-12-09**: Implementation complete (Section 9)
|
||||
|
||||
Reference in New Issue
Block a user