Source modules, imports and exports
ASPL 0.7.0 · Current release
Import native source files, export declarations with share, and resolve private-member and entry errors.
On this page
Host and import syntax
This is the native ASPL 0.7.0 source-module contract. Install the native toolchain first. Browser virtual files are run data and do not supply a source-module loader, even when named .aspl or .لبات. Supplied libraries such as core::http, core::raylib and core::c have their own native support and are distinct from user-authored source files and C shared libraries.
Illustrative fragment
import helpers.aspl as lib;
استورد services/معالجات.لبات بسم خدمة.Use import / استورد, a relative path ending in .aspl or .لبات, and an optional as / بسم namespace. Paths are unquoted descriptors; escape a space with \ . An absolute import path is rejected. Resolution starts at the importing file's directory, including nested imports, rather than the process working directory. Without an alias, the filename stem must be a valid namespace identifier. Use an alias for filenames such as my-file.aspl.
ASPL 0.7.0 accepts \ي{...} alongside \u{...} in import paths, with the same hexadecimal alphabets and scalar limits as string escapes. Import paths reject U+0000. Escaped spaces and ASCII punctuation keep their existing spellings; the short string escapes such as \n and \س are invalid in import paths. Published 0.6.0 artifacts retain their original path escape syntax.
Namespaces and exports
Use lib::answer() to call a directly imported export. Imports do not execute code, merge declarations into the caller, or make transitive namespaces visible. Different source modules may use the same private name. Repeated imports of the same canonical file share its function and record identities, even through different aliases. Two different files defining the same record spelling still define distinct nominal types.
Functions, records and foreign declarations are private by default. Prefix an exported declaration with share / شارك. Exported user names keep their declared spelling; they do not acquire Arabic/English aliases. An exported foreign call still needs its explicit unsafe marker. Exported signatures and record fields cannot expose private types, including through nested callable, list or result types. Export the needed record too, or change the public signature.
Illustrative fragment
share fn answer() -> i64 { return 42; }
share record Reply { value: i64 }share import is rejected with shared-import: there are no re-exports. Import every namespace you name directly. See the private-declaration failure and corrected module program.
Entry and graph restrictions
Only the root source file defines start_main / ابدأ_الرئيسية, with no parameters and an i64 process status. Imported files must not define an entry; imported-entry rejects them. The root entry cannot be exported; shared-entry rejects that declaration. Entry names cannot be called or stored as callable values.
Cycles fail with import-cycle; namespace collisions fail with namespace-collision. Missing files fail with missing-file. The native graph has at most 1024 source modules and a longest import chain of 256 edges. Every imported declaration is checked, including unused helpers, so importing a file does not hide its type errors.
Check, run and build
Keep the entry and all declared source files in the documented relative layout. These commands need no data asset for this example:
aspl check main.aspl
aspl run main.aspl
aspl build -o module-program main.aspl
./module-programThe source-module example prints 42 followed by LF and returns 0. The built native program contains the checked program and VM and can execute after its source files are removed. It may still need any shared libraries or runtime data files used by that program.
Read the practical guide, callable accessibility, Linux command phases and complete-program collection.