Implements role-based separation of LoopBodyLocal variables to prevent inappropriate Trim promotion for body-only local variables. ## Changes ### Task 183-1: Design Documentation - Created `phase183-loopbodylocal-role-separation.md` with role taxonomy: - Condition LoopBodyLocal: Used in loop conditions → Trim promotion target - Body-only LoopBodyLocal: Only in body → No promotion needed - Documented architectural approach and implementation strategy ### Task 183-2: Implementation - Added `TrimLoopLowerer::is_var_used_in_condition()` helper - Recursively checks if variable appears in condition AST - Handles BinaryOp, UnaryOp, MethodCall node types - Updated `try_lower_trim_like_loop()` to filter condition LoopBodyLocal - Only processes LoopBodyLocal that appear in break conditions - Skips body-only LoopBodyLocal (returns Ok(None) early) - Added 5 unit tests for variable detection logic ### Task 183-3: Test Files - Created `phase183_body_only_loopbodylocal.hako` - Demonstrates body-only LoopBodyLocal (`temp`) not triggering Trim - Verified trace output: "No LoopBodyLocal detected, skipping Trim lowering" - Created additional test files (phase183_p1_match_literal, phase183_p2_atoi, phase183_p2_parse_number) ### Task 183-4: Documentation Updates - Updated `joinir-architecture-overview.md` with Phase 183 results - Updated `CURRENT_TASK.md` with Phase 183 completion status ## Results ✅ LoopBodyLocal role separation complete ✅ Body-only LoopBodyLocal skips Trim promotion ✅ 5 unit tests passing ✅ Trace verification successful ## Next Steps (Phase 184+) - Body-local variable MIR lowering support - String concatenation filter relaxation - Full _parse_number/_atoi implementation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
37 lines
880 B
Plaintext
37 lines
880 B
Plaintext
// Phase 183-3: Demonstrate body-only LoopBodyLocal (doesn't trigger Trim)
|
|
// Goal: Show that LoopBodyLocal used only in body, not in conditions,
|
|
// doesn't trigger Trim lowering
|
|
|
|
static box Main {
|
|
main(args) {
|
|
// Pattern 2 with body-only LoopBodyLocal
|
|
local result = 0
|
|
local i = 0
|
|
|
|
loop(i < 5) {
|
|
// Body-only LoopBodyLocal: temp is computed but never appears in any condition
|
|
local temp = i * 2
|
|
|
|
// Break condition doesn't use temp - only uses outer variable i
|
|
if i == 3 {
|
|
break
|
|
}
|
|
|
|
result = result + temp
|
|
i = i + 1
|
|
}
|
|
|
|
// Expected: result = 0*2 + 1*2 + 2*2 = 0 + 2 + 4 = 6
|
|
// i should be 3 (broke at 3)
|
|
if result == 6 {
|
|
if i == 3 {
|
|
print("PASS: Body-only LoopBodyLocal accepted (no Trim)")
|
|
return 0
|
|
}
|
|
}
|
|
|
|
print("FAIL: result or i incorrect")
|
|
return 1
|
|
}
|
|
}
|