Skip to main content

Module normalize

Module normalize 

Source
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 ] if

When 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 a Statement::If. Runs after parse + include resolution, before type-checking.