Files
hakorune/docs/development/current/main/phases/phase-143-loopvocab
tomoaki 27663097c5 docs(phase143): Step 9 - Phase 143-loopvocab P0 documentation
Phase 143 P0: Final documentation

Content:
- Purpose: Extend vocabulary for conditional break pattern
- P0 scope: loop(true) { if(cond_pure) break } only
- Design: 6-function JoinModule with Jump/Call/Return
- Implementation: Steps 1-8 (pattern detection → fixtures)
- Verification: cargo check , 4 commits created
- Out-of-scope handling: Ok(None) graceful fallback
- Next steps: P1 (with statements), P2 (else branches), P3 (impure conditions)

Status:  Phase 143 P0 COMPLETE

Files:
- Core: loop_true_if_break_continue.rs (~400 lines)
- Fixtures: phase143_loop_true_if_break_min.hako
- Tests: VM + LLVM EXE smoke tests

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-19 06:03:09 +09:00
..

Phase 143-loopvocab: Loop Vocabulary Extension

Status: P0 Complete Date: 2025-12-19


目的Why

Phase 131で loop(true) break を実装したが、Phase 143では「条件付きbreak」パターンを吸収する。

Phase 143-loopvocab では、loop(true) { if(cond_pure) break }Normalized shadow lowering で段階的に拡張するための語彙追加を行う。

パターン進化

Phase 131:

loop(true) { break }  // 無条件break

Phase 143 P0:

loop(true) { if(cond_pure) break }  // 条件付きbreak

P0: Minimal Vocabulary Extension (COMPLETE )

Summary

loop(true) { if(cond_pure) break } パターンを Normalized shadow で実装完了。

Scope (P0 - Conservative)

Supported:

  • Loop condition: true literal only
  • Loop body: Single if statement only
  • If then branch: break only (no continue, no nested if)
  • Condition expression: Pure only (variables, literals, arith, compare)

Out of Scope (Ok(None) fallback):

  • Loop condition not true: loop(x > 0) { ... }
  • Multiple statements in loop body
  • If/else statements (no else branch)
  • Impure conditions: loop(true) { if(s.length() > 0) break }
  • Nested structures within if body

Design: 6-Function JoinModule

main(env) → loop_step(env) → loop_cond_check(env)
                              [condition lowering + Jump]
                              → k_exit(env) on break [Ret]
                              → loop_step(env) on continue [Call]

k_then(unused in P0)
k_else(unused in P0)

Jump Semantics:

  • Jump { cont: k_exit, args: [...], cond: Some(vid) }
  • If vid is true: jump to k_exit (break)
  • If vid is false: fall through to Call(loop_step)

Implementation Steps (Complete )

Step 1-2: Pattern Detection + Routing

  • Extract loop(true) + if + break pattern
  • Validate loop condition = Bool(true) literal
  • Validate if body = single Break statement
  • Add module declaration and routing in builder.rs

Step 3: Condition Lowering Integration

  • Validate condition with NormalizedExprLowererBox
  • Use ExprLoweringScope::PureOnly
  • Return Ok(None) for impure conditions (graceful fallback)

Step 4: Branch Instruction Emission

  • Allocate 6 JoinFuncIds (stable IDs 0-5)
  • Build env parameter passing (deterministic BTreeMap)
  • Emit Jump instruction in loop_cond_check
  • Create Call fallthrough for loop_step

Step 5: Exit Action Discrimination

  • Complete k_exit() function
  • Build exit values from env_layout.writes
  • Extract final ValueIds from environment

Step 6: ExitMeta Construction

  • Create ExitMeta::multiple() from exit values
  • Use JoinFragmentMeta::carrier_only()
  • Return Ok(Some((module, meta)))

Step 7: Routing Integration

  • Already integrated in builder.rs (Step 1)
  • Phase 131 (simpler) → Phase 143 (conditional) priority

Step 8: Fixtures + Smoke Tests

Fixture: apps/tests/phase143_loop_true_if_break_min.hako

Tests:

  • 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

Expected exit code: 1

Step 9: Documentation (THIS FILE)

Acceptance Criteria (All Met )

  • Pattern detection correctly identifies loop(true) { if(cond) break }
  • Condition lowering validates pure scope
  • Out-of-scope patterns always return Ok(None)
  • JoinModule built with 6 functions
  • Jump instruction with conditional emission
  • k_exit returns exit values
  • ExitMeta constructed correctly
  • Fixture executes correctly (VM)
  • LLVM EXE parity test ready
  • No regressions in Phase 131-142
  • cargo check passes (no errors)
  • All commits created

Verification Results

Compilation: cargo check -p nyash-rust --lib (0 errors)

Commits:

  1. f55f6cc65 - Step 3: Condition lowering integration
  2. 434c891a1 - Step 4: Branch instruction emission
  3. d1d59dc82 - Steps 5-6: Exit handling + ExitMeta
  4. e28d59101 - Step 8: Fixtures + Smoke tests

Design Principles

Out-of-Scope Handling

All out-of-scope patterns return Ok(None) for graceful fallback to legacy routing.

Fail-Fast Policy

  • Out-of-scope: Always Ok(None) (no change to existing behavior)
  • In-scope errors: Return Err(msg) (internal errors, strict mode freeze)

Files

Core Implementation

  1. src/mir/control_tree/normalized_shadow/loop_true_if_break_continue.rs (~400 lines)

Fixtures + Tests

  1. apps/tests/phase143_loop_true_if_break_min.hako
  2. tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_break_vm.sh
  3. tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_break_llvm_exe.sh


Commits

  1. f55f6cc65 - feat(phase143): Step 3 - Condition lowering integration
  2. 434c891a1 - feat(phase143): Step 4 - Branch instruction emission
  3. d1d59dc82 - feat(phase143): Steps 5-6 - Exit handling + ExitMeta
  4. e28d59101 - feat(phase143): Step 8 - Fixtures + Smoke tests