EMBED reads a UTF-8 file while building and makes a readonly module value.
The executable needs neither the input file nor the decoder. PUBLIC/PRIVATE work
as for other module declarations. Implementation reference
.
TYPE ServerConfig
Host AS STRING
Port AS INTEGER = 8080
END TYPE
EMBED Defaults FROM "config/defaults.json" AS ServerConfig USING Json
EMBED DefaultText FROM "config/defaults.json" AS STRING
EMBED Port FROM "config/port.txt" AS INTEGER USING ReadPort
PRINT Defaults.Host; ":"; Defaults.Port
local = Defaults
local.Port = 9000
PRINT Defaults.Port ' Still the original value.
FUNCTION ReadPort(text AS STRING) AS INTEGER FAILS NumericError
RETURN VAL(TRIM(text))
END FUNCTIONPaths are relative to the declaring source, including imported modules. A path must stay inside its declared project tree, or its source directory for a standalone module; absolute paths and escaping symlinks are rejected. Inputs must be stable regular files. STRING preserves UTF-8 bytes, NUL, a BOM and line endings exactly. A decoder applies its own text/format policy.
USING names an ordinary visible function. Its first argument receives STRING
content; trailing arguments use their checked defaults. The AS type supplies
ordinary result context, including inferred generic result types. The same
function works at runtime. Json selects DecodeJson when no visible function
named Json exists. Other user decoders need no registration or compiler plugin.
YAML/TOML/XML codecs are separate pending work.
All declarations are checked, including unused inputs. Decoders may read other embedded values; dependencies are ordered before execution and cycles are errors. Application top-level statements and Main do not run during decoding.
The declaration and its nested data cannot be assigned, transferred or passed BYREF. Ordinary readonly calls borrow it. Assignment/owned return/BYVAL use the normal independent-value rules; changing a copy cannot change the embedded value. Immutable STRING bytes can safely remain shared. Records, lists, sets, dictionaries, dense arrays, optionals, choices and enums are supported recursively. Resources, pointers, function values, task/channel handles and errors as successful data are rejected. A decoder can still fail with its declared typed errors.
Raw STRING embeddings also work in ordinary constant/default contexts. A value
produced by USING is a readonly runtime value; it does not become a general
constant-expression factory. Exported .blib values preserve these rules after
moving the package and deleting producer sources/data. Generic bodies may refer
to private embedded values in their own module.
Deterministic decoding and failures
Local construction, computation and cleanup are allowed. The decoder’s checked call/callback/cleanup closure must avoid I/O, clocks, randomness, tasks, unsafe operations and unknown foreign behavior. Prebuilt BASIL decoders require a versioned build-effects contract; legacy packages work normally but must be rebuilt to serve as opaque build-time decoders. Scheduler EFFECTS alone is not evidence of deterministic behavior.
A Linux x86-64 child receives the authorized content and has bounded memory, CPU, wall time and output. Filesystem/network/process access and executable memory are denied. Unsupported kernel isolation fails the build. Normal decoder failures clean owned values, then report the declaration’s source line/column, input path, concrete error and primitive error fields. JSON offsets additionally map to input line/scalar-column alongside path/offset/message fields. Diagnostic I/O does not replace the primary failure. Nonprimitive error fields are not dumped; user Display/serialization hooks do not run while reporting failures. Forced termination/fatal allocation does not promise normal decoder cleanup.
Current build policy: 8 MiB per input; 32 MiB aggregate input including an eight-byte length per declaration; 32 MiB evaluator image; 64 MiB value packet; 1,048,576 value nodes; nesting depth128; 16 KiB diagnostics; 256 MiB child virtual memory; 5 CPU seconds and 10 wall seconds. Exceeding a limit is a build diagnostic, not a recoverable error in the resulting application.
Caches and output
build/.basic/embed beneath the entry source directory holds optional evaluator
images and successful checked packets. Keys include compiler/SDK, target/policy,
source/module/project identities, type schemas, decoder/default code and compiled
inputs. Changed typed content reuses a compatible evaluator but reruns decoding.
Semantic/effect checks and packet validation still run on hits. Damaged entries
miss/rebuild; a malformed executable with otherwise valid cache metadata is
explicitly rejected by the job boundary. Failures are never cached. Readonly
projects build without a writable cache. Remove this directory to clear it.