# Phase 188.3: Nested loop lowering (1-level) — make Pattern 6 real **Date**: TBD **Status**: Planning (docs-first) **Prereq**: Phase 188.2 Option A is complete (StepTree depth SSOT + strict Fail-Fast) --- ## Goal `max_loop_depth == 2`(1-level nested loop)を **JoinIR lowering で実際に通す**。 - 既知の事実: `LoopForm (=LoopShape)` にはネスト情報が無いので、**LoopFormベースの Pattern6 検出/ルーティングでは実装できない** - 実装は **StepTree(AST側)**を SSOT として扱う(Phase 188.2 Option A を継続) --- ## Scope (minimal) 対応するのは “NestedLoop Minimal” の 1形だけに限定する。 - depth: `max_loop_depth == 2` のみ - inner loop: Pattern1相当(break/continue 無し) - outer loop: Pattern1相当(break/continue 無し)を優先 - それ以外: - strict mode: 明示エラー(Phase 188.2 の depth check とは別タグで良い) - non-strict mode: 既存の fallback 経路に任せる(ただし silent fallback を増やさない) --- ## SSOT (what to rely on) - nesting depth SSOT: `StepTreeFeatures.max_loop_depth` - depth > 2: strict mode で `control_tree/nested_loop/depth_exceeded`(Phase 188.2) --- ## Scope & Variable Model (SSOT) Nyash の変数スコープ方針に合わせて、nested loop lowering でも以下を SSOT として固定する。 ### Visibility (read) - inner loop から outer の binding は参照できる(lexical scope: “1つ上は見える”) - ただし JoinIR lowering では「見える」を **明示的な引数/継続で表現**する(暗黙キャプチャを増やさない) ### Mutation (write-back) Phase 188.3 では段階的に進める: - **P188.3 (minimal)**: outer 変数の **read-only capture** を許す(inner から outer を読む) - **P188.4+ (generalize)**: outer 変数の **write-back** を対応する(inner で outer に代入した値を `k_inner_exit(...)` で戻す) この分離により、PHI/exit binding の複雑さを Phase 188.3 に持ち込まずに済む。 --- ## Lowering sketch (how it should look) Nested loop は JoinIR の「tail recursion + continuation」を再帰的に合成して表現する。 - outer: `outer_step(state..., k_outer_exit)` - inner: `inner_step(state..., k_inner_exit)` - inner が終わったら `k_inner_exit(...)` で outer の“残り”へ戻る この `k_inner_exit` がスコープ境界として働くので、将来の write-back もここに集約できる。 --- ## Deliverables 1. **Fixture + integration smoke(exit code SSOT)** - 1-level nested loop を最小で再現する `.hako` を追加 - integration で実行し、exit code で判定(stdout比較はしない) 2. **StepTree-based lowering implementation** - StepTree を辿って、inner loop を outer loop の中で正しく lowering できるようにする - 入口は “StepTree→JoinIR” のどこか(LoopFormベースの router は使わない) 3. **Docs update** - Phase 188.1 の “Pattern6 specification” が design であることは維持 - Phase 188.3 で “実装済み/未実装の境界” を明確に書く --- ## Acceptance Criteria - `./tools/smokes/v2/run.sh --profile quick` が常にグリーン維持 - integration selfhost が FAIL=0 を維持 - 追加した nested loop fixture が PASS(JoinIR lowering が使われたことをログ/タグで確認可能) --- ## Next (schedule) - **Phase 188.3**: depth=2 の最小形を “確実に通す” + PoC fixture を smoke 固定 - **Phase 188.4+**: write-back(outer carrier reconnection)と “再帰 lowering の一般化(depthを増やしても壊れない)” を docs-first で設計してから実装 --- ## Out of Scope - nested loop + break/continue の一般対応 - LoopRegion を使った MIR-level nesting SSOT(Option B)