Expand description
AST normalization passes that run after parse + include resolution and before type-checking.
§if literal-quotation lowering
if is a stack-consuming conditional combinator. At the source level
a typical use is:
cond [ then-body ] [ else-body ] ifWhen both operands are literal [ ... ] quotations at the call site,
this triple is semantically identical to a parser-level if/else
conditional. Rewriting it to Statement::If here — before the
type-checker runs — means every downstream pass (typechecker,
codegen, lints, the type-specializer) sees the same shape it sees
for any other inline conditional.
Doing this purely syntactically (no consultation of inferred types)
is sound: lifting a literal quotation’s body into the enclosing word
is semantically equivalent to invoking the quotation, because
captures resolve in the same lexical scope and >aux/aux> slot
allocation falls naturally to the enclosing word’s slot table once
the body is no longer wrapped in its own quotation function.
When at least one operand is not a literal [ ... ] (e.g. it
comes from a word argument or is constructed at runtime), the
triple is left alone and the runtime patch_seq_if dispatch
handles the call.
§Pipeline invariant
Every code path that runs the type-checker on user source must
call lower_literal_if_combinators first. The dynamic-dispatch
path through infer_if_combinator is strictly less expressive than
Statement::If (no aux-stack consistency check, no divergent-branch
short-circuit), so a lint or analysis pass that skips this pre-pass
will reject programs the build accepts. Today the call sites are
crates/compiler/src/lib.rs (both compile_* paths) and
crates/compiler/src/main/lint.rs. Add new pipelines to that list.
Functions§
- lower_
literal_ if_ combinators - Rewrite every
[Quotation, Quotation, WordCall("if")]triple in the program to aStatement::If. Runs after parse + include resolution, before type-checking.