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>
3.7 KiB
3.7 KiB
Phase 143-loopvocab: StepTree Vocabulary Expansion (loop → if/break/continue)
Status: planned
Scope: Normalized shadow / JoinIR(dev-only, default behavior unchanged)
Related (SSOT):
docs/development/current/main/design/control-tree.mddocs/development/current/main/design/normalized-expr-lowering.mddocs/development/current/main/phases/phase-142-loopstmt/README.md
Goal
loop(true){ if(cond) break/continue } を「新パターン追加」ではなく、StepTree/ControlTree の語彙(vocabulary)拡張として表現し、同じ Normalized lowering(env + continuation)に流す。
つまり、suffix/fixture の形を増やすのではなく:
- 制御は構造(StepTree)
- 値は一般化(ExprLowererBox)
で吸収する。
Non-Goals
loop(<cond>)(条件付き loop)を Normalized に入れる(既存経路へフォールバック維持)- impure expression(Call/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)
- break:
loop(true) {
if (cond) { break }
}
- continue:
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 個の If(else無しでも可)で、その 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 tok_exit/loop_stepに落とすif(cond){continue}: then -> tailcallloop_step, else -> fallthrough
Fixtures / smokes
- VM + LLVM EXE parity を 1 本ずつ増やす(最小2本)
apps/tests/phase143_loop_true_if_break_min.hakoapps/tests/phase143_loop_true_if_continue_min.hako
- Integration smokes:
tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_break_vm.shtools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_break_llvm_exe.shtools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_continue_vm.shtools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_continue_llvm_exe.sh
Acceptance criteria
- Phase 142-loopstmt の「statement-level normalization(consumed=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 化)