# Phase 25.1q — LoopForm Front Unification (AST / JSON v0) Status: planning-only(Phase 25.1 ラインの安定化が終わったあとに着手) ## ゴール - ループ lowering / PHI 構築の **SSOT を `phi_core + LoopFormBuilder` に完全に寄せる**。 - Rust AST → MIR(`MirBuilder` / `LoopBuilder`)と JSON v0 → MIR(`json_v0_bridge::lower_loop_stmt`)のフロントを整理し、 「どこを直せば loop/PHI の意味論が変わるか」を 1 箇所に明示する。 - 実装者・LLM の混乱ポイントを減らす: - Stage‑B / FuncScanner のようなループバグ調査時に、「Rust AST 側を触るべきか」「JSON v0 側を触るべきか」で迷わない構造にする。 - 今回のように `loop_.rs` 側だけにログ・修正を入れてしまう誤りを防ぐ。 ## 現状(25.1m / 25.1p 時点の構造) - **バックエンド(SSOT)** - `src/mir/phi_core/loop_phi.rs` / `src/mir/phi_core/loopform_builder.rs` - LoopForm v2 / LoopSSA v2 の本体。 - `LoopFormBuilder` + `LoopFormOps` として、ヘッダ PHI / exit PHI / continue スナップショットなどを一元的に扱う。 - **Rust AST → MIR 経路** - `ASTNode::Loop` - `src/mir/builder_modularized/control_flow.rs::build_loop_statement` - `src/mir/builder/control_flow.rs::cf_loop` - `src/mir/loop_builder.rs::LoopBuilder::build_loop_with_loopform` - こちらはすでに LoopForm v2 / ControlForm v2 に統一済みで、「Rust パーサで読んだ .hako」を MIR に落とす主経路。 - **JSON v0 → MIR 経路** - `Program(JSON v0)`(`ProgramV0`): - `src/runner/json_v0_bridge/lowering.rs::lower_stmt_with_vars` - `StmtV0::Loop { .. } => loop_::lower_loop_stmt(...)` - `src/runner/json_v0_bridge/lowering/loop_.rs::lower_loop_stmt` - ここも LoopForm v2 / phi_core を呼ぶ構造にはなっているが、 - ファイルが AST ルートとは別に分かれている - 追加ログや一時的なデバッグコードが入りやすく、「どの経路でループが下りているか」分かりづらい状態になりがち。 - 結果として: - Stage‑B / FuncScannerBox のような「Rust AST 経路」を見たいときに、誤って `loop_.rs` 側だけを触る、といった混乱が起きやすい。 - 一方で JSON v0 経路は provider (`env.mirbuilder.emit` / `--program-json-to-mir`) で重要なので、急に削除はできない。 ## スコープ(25.1q でやること) 1. **LoopForm / phi_core を SSOT として明文化(ドキュメント整理)** - `docs/development/roadmap/phases/phase-25.1b/` / `phase-25.1m/` / 本 `phase-25.1q` で: - ループ意味論(preheader/header/body/latch/exit、continue/break スナップショット、PHI)の SSOT を `phi_core::loop_phi` / `LoopFormBuilder` に一本化すると明言する。 - `LoopBuilder`(Rust AST フロント)と `json_v0_bridge::lower_loop_stmt`(JSON フロント)は「薄いアダプタ」に留める方針を書いておく。 2. **json_v0_bridge::lower_loop_stmt の責務縮小(薄いフロント化)** - 目標: `loop_.rs` は「JSON から LoopForm に渡すための最低限の橋渡し」に限定する。 - 具体案: - 余計なデバッグログや独自判定を段階的に削り、やることを - preheader/header/body/latch/exit のブロック ID を用意する - ループ開始時点の `vars` を LoopPhiOps 実装に渡す - break / continue のスナップショット記録を呼び出す に絞る。 - ループ構造・PHI の仕様変更は **phi_core 側だけ** に集約し、`loop_.rs` 側には分岐や条件を増やさない。 3. **ログ・デバッグ経路の整理** - `HAKO_LOOP_PHI_TRACE` / `NYASH_LOOPFORM_DEBUG` などのトグルについて: - どのフロント(Rust AST / JSON)からでも同じタグで観測できるようにし、ログの出し場所を整理する。 - `loop_.rs` に残っている「一時的な ALWAYS LOG」などはすでに削除済みだが、今後も dev トレースは必ず env ガード越しに行う。 4. **JSON v0 → AST → MirBuilder 統合の検討(設計レベルのみ)** - 将来案として: - `ProgramV0` を一度 Nyash AST 相当の構造体に変換し、`MirBuilder` の `build_loop_statement` を再利用する形に寄せる。 - これが実現すると、`loop_.rs` 自体を削除しても LoopForm/PHI の意味論は完全に一箇所(LoopBuilder + phi_core)に集約される。 - 25.1q ではここまでは踏み込まず、「やるならどのフェーズで、どの単位の差分にするか」を設計メモとして残す。 ## スコープ外(25.1q ではやらないこと) - ループ意味論そのものの変更: - `loop(cond){...}` の評価順序や break/continue の意味論を変えない。 - Stage‑B / Stage‑1 / 自己ホストルートで既に green な LoopForm/SSA テストの挙動は不変とする。 - 新しいループ構文・最適化の追加: - `while` / `for` / range loop など、新構文の導入は別フェーズ(言語拡張側)に任せる。 - JSON v0 スキーマの変更: - `StmtV0::Loop` などの JSON 形は既存のまま(schema v0/v1 は維持)。 ## 他フェーズとの関係 - 25.1m(Static Method / LoopForm v2 continue + PHI Fix): - ここで LoopForm v2 / continue + header PHI は Rust AST 経路でほぼ安定している。 - 25.1q では、その成果を JSON v0 経路にも構造的に反映し、「LoopForm v2 がどこから使われているか」を明示する役割を担う。 - 25.1p(MIR DebugLog 命令): - DebugLog を使って LoopForm/PHI の ValueId を観測しやすくすることで、25.1q での統一作業時に「AST ルートと JSON ルートの差」を追いやすくする。 - 25.1q は DebugLog 基盤が整っていることを前提に、小さな JSON v0 → MIR のテストケースで CFG/PHI を比較するフェーズとする。 - 25.2(Numeric Microbench / EXE Tuning): - JSON v0 → MIR → EXE 経路は numeric_core / AotPrep と強く結びついているため、25.1q で LoopForm front を整理しておくと、25.2 でのパフォーマンス解析やバグ調査がやりやすくなる。***