100%

walking-skeleton

Goal

A minimal while i < n do { ... } program parses, desugars to loop, and runs identically in both backends — verified against the implementation already landed at HEAD.

Delivered State at HEAD — verify, do not re-execute

This section’s deliverable already exists at HEAD via compiler_repo commit b9939de7d (2026-06-03, “feat(while): add while-loop expression end-to-end”). Executing the original work item as written would re-implement landed work. Landed evidence:

  • Parser: parse_while_expr at compiler_repo/compiler/ori_parse/src/grammar/expr/primary/control_flow.rs:296, dispatched on the while tag at compiler_repo/compiler/ori_parse/src/grammar/expr/primary/mod.rs:134.
  • Desugar: canon-time, NOT parse-time — desugar_while at compiler_repo/compiler/ori_canon/src/lower/expr.rs:317 lowers to loop { if !cond then break; body }.
  • Typeck: ExprKind::While survives through typeck; LoopForm loop-context tracking rejects break value (E0860) and continue value (E0861).
  • Spec tests: compiler_repo/tests/spec/expressions/while.ori with observable assert_eq pins (while_basic() == 10, while_break, while_continue, nested_while) and #compile_fail(E0860/E0861) pins at lines 135/141/213.

Architecture note (supersedes this plan’s original implementation sketch): the landed design keeps ExprKind::While through typeck and desugars in ori_canon — aligned with the missions.md ori_canon mission (sugar eliminated at canonicalization; one shape consumed identically by both backends). The plan’s parse-time-desugar sketch is superseded; see the delivered-architecture note in sibling parser-desugar--s-410a0ed6.md.

Cross-phase ownership note: the landed feature spans parse + typeck + canon, not parse-only — decisions about it route across those phases’ owners, not solely the parser.

Section-boundary note (vs sibling parser-desugar w-78dc9ae8 / w-90fd359e): this section owns end-to-end parity verification (parse → canon desugar → both backends, anchored on the observable spec-test cases); parser-desugar owns parser-level grammar-coverage verification (labels, do-block vs bare-expr body, while...yield rejection, Rust parser tests). No re-implementation in either section.

Implementation Sketch

Verification-only: confirm each landed artifact above exists at HEAD; run the spec tests under both backends; run the leak gate. No new code unless verification surfaces a gap — fix any gap surfaced.

Parity-evidence note: the superseded skeleton spec (@run (n: int) -> void mutating a local then discarding it) has no observable result, so “runs identically under both backends” would be vacuously satisfiable by a no-op desugar. Parity evidence anchors to the observable-asserting spec-test cases in tests/spec/expressions/while.ori instead.

Spec References

while-loop-proposal.md Design/Semantics; grammar.ebnf:541; spec/16-control-flow.md:137 §16.2.4 While loop; spec/14-expressions.md:896 §14.12 While Expression.

Work Items

  • Verify-against-HEAD (deliverable landed via compiler_repo commit b9939de7d — do NOT re-implement): (1) confirm the landed artifacts exist at HEAD — parse_while_expr (ori_parse/src/grammar/expr/primary/control_flow.rs:296; dispatch at primary/mod.rs:134), desugar_while (ori_canon/src/lower/expr.rs:317), typeck LoopForm E0860/E0861 enforcement; (2) run tests/spec/expressions/while.ori observable cases (while_basic() == 10, while_break, while_continue, nested_while) under the interpreter AND the LLVM backend (dual-execution parity per CLAUDE.md Fix Completeness) plus ORI_CHECK_LEAKS=1 leak gate; (3) when verification passes, mark complete via the owning scripts WITHOUT re-executing the original implementation; fix any gap verification surfaces.