From 935d475882b4b1d572b9d3b895c78cf27323eff8 Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Wed, 17 Dec 2025 17:39:12 +0900 Subject: [PATCH] docs: Phase 103 plan (if-only parity baseline) --- .../current/main/01-JoinIR-Selfhost-INDEX.md | 2 + docs/development/current/main/10-Now.md | 11 ++- docs/development/current/main/30-Backlog.md | 18 +++-- .../development/current/main/phases/README.md | 5 +- .../current/main/phases/phase-103/README.md | 69 +++++++++++++++++++ 5 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 docs/development/current/main/phases/phase-103/README.md diff --git a/docs/development/current/main/01-JoinIR-Selfhost-INDEX.md b/docs/development/current/main/01-JoinIR-Selfhost-INDEX.md index 4a046ce5..8fea0f20 100644 --- a/docs/development/current/main/01-JoinIR-Selfhost-INDEX.md +++ b/docs/development/current/main/01-JoinIR-Selfhost-INDEX.md @@ -59,6 +59,8 @@ JoinIR の箱構造と責務、ループ/if の lowering パターンを把握 - `docs/development/current/main/phases/phase-100/README.md` 13. Phase 102: real-app read_quoted loop regression(VM + LLVM EXE) - `docs/development/current/main/phases/phase-102/README.md` +14. Phase 103: if-only regression baseline(VM + LLVM EXE / plan) + - `docs/development/current/main/phases/phase-103/README.md` 6. MIR Builder(Context 分割の入口) - `src/mir/builder/README.md` 7. Scope/BindingId(shadowing・束縛同一性の段階移行) diff --git a/docs/development/current/main/10-Now.md b/docs/development/current/main/10-Now.md index 1c709bdc..7fbd1acb 100644 --- a/docs/development/current/main/10-Now.md +++ b/docs/development/current/main/10-Now.md @@ -1,5 +1,11 @@ # Self Current Task — Now (main) +## 2025-12-17:Phase 100 P3 完了 ✅ + +**Phase 100 P3: String Accumulator Captures** +- String accumulator(`out = out + ch`)を最小形で固定し、VM/LLVM EXE parity を smoke で検証 +- LLVM EXE 側の stringish 伝播(PHI/copy/binop)を修正し、concat の意味論を安定化 + ## 2025-12-17:Phase 100 P2 完了 ✅ **Phase 100 P2: Mutable Accumulator Captures** @@ -23,9 +29,8 @@ - escape 末尾バックスラッシュを best-effort として固定(`hello\` そのまま出力) - VM+LLVM EXE parity 完全対応、integration smoke で検証済み -Next(設計メモ): -- Phase 100: Pinned Read‑Only Captures(ループ外 local を loop 内 receiver として解決): `docs/development/current/main/phases/phase-100/README.md` - - 段階投入: P1=read‑only(Pinned)→ P2=mutable は LoopState(carrier/env)へ +関連(設計/実装の入口): +- Phase 100: `docs/development/current/main/phases/phase-100/README.md` ## 2025‑12‑15:Phase 132 完了 ✅ diff --git a/docs/development/current/main/30-Backlog.md b/docs/development/current/main/30-Backlog.md index 3ead0df0..e59ad3ad 100644 --- a/docs/development/current/main/30-Backlog.md +++ b/docs/development/current/main/30-Backlog.md @@ -8,13 +8,19 @@ Related: ## 直近(JoinIR/selfhost) +- **Phase 103: if-only regression baseline(VM + LLVM EXE)** + - ねらい: loop が無い `if`(merge/return を含む)を VM/LLVM EXE parity で固定し、ループ系の回帰を早期検知する。 + - 入口: `docs/development/current/main/phases/phase-103/README.md` + +- **real-app loop regression の横展開(VM + LLVM EXE)** + - ねらい: 実コード由来ループを 1 本ずつ最小抽出して fixture/smoke で固定する(段階投入)。 + - 現状: Phase 102(read_quoted)まで固定済み。 + - 次候補: `parse_object` / `parse_array` の key/value ループ、read_digits 系。 + - 入口: `docs/development/current/main/phases/phase-102/README.md` + - **P5b “完全E2E”**(escape skip の実ループを end-to-end で固定) - 現状: Phase 94 で VM E2E まで固定済み。次は selfhost 実コード(`apps/selfhost-vm/json_loader.hako`)へ横展開して回帰を減らす。 - 入口: `docs/development/current/main/phases/phase-94/README.md` -- **Pinned Read‑Only Captures(Phase 100)** - - ねらい: loop 外 local(動的式でも可)を loop 内 receiver として解決できるようにする(`receiver not found` を潰す)。 - - 段階投入: P1=read‑only(Pinned)→ P2=mutable は LoopState(carrier/env)へ昇格。 - - 入口: `docs/development/current/main/phases/phase-100/README.md` - **制御の再帰合成(docs-only → dev-only段階投入)** - ねらい: `loop/if` ネストの “構造” を SSOT(ControlTree/StepTree)で表せるようにする - 注意: canonicalizer は観測/構造SSOTまで(ValueId/PHI配線は Normalized 側へ) @@ -22,6 +28,10 @@ Related: ## 中期(ループ在庫の残り) +- **loop(true) + break-only(digit scan など)** + - ねらい: bounded ではない実ループを段階的に飲み込む(fixture + shape guard + Fail-Fast)。 + - 方針: “新パターン増殖”よりも Pattern5 系(infinite loop family)として扱う設計を先に固める。 + - **P5(guard-bounded)**: 大型ループを “小粒度” に割ってから取り込む(分割 or 新契約) - **P6(nested loops)**: capability guard で Fail-Fast 維持しつつ、解禁時の契約を先に固定 diff --git a/docs/development/current/main/phases/README.md b/docs/development/current/main/phases/README.md index 63c5b919..5d4d77a9 100644 --- a/docs/development/current/main/phases/README.md +++ b/docs/development/current/main/phases/README.md @@ -11,6 +11,9 @@ - **Phase 136**: MirBuilder Context SSOT 化(+ ValueId allocator 掃討) - **Phase 137–141**: Loop Canonicalizer(前処理 SSOT)導入(Phase 137 フォルダに統合して記録) - **Phase 91–92**: Selfhost depth‑2 coverage(P5b escape recognition → lowering) +- **Phase 94–100**: P5b escape E2E / Trim policy / pinned + accumulator(VM/LLVM EXE parity) +- **Phase 102**: real-app read_quoted loop regression(VM + LLVM EXE) +- **Phase 103**: if-only regression baseline(VM + LLVM EXE / plan) ## Phase フォルダ構成(推奨) @@ -46,4 +49,4 @@ phases/phase-131/ --- -**最終更新**: 2025-12-15 +**最終更新**: 2025-12-17 diff --git a/docs/development/current/main/phases/phase-103/README.md b/docs/development/current/main/phases/phase-103/README.md new file mode 100644 index 00000000..b3ca36a6 --- /dev/null +++ b/docs/development/current/main/phases/phase-103/README.md @@ -0,0 +1,69 @@ +# 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 を広げる。 +