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>