Expand description
Source-level assembly of a multi-file / multi-directory LOGOS project.
A project is ONE compilation unit. assemble_project resolves the entry
file’s explicit imports (markdown links in its abstract), transitively loads
every reachable module, and splices their code into a single combined source
string — the same string-level seam the stdlib prelude already uses
(apply_prelude). Because every execution
tier (AOT, interpreter, VM, wasm, isa, C) re-parses from a source string, one
assembled string feeds them all: the imported functions and types reach the
parser, the call graph, and codegen exactly as if the program had been
written in a single file.
§Ordering
Modules are collected in post-order DFS over the import graph, so a
module’s dependencies are spliced before it and the entry’s own body (with
its ## Main) comes last. The tree-walking interpreter registers each
## To definition as it walks and has no hoisting pass, so “definitions
before the Main that uses them” must hold structurally — post-order gives it.
§Cycle & diamond safety
Collection dedups by canonical path through a visited set, seeded with
the entry. Mutual imports (A uses B, B uses A) are legal — required
for cross-file mutual recursion — and contribute each module’s code exactly
once. A module that imports the entry back never re-splices the entry’s
## Main.
§Foreign ## Main
Only the ENTRY’s ## Main survives; an imported module contributes its
functions and type definitions but never a ## Main (stripped by
strip_main_block). This preserves the single-entry-Main contract every
tier relies on.
Structs§
- Assembled
Program - One assembled compilation unit: the combined source plus the metadata later passes need for qualified-name resolution, collision diagnostics, and cross-file error attribution.
- DefSite
- A single definition site: which module (canonical path) declared a bare name, and the normalized content of the definition (its identity — two defs with the same normalized body are THE SAME definition).
- Located
- A combined-source offset resolved back to its origin.
- Provenance
- Bare-name → the modules that define it. A bare name owned by more than one distinct module is ambiguous: a bare reference to it is a hard error, and the qualified form disambiguates.
- Scope
Info - Per-file lexical scope for the whole project: what each file is allowed to reference. A file sees its own definitions and the exports of the modules it directly imports — never anything reached only transitively.
- Segment
- One contributed segment of the combined source: its
[start, end)byte range in the combined string, the ORIGINAL file it came from, and — for a byte-intact segment — the offset in that file itsstartcorresponds to. - Source
Map - File-level attribution: for each contributed segment of the combined source, its byte range, originating file, and (for byte-intact segments) the offset-within-file mapping — so a diagnostic on the combined blob is attributed to the user’s own file and line.
Enums§
- DefKind
- The kind of a top-level definition, for collision messages.
Functions§
- assemble_
project - Assemble the whole project reachable from
entry_pathinto one compilation unit. Returns an error only for unreadable/unresolvable imports; the combined source is then parsed by the normal pipeline. - assemble_
project_ with_ deps assemble_project, additionally linking the declared dependency roots so a bareImport <Dep>.resolves against apath/git-local package outside the project root.dep_rootsempty is byte-for-byte identical toassemble_project, so a single-project build is unchanged.- check_
scopes - Enforce per-file scoping over the assembled program: a reference to a name that is another user module’s export, from a file that neither defines nor imports it, is a hard error (no transitive leakage). Builtins, stdlib, and a file’s own/imported names are always fine, so a valid program never trips.