Metaprogramming
import() — comptime file inclusion
std::import(path) reads a project file at compile time and folds to its contents as a comptime string.
since 0.1.0-alpha.1linuxwindowswasm
Description
std::import(path) reads a file while the program is being compiled and evaluates to its contents as a
string. It is meant for a comptime initializer, so the text of a template, a table or a script becomes
part of the program without being read at run time:
Including a template
comptime string tpl = import("views/index.html");
bool hasPlaceholder(string s) => s.contains("{{name}}");
comptime bool ok = hasPlaceholder(tpl);
console.writeln(tpl.length());
console.writeln(ok);
The file becomes a declared build input of the program. It has the same standing as a .lev source file:
the same inputs always give the same result.
A file that your project depends on has to be named in the project manifest. For a project built with
trident, list the files in assets in trident.toml:
name = "shop"
version = "0.1.0"
sources = ["src/*.lev"]
assets = ["views/index.html", "views/footer.html"]
import("views/index.html") in that project reads the declared file, and a path that is not in the list
is a compile error that names assets.
Rules
- A path is plain, project-relative and
/-separated. It has no leading/, no\, no empty text, and no.or..segment. These are checked on the text before the file system is touched, so a path that is shaped like an escape is refused as written and never normalized. - A build with a manifest looks the path up in the
assetsof the module that contains the importing file. A dependency'simport()sees only its own declared assets, never those of the app that uses it, and the app never sees the dependency's. A file compiled by itself, with no manifest, resolves the path relative to the source file's own directory. - A file is read once per compile. Two
comptimesites that import the same path see identical text even if the file changes while the compiler runs. leviathan --assets file.levlists every file animport()consumed, with its size, hash and module.- There is no size limit on the file. The
comptimestep budget (seelang.comptime) bounds a runaway loop that imports in each iteration. - A call to
import()that is reached at run time, not folded at compile time, throws a catchableRuntimeException. The behaviour is the same on every engine. - A function named
importthat you declare yourself is never affected: only the standard library'simportis folded. - A file that cannot be read is a compile error.
Examples
At run time import() has nothing to fold, so it throws. This program catches the exception:
import() at run time throws
try {
string s = import("views/index.html");
console.writeln(s);
} catch (RuntimeException e) {
console.writeln("import() only works at compile time");
}
import() only works at compile time
Your own function named import is an ordinary function:
A user function named import
int import(string name) => name.length();
console.writeln(import("views/index.html"));
16
Notes
- Compile-time evaluation is otherwise hermetic (see
lang.comptime);import()is the one declared file input. comptimestring results can feed other compile-time code, such as a function that parses a template.
See also
- comptime — run the language at compile time —
comptimevariables, expressions andifstatements evaluate ordinary code during compilation and fold the result into the program. - Compile-time metaprogramming — A map of the four compile-time layers, procedural macros, and the
--expandflag that shows what a rule produced. - import — Read a file at compile time and return its content as a string.