Files
hakorune/docs/development/current/main/phases/phase-251/README.md

87 lines
3.6 KiB
Markdown
Raw Normal View History

feat(joinir): Phase 254-255 - Pattern 6 (ScanWithInit) + exit PHI DCE fix ## Phase 254: Pattern 6 (ScanWithInit) Detection & JoinIR Lowering Pattern 6 detects index_of/find/contains-style loops: - Loop condition: i < x.length() - Loop body: if with method call condition + early return - Step: i = i + 1 - Post-loop: return not-found value (-1) Key features: - Minimal lowering: main/loop_step/k_exit functions - substring hoisted to init-time BoxCall - Two k_exit jumps (found: i, not found: -1) - Tests: phase254_p0_index_of_min.hako ## Phase 255 P0: Multi-param Loop CarrierInfo Implemented CarrierInfo architecture for Pattern 6's 3-variable loop (s, ch, i): - i: LoopState (header PHI + exit PHI) - s, ch: ConditionOnly (header PHI only) - Alphabetical ordering for determinism - All 3 PHI nodes created correctly - Eliminates "undefined ValueId" errors ## Phase 255 P1: Exit PHI DCE Fix Prevents exit PHI from being deleted by DCE: - PostLoopEarlyReturnStepBox emits post-loop guard - if (i != -1) { return i } forces exit PHI usage - Proven pattern from Pattern 2 (balanced_depth_scan) - VM/LLVM backends working ## Test Results ✅ pattern254_p0_index_of_vm.sh: PASS (exit code 1) ✅ pattern254_p0_index_of_llvm_exe.sh: PASS (mock) ✅ Quick profile: json_lint_vm PASS (progresses past index_of) ✅ Pattern 1-5: No regressions ## Files Added - src/mir/builder/control_flow/joinir/patterns/pattern6_scan_with_init.rs - src/mir/join_ir/lowering/scan_with_init_minimal.rs - apps/tests/phase254_p0_index_of_min.hako - docs/development/current/main/phases/phase-254/README.md - docs/development/current/main/phases/phase-255/README.md 🧠 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 23:32:25 +09:00
Status: Active
Scope: Phase 251 (JoinIR 条件変数抽出の回帰修正 + 出力のクリーンアップ)
Related:
- docs/development/current/main/10-Now.md
- docs/reference/environment-variables.md
# Phase 251 Fix: json_lint_vm 回帰ConditionEnv 変数抽出 / 出力ノイズ)
## 目的
- 回帰の修正(`json_lint_vm``arr.length()` 等の基底変数が ConditionEnv に入らず落ちる)
- smoke 出力を壊す無条件ログ(`eprintln!`)の除去
## 実装(完了)
### 1) 条件変数抽出の拡張(核心)
ファイル:
- `src/mir/join_ir/lowering/condition_var_extractor.rs`
問題:
- 例: `loop (j < valid.length())``valid` が抽出されず、ConditionEnv で `Variable 'valid' not found` になる
原因:
- `collect_variables_recursive()``MethodCall` 等の複合式を辿れていなかった
対応:
- `collect_variables_recursive()` に以下の AST ノード処理を追加し、基底と引数側を再帰収集する
- `MethodCall`: `arr.length()` から `arr` を抽出(引数も再帰)
- `FieldAccess`: `obj.count` から `obj` を抽出
- `Index`: `arr[i]` から `arr``i` を抽出
- `Call`: callee と arguments を再帰(関数参照・引数の変数を拾う)
### 2) デバッグ出力のクリーンアップ
ファイル:
- `src/mir/join_ir/lowering/loop_with_if_phi_if_sum.rs`
問題:
- 無条件 `eprintln!` が quick smoke の期待出力を壊す
対応:
- `crate::config::env::is_joinir_debug()` ガードで条件付き出力に変更
- 推奨 env: `HAKO_JOINIR_DEBUG=1``NYASH_JOINIR_DEBUG` は legacy
### 3) ユニットテスト追加
ファイル:
- `src/mir/join_ir/lowering/condition_var_extractor.rs`
追加:
- `MethodCall/FieldAccess/Index` などの変数抽出が期待通りであることを固定(回帰防止)
## 検証Phase 251 の範囲)
- 元の回帰(`arr.length()``arr` が ConditionEnv に入らない): 解決
- `--profile quick``json_lint_vm`: 別件の失敗が露出Phase 251 対象外)
## 残タスク(次の指示書 / Phase 252 案)
### 現象
- JoinIR Pattern2 の break 条件 lowering が `MethodCall` を扱えず失敗する
- 例: `Me.is_whitespace(s.substring(i, i + 1))` のような `MethodCall` を含む条件
### 指示Claude 実装用)
1. 再現コマンド
- `./tools/smokes/v2/run.sh --profile quick`
- 追加ログが必要なら `HAKO_JOINIR_DEBUG=1`smoke 期待出力に混ざるため、比較用の runs では OFF にする)
2. 構造的な修正方針
- 「条件 lowering 専用の箱」側で `ASTNode::MethodCall`(必要なら `Me` / `Call` / `FieldAccess` / `Index`)を fail-fast で受理できるようにする
- 実装は 2 ルートのどちらかに統一する
- A) 条件式を事前に式 loweringANF を含む)で `ValueId` に落としてから branch 用の bool 値として扱う
- B) 受理範囲を明確化し、MethodCall を KnownIntrinsic に限定して lowering逸脱はエラー
3. ドキュメントとテスト(コードの前)
- `condition_lowering_box` の責務(受理する AST の境界)を README / doc comment で明文化
- `MethodCall` を含む break 条件を最小 fixture で固定し、v2 smoke に追加quick 既定に入れるかは要検討)
4. 受け入れ基準
- `./tools/smokes/v2/run.sh --profile quick` が緑
- デフォルトで出力が汚れない(`HAKO_JOINIR_DEBUG=1` の時だけ追加ログ)
- by-name や特定関数名での分岐など、対処療法的ハードコードを追加しない