# Phase 103: if-only regression baseline(VM + LLVM EXE) Status: Active Scope: loop を含まない `if` の lowering/merge を、VM と LLVM EXE で同一出力に固定する。 Related: - 入口: `docs/development/current/main/10-Now.md` - 地図: `docs/development/current/main/design/joinir-design-map.md` - 既存の LLVM EXE smoke / plugin gating: `docs/development/current/main/phases/phase-97/README.md` ## 目的 - 「loop が無い `if`」でも JoinIR 経路(if lowering + merge)が壊れないことを、**VM/LLVM EXE parity** で固定する。 - ループ系の変更(Pattern2/4/derived/pinned/mutable accumulator)の回帰を、if-only で早期検知できるようにする。 - CI は最小のまま(`tools/smokes/v2` の `integration` にのみ追加)。 ## P0: Fixture + integration smokes(最小) ### 1) fixture - 追加: `apps/tests/phase103_if_only_merge_min.hako` - 要件: - `if { ... } else { ... }` で同一変数へ代入し、merge(PHI 相当)が必要になる形にする。 - nested if を 1 段だけ入れて「if の中の if」も踏む。 - 出力は **数値 1 行**(例: `2`)に固定(exit code には依存しない)。 ### 2) VM smoke - 追加: `tools/smokes/v2/profiles/integration/apps/phase103_if_only_vm.sh` - 実行: - `HAKO_JOINIR_STRICT=1 ./target/release/hakorune --backend vm apps/tests/phase103_if_only_merge_min.hako` - 先頭 `[` のデバッグ行は除外して数値行のみを比較する(Phase 97 方式)。 - 受け入れ: - stdout の数値行が `2` と一致。 ### 3) LLVM EXE smoke - 追加: `tools/smokes/v2/profiles/integration/apps/phase103_if_only_llvm_exe.sh` - 方針: - Phase 97/98 と同様に、必要 plugin の `.so` を `ctypes.CDLL` で確認し、必要時のみ `tools/plugins/build-all.sh` を実行。 - `tools/build_llvm.sh` で exe を生成して実行し、数値行のみを比較する。 - 受け入れ: - stdout の数値行が `2` と一致。 ## 受け入れ基準(P0) - `bash tools/smokes/v2/profiles/integration/apps/phase103_if_only_vm.sh` が PASS - `bash tools/smokes/v2/profiles/integration/apps/phase103_if_only_llvm_exe.sh` が PASS(前提不足は SKIP) - 回帰確認: - `bash tools/smokes/v2/profiles/integration/apps/phase94_p5b_escape_e2e.sh` が PASS - `bash tools/smokes/v2/profiles/integration/apps/phase97_next_non_ws_llvm_exe.sh` が PASS(前提不足は SKIP) - 新しい環境変数は追加しない(既存の `HAKO_JOINIR_STRICT` などで制御)。 ## P1(任意): if-only early return if 文の then/else 内で return する形(merge 不要 or merge 途中で return)を 1 本追加して、Boundary/ExitLine の退行を拾いやすくする。 ## Next(別フェーズ候補) ### loop(true) + break-only(digit scan など) 現状の Pattern 群では、`loop(true)` で **continue なし / break 複数**の実ループが取りこぼされやすい。 - 実在例: - `apps/libs/json_cur.hako:29`(`read_digits_from`) - `apps/selfhost-vm/json_loader.hako:25`(`read_digits_from`) - 進め方(箱理論): - “新パターン増殖” ではなく、**Pattern5 系(infinite loop family)**として扱う方針を先に決める。 - まずは fixture + shape guard + Fail-Fast で段階投入し、VM/LLVM parity を固めてから lowering を広げる。