iter loop-recur.1: additive Term::Loop / Term::Recur / LoopBinder foundation
First of three iterations of the standalone loop/recur milestone
(spec 97c1ed1). loop/recur become real parseable / printable /
round-trippable / hash-stable strictly-additive AST nodes across
every no-wildcard exhaustive Term match in all six crates, plus
parse/print, prose arms, DESIGN.md + form_a.md schema blocks,
drift/coverage/hash anchors, and the spec's worked sum_to program
as a green round-trip fixture. NO typecheck semantics and NO real
codegen this iter by design: synth and lower_term are stubbed
CheckError::Internal / CodegenError::Internal exactly as mut.1
(real typecheck = iter 2, real loop-header/phi/back-edge = iter 3).
Two binding Boss design calls recorded in the plan header and the
journal: (1) verify_tail_positions "byte-unchanged" = its tail-app
verification role is unchanged, not its source — it is an
exhaustive no-wildcard match so two descent-only arms are
mandatory; acceptance evidence is the tail-app non-regression test.
(2) codegen is in iter-1 scope as stubs/pass-throughs because the
workspace must compile for cargo test --workspace.
Three plan-pseudo-vs-reality substitutions (serde Type::Con
literal, bare Int -> (con Int), unqualified LoopBinder) and one
recon-undercount integration-test site, all intent-preserving and
journalled. Boss forward-fix folded in: the committed specs
themselves wrote bare Int in the loop-binder snippets (parses as
Type::Var) — corrected the three headline snippets to (con Int) for
doc-honesty (no design/schema change).
cargo test --workspace 600 -> 608 / 0 red (Boss-reran
independently); iter13a + new loop_recur hash pins green.
This commit is contained in:
@@ -1837,6 +1837,14 @@ impl<'a> Emitter<'a> {
|
||||
));
|
||||
Ok(("0".into(), "i8".into()))
|
||||
}
|
||||
// loop-recur iter 1: real codegen (loop-header block,
|
||||
// per-binder phi, back-edge br) lands in iter 3. This
|
||||
// iter stubs the dispatch so the workspace compiles; no
|
||||
// loop/recur program is codegen'd in iter 1. Mirrors
|
||||
// mut.1's lower_term stub.
|
||||
Term::Loop { .. } | Term::Recur { .. } => Err(CodegenError::Internal(
|
||||
"Term::Loop/Term::Recur lowering lands in loop-recur iter 3".into(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3093,6 +3101,13 @@ impl<'a> Emitter<'a> {
|
||||
// is exhaustive on Term so the arms must exist.
|
||||
Term::Mut { body, .. } => self.synth_with_extras(body, extras),
|
||||
Term::Assign { .. } => Ok(Type::unit()),
|
||||
// loop-recur iter 1: a Term::Loop's static type is the
|
||||
// body's type (mirror Term::Mut). Term::Recur does not
|
||||
// fall through; a Unit stub is safe — this arm is never
|
||||
// hit on the shipping path because lower_term stubs
|
||||
// Loop/Recur, and iter 1 codegens no loop/recur program.
|
||||
Term::Loop { body, .. } => self.synth_with_extras(body, extras),
|
||||
Term::Recur { .. } => Ok(Type::unit()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user