feat(joinir): Phase 183 LoopBodyLocal role separation

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>
This commit is contained in:
nyash-codex
2025-12-08 23:14:10 +09:00
parent 94bf00faf9
commit a3df5ecc7a
8 changed files with 586 additions and 9 deletions

View File

@ -294,6 +294,18 @@ Phase 181 で JsonParserBox 内の 11 ループを棚卸しした結果、
2. 文字列連結フィルタPhase 178
- `num_str = num_str + ch` のような string concat を保守的に reject
- JsonParser では必須の操作なので段階的に有効化が必要
- **Phase 183 で LoopBodyLocal 役割分離完了** ✅:
- **設計**: LoopBodyLocal を 2 カテゴリに分類:
- **Condition LoopBodyLocal**: ループ条件header/break/continueで使用 → Trim 昇格対象
- **Body-only LoopBodyLocal**: ループ本体のみで使用 → 昇格不要、pure local 扱い
- **実装**: TrimLoopLowerer に `is_var_used_in_condition()` ヘルパー追加
- 条件で使われていない LoopBodyLocal は Trim 昇格スキップ
- 5 つの unit test で変数検出ロジックを検証
- **テスト**: `apps/tests/phase183_body_only_loopbodylocal.hako` で動作確認
- `[TrimLoopLowerer] No LoopBodyLocal detected` トレース出力で body-only 判定成功
- **次の課題**: body-local 変数の MIR lowering 対応(`local temp` in loop body
- Phase 183 では "Trim promotion しない" 判定まで完了
- 実際の MIR 生成は Phase 184+ で対応予定
- 構造的に P1P4 で対応可能(代表例):
- `_parse_number` / `_atoi`P2 Break- Phase 182 でブロッカー特定済み
- `_match_literal`P1 Simple while- Phase 182 で動作確認済み ✅