Skip to main content

Module compiler

Module compiler 

Source
Expand description

Compiler: Form trees (with parser spans) to a validated Program.

Supports the milestone-4 synchronous subset: literals, lexical locals, the ten shared primitives, if, do, let, loop/recur, fn closures with capture-by-value upvalues (including variadic parameters), direct calls, exceptions, and the registry-direct global forms — def, defn (single- and multi-arity, interning real late-bound vars), var, set!, declare, field, and instance? (issue #223; see specs/01-lang/010-bytecode/draft/hal-bytecode-vm.edn :vm/namespaces). Anything else is a typed CompileError with source context; the compiler never emits fallback calls into the tree-walking evaluator.

Structure: shared state (constants, finished prototypes) plus a stack of function contexts. Each context owns a code buffer, scope stack, loop stack, and capture list. Slot layout per function: parameters at 0..arity-1, captures at arity..arity+capture_count-1, body locals above. Captures are discovered by a free-variable pre-pass over the body, so their slots are reserved (and pre-declared in the function’s base scope) before any body-local slot is allocated.

Functions§

compile_form_with_config_allow_unbound_globals
Compiles an already-read form without printing it back to source first. This is used by the native runtime’s ordinary form boundary so metadata such as ^:async remains part of the bytecode contract.
compile_halc_module
Lowers decoded HALC directly into bytecode while preserving its canonical schema graph in the resulting program. The module’s ns declaration is loader configuration rather than executable code and is omitted here.
compile_source
Compiles source text into a validated program. Multiple top-level forms compile as an implicit do. Without a namespace registry the program must be closed: only the names it declares itself are visible as globals (issue #223).
compile_source_with
Compiles against a caller’s namespace registry: registry vars (std.foundation and anything already interned) are visible to the two-phase global check, exactly as they will resolve at execution time through execute_program_with_globals (issue #223).
compile_source_with_allow_unbound_globals
Variant of compile_source_with for direct runtime evaluation. It keeps source namespace configuration intact while allowing late-bound globals which a preceding dynamic form may define.
compile_source_with_config
Compiles source against a caller-owned registry and namespace configuration. The configuration is applied to parsed forms before bytecode lowering so aliases remain source-positioned and the VM does not need an evaluator or text round-trip fallback. Runtime callers use this when their namespace declaration has already been loaded and its complete config is available.
compile_source_with_config_allow_unbound_globals
Compiles source for a direct-native runtime escape hatch. Dynamic Hara evaluation may define a Var before a later form in the same native frame reads it, so unresolved names are emitted as late-bound global reads. The direct runtime still fails at the read if the Var was not actually materialized; no evaluator fallback is introduced.
compile_spanned_form_with_config_allow_unbound_globals
Compiles an already-read source form without discarding its parser span. Prefer compile_spanned_forms_with_config_allow_unbound_globals when a runtime entry point has more than one contiguous ordinary source form.
compile_spanned_forms_with_config_allow_unbound_globals
Compiles already-read source forms without discarding their parser spans. Runtime entry points use this boundary so direct-native execution reports the source location of nested exception creation and throw instructions while preserving one program for each contiguous ordinary-form batch.
source_namespace_config
source_uses_dynamic_evaluation
Reports whether source contains a language-level dynamic evaluation boundary. Direct-native callers use this to permit late-bound reads which may be materialized by Runtime/eval, load-string, or defonce during execution. The scan is deliberately structural so a string containing the word eval does not change compilation policy.