feat(joinir): Phase 286 P3.2 - Pattern5 Plan line (loop(true) + early exit)

- Pattern5InfiniteEarlyExitPlan (Return/Break variants)
- extract_pattern5_plan() for loop(true) literal only
- normalize_pattern5_return(): 5 blocks CFG (header→body→found/step)
- normalize_pattern5_break(): 6 blocks CFG with carrier PHI
- NormalizationPlanBox exclusion for Pattern5-style loops
- Fixtures: phase286_pattern5_{return,break}_min.hako
- quick smoke 154/154 PASS

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-26 09:56:34 +09:00
parent ec55cce380
commit 22945c190c
12 changed files with 963 additions and 16 deletions

View File

@ -1,8 +1,8 @@
# Self Current Task — Now (main)
## Current Focus: Phase 286 P2.7 (Plan line guardrails)
## Current Focus: Phase 284 P0 (design-first) / Post Phase 286
Pattern3 まで Plan line で完走し、legacy fallback を撤去できた。次は「同じ落とし穴を二度踏まない」ため、Plan/LoopPlan の契約(例: body ブロックの effect 配置をドキュメント・verify で固定していく
Phase 286 で JoinIR line の主要 pattern19が Plan/Frag SSOT に吸収できた。次は “出口語彙” をさらに SSOT に寄せるため、Phase 284Return as ExitKind SSOTへ進む
設計相談(将来の正規化):
- `docs/development/current/main/investigations/phase-286-plan-normalization-consult.md`
@ -23,11 +23,11 @@ Pattern3 まで Plan line で完走し、legacy fallback を撤去できた。
- quick smoke 154/154 PASS 維持、Pattern1/4 PoC 両方 PASS
**次のステップ**:
1. **Phase 286 P2.7** (current): Plan line guardrailsverify / doc
- 例: CoreLoopPlan の “body effects は loop_plan.body に積む” 契約を Fail-Fast で固定
2. **Phase 286future design, separate phase**: Plan 生成の正規化をどう進めるか(相談パケット)
1. **Phase 284design-first**: Return as ExitKind SSOTpattern に散らさない
2. **future designseparate phase**: Plan 生成の正規化をどう進めるか(相談パケット)
- `docs/development/current/main/investigations/phase-286-plan-normalization-consult.md`
3. **Phase 284** (design-first): Return as ExitKind SSOT
3. optional, post self-hostREPL = script engine 構想docs-only
- `docs/reference/language/repl.md`
## Recently Completed

View File

@ -59,13 +59,12 @@ Related:
- 既存の `apps/tests/*.hako` fixture を再利用し、VM/LLVM parity のスモークが維持される。
- weak の語彙(`weak <expr>` / `weak_to_strong()`が同じ意味で動作するcycleは当面リーク仕様でも可
- **Phase 286planned, design-first: JoinIR Line AbsorptionJoinIR→CorePlan/Frag 収束)**
- **Phase 286✅ complete: JoinIR Line AbsorptionJoinIR→CorePlan/Frag 収束)**
- 目的: 移行期間に残っている「2本の loweringPlan line / JoinIR line」を、構造で 1 本に収束させる
- ねらい: `return/break/continue` のような “大きな出口語彙” の実装場所が揺れない状態にする
- 入口: `docs/development/current/main/phases/phase-286/README.md`
- P0docs-only: `docs/development/current/main/phases/phase-286/P0-INSTRUCTIONS.md`
- 状況: P2Pattern4/P2.1Pattern1/P2.2hygiene/P2.3Pattern9/P2.4.1Pattern8 Plan完走まで完了。現在は P2.6Pattern3 Plan化進行中
- 次の実装指示Pattern3完走: `docs/development/current/main/phases/phase-286/P2.6.1-INSTRUCTIONS.md`
- 状況: Pattern19 の主要ループ形が Plan/Frag SSOT に吸収され、quick gate は green を維持
- 将来の設計相談Phase 286 の範囲外で、別フェーズでSSOT化してから: `docs/development/current/main/investigations/phase-286-plan-normalization-consult.md`
- SSOT:
- Plan/Frag: `compose::*` + `emit_frag()`Phase 280/281

View File

@ -1,6 +1,6 @@
# Phase 286: JoinIR Line AbsorptionJoinIR→CorePlan/Frag 収束)
Status: In Progress (P0, P1, P2, P2.1, P2.2, P2.3, P2.4, P2.4.1, P2.6, P2.7, P3, 286C-2, **P3.1 COMPLETE**)
Status: ✅ COMPLETE (P0, P1, P2, P2.1, P2.2, P2.3, P2.4.1, P2.6, P2.7, P2.8, P3.1, P3.2, P3 COMPLETE)
## Goal
@ -38,8 +38,22 @@ Phase 286 では JoinIR line を “第2の lowerer” として放置せず、*
## Next短期の道筋
- **P2.6.1Pattern3 Plan完走**: `docs/development/current/main/phases/phase-286/P2.6.1-INSTRUCTIONS.md`
- **将来設計の相談別フェーズでSSOT化してから**: `docs/development/current/main/investigations/phase-286-plan-normalization-consult.md`
- **次のおすすめdesign-first**: Phase 284Return as ExitKind SSOT
## Coverage MapPlan line 移行状況)
| Pattern | Shape | Status | Notes |
|---:|---|---|---|
| 1 | SimpleWhile | ✅ Plan line | PoC + integration fixture固定済み |
| 2 | Break | ✅ Plan line | PoCサブセットは Plan 完走、PoC外は `Ok(None)` で legacy fallback |
| 3 | If-Phi | ✅ Plan line | Fail-Fast 統一extract `Some` 後の legacy fallback なし) |
| 4 | Continue | ✅ Plan line | PoC + integration fixture固定済み |
| 5 | InfiniteEarlyExit | ✅ Plan line | `loop(true)` literal に限定した PoC サブセットReturn/Break |
| 6 | ScanWithInit | ✅ Plan line | Phase 273 で SSOT |
| 7 | SplitScan | ✅ Plan line | Phase 273 で SSOT |
| 8 | BoolPredicateScan | ✅ Plan line | static box は設計上スキップReceiverNormalizeBox が担当) |
| 9 | AccumConstLoop | ✅ Plan line | Pattern1 より優先(より具体的) |
### P0docs-only✅ COMPLETE (2025-12-25)
@ -380,6 +394,67 @@ preheader → header(PHI: i_current, carrier_current)
- ✅ Fixture B (break without update): Plan line PASS (出力 11)
- ✅ Regression: quick smoke 154 PASS, 0 FAILED
### P3.2 (Pattern5 Plan化 - Infinite Loop with Early Exit) ✅ COMPLETE (2025-12-26)
**完了内容**:
- Pattern5InfiniteEarlyExitPlan 追加Return版・Break版両対応
- extract_pattern5_plan() 実装loop(true) リテラル限定)
- normalize_pattern5_infinite_early_exit() 実装Return版5blocks、Break版6blocks CFG
- NormalizationPlanBox で Pattern5 スタイルループを除外Plan line へルーティング)
- quick smoke 154/154 PASS
**背景**:
- Pattern5 は `loop(true)` の無限ループパターン
- 既存 legacy Pattern5 は `break + continue` 両方必須の複雑な形式
- PoC は **simpler subset**: 早期 return または break 単独
**CFG構造Return版**:
```
preheader → header(PHI: i_current) → body(exit_cond)
↑ ↓
└───── step ←──────── else path
then path: CoreExitPlan::Return
```
**CFG構造Break版**:
```
preheader → header(PHI: i, carrier) → body(exit_cond)
↑ ↓
└───── step ←────────── else path
then path → after_bb(PHI: carrier_out)
```
**実装ステップ**:
1. Step 0: docs-first - README P3.2節追加
2. Step 1: integration fixture 2本 (return版、break版)
3. Step 2: DomainPlan::Pattern5InfiniteEarlyExit 追加
4. Step 3: extract_pattern5_plan() 実装
5. Step 4: normalize_pattern5_infinite_early_exit() 実装
6. Step 5: router に Pattern5 追加
7. Step 6: 検証
**PoC サブセット厳守**:
- `loop(true)` リテラルのみ(`loop(1)` や truthy は `Ok(None)`
- Return版: `if (cond) { return <expr> }` + `i = i + 1`
- Break版: `if (cond) { break }` + `sum = sum + 1` + `i = i + 1`carrier_update 必須)
**成果物** (予定):
- `apps/tests/phase286_pattern5_return_min.hako` (Fixture A)
- `apps/tests/phase286_pattern5_break_min.hako` (Fixture B)
- `tools/smokes/v2/profiles/integration/apps/phase286_pattern5_return_vm.sh`
- `tools/smokes/v2/profiles/integration/apps/phase286_pattern5_break_vm.sh`
- `src/mir/builder/control_flow/plan/mod.rs` (Pattern5InfiniteEarlyExitPlan + Pattern5ExitKind)
- `src/mir/builder/control_flow/joinir/patterns/extractors/pattern5.rs` (extract_pattern5_plan)
- `src/mir/builder/control_flow/plan/normalizer.rs` (normalize_pattern5_infinite_early_exit)
- `src/mir/builder/control_flow/joinir/patterns/router.rs` (Pattern5 Plan line routing)
**成功基準**:
- Fixture A (return): PASS (出力 7)
- Fixture B (break): PASS (出力 3)
- Regression: quick smoke 154 PASS, 0 FAILED
## AcceptanceP0
- 2本の lowering が "設計として" どこで 1 本に収束するかが明文化されている