feat(normalization): Phase 142 P0 - Loop statement-level normalization

Phase 142-loopstmt P0: Statement-level normalization

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-19 05:28:49 +09:00
parent 275fe45ba4
commit 4082abb30c
23 changed files with 1610 additions and 246 deletions

View File

@ -0,0 +1,96 @@
# Phase 143-loopvocab: StepTree Vocabulary Expansion (loop → if/break/continue)
Status: planned
Scope: Normalized shadow / JoinIRdev-only, default behavior unchanged
Related (SSOT):
- `docs/development/current/main/design/control-tree.md`
- `docs/development/current/main/design/normalized-expr-lowering.md`
- `docs/development/current/main/phases/phase-142-loopstmt/README.md`
---
## Goal
`loop(true){ if(cond) break/continue }` を「新パターン追加」ではなく、**StepTree/ControlTree の語彙vocabulary拡張**として表現し、同じ Normalized loweringenv + continuationに流す。
つまり、suffix/fixture の形を増やすのではなく:
- **制御は構造StepTree**
- **値は一般化ExprLowererBox**
で吸収する。
## Non-Goals
- `loop(<cond>)`(条件付き loopを Normalized に入れる(既存経路へフォールバック維持)
- impure expressionCall/MethodCall general caseを増やすPhase 141 P2+ で扱う)
- 既定挙動変更out-of-scope は `Ok(None)` でフォールバック)
---
## P0 (planned): If-in-loop (single if, break/continue only)
### Accepted surface syntax (fixtures)
1) break:
```hako
loop(true) {
if (cond) { break }
}
```
2) continue:
```hako
loop(true) {
if (cond) { continue }
}
```
### StepTree vocabulary (existing)
StepTree は既に `StepNode::Loop` / `StepNode::If` / `StepStmtKind::{Break,Continue}` を持っている。
P0 の焦点は **Normalized lowering が Loop-body 内の If を受けられるようにする**こと。
### Capability / contract (Fail-Fast boundary)
- P0 で許可するのは「Loop-body の先頭/末尾に 1 個の Ifelse無しでも可で、その then/else が Break/Continue のみ」まで。
- それ以外(ネスト if、複数 if、then に Assign など)は out-of-scope (`Ok(None)`) にして既存経路へフォールバック。
- strict/dev では `OutOfScopeReason` を必ず出すsilent accept 禁止)。
### Implementation sketch (boxes)
- `NormalizationPlanBox`:
- `loop(true)` を見たら `loop_only(consumed=1)`Phase 142-loopstmt と同じ)
- 追加で「Loop-body が If を含むか」を feature として観測plan の枝分かれは最小)
- `NormalizationExecuteBox`:
- `execute_loop_only` の内部で StepTree を作る
- `StepTreeContractBox` で capability 判定(許可形なら Normalized lowering、不可なら `Ok(None)`
- Normalized lowering:
- `if(cond){break}`: `cond_vid``ExprLowererBox`pure onlyで生成し、branch to `k_exit` / `loop_step` に落とす
- `if(cond){continue}`: then -> tailcall `loop_step`, else -> fallthrough
### Fixtures / smokes
- VM + LLVM EXE parity を 1 本ずつ増やす最小2本
- `apps/tests/phase143_loop_true_if_break_min.hako`
- `apps/tests/phase143_loop_true_if_continue_min.hako`
- Integration smokes:
- `tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_break_vm.sh`
- `tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_break_llvm_exe.sh`
- `tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_continue_vm.sh`
- `tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_continue_llvm_exe.sh`
### Acceptance criteria
- Phase 142-loopstmt の「statement-level normalizationconsumed=1」を維持し、suffix 形の増殖をさせない
- out-of-scope は `Ok(None)` でフォールバック(既定挙動不変)
- Unit tests が「許可形/不許可形」を contract として固定している(箱の責務が明確)
---
## Next
- P1: `if(cond) { break } else { continue }`else branch を入れる)を vocabulary として追加
- P2+: nested if / multi-if は capability guard で段階解禁Phase 切りで SSOT 化)