Expand description
Multi-file loader: resolves import "./...", import "../...", and
import "/abs/..." statements relative to the importer, recursively
parses, and produces a single Program with all stages merged.
Names that are local to an imported file are mangled with a
per-file-path prefix, so the same module imported via multiple
aliases (or from multiple parents in a diamond shape) collapses to
one set of mangled names — same SigId, same nominal identity.
Stdlib imports (import "std.foo" as bar) pass through unchanged.
§Mangling
Each loaded file gets a prefix derived from its canonical filesystem
path. The entry file’s prefix is empty (so lex run main.lex process works unchanged). Imported files use <stem>_<hash>
where hash is the first 8 hex chars of SHA-256 of the canonical
path string. The hash disambiguates same-stem files in different
directories without forcing a project manifest.
Within a file at prefix P:
fn foodeclared in this file becomes<P>.foo(justfooat root).type Tdeclared in this file becomes<P>.T.- References to a locally-declared name get mangled, unless the name is shadowed by a binder (let, fn param, lambda param, or pattern binder) in scope.
m.foowheremis a path-import alias is rewritten to the imported file’s prefix-qualified name. Two parents importing the same file see the same prefix → calls and types unify.m.foowheremis a stdlib alias is unchanged.
Variant constructors are not mangled — they live in a global namespace, and a collision between two imported types’ constructors surfaces later as a type-check error. Same for record field names.
§Diamond imports
main.lex imports ./left and ./right, both of which import
./shared. shared.lex is parsed once per resolution, but its
mangled items are merged into the output exactly once (subsequent
loads from the same canonical path return an empty Program). This
is what makes s.build_report(...) and v.read_score(...) agree
on Report’s nominal identity.
§Limitations (tracked separately)
The mangling key is the canonical filesystem path. Moving a file
changes its SigId; renaming changes the file-stem half of the
prefix. The eventual fix — content-addressed identity decoupled
from filesystem layout — lives with store-native imports
(import "stage:..."); see the corresponding follow-up tracker.
Enums§
Functions§
- load_
program - Load a multi-file Lex program, expanding local imports relative to
the entry path. Stdlib imports (
std.*) pass through unchanged. - load_
program_ from_ str - Load a Lex program from a string source. Local-path imports are rejected up-front since there’s no base path to resolve from.