4. Includes
EBNF
include = "include" target .target = '"' file_char { file_char } '"' | "'" file_char { file_char } "'" .file_char = letter | digit | "_" | "-" | "." | "/" .File importing is supported through include statements, or just includes, which specify paths to other Viv files whose construct definitions will be merged into the one at hand.
Targets
Section titled “Targets”An author can specify either a filename, a relative path, or an absolute path as the target of an include. An include can only have a single target, so multiple statements are required to import multiple files.
File paths
Section titled “File paths”Viv file paths use the forward-slash (/) character as the directory separator, regardless of the host operating system. The compiler SHALL map such paths onto the underlying filesystem conventions.
Path resolution
Section titled “Path resolution”If an include target is a filename or a relative path, path resolution is required for the compiler to load its contents. Such path resolution always depends on the file in which the include statement appears, not the entry file that was submitted to the compiler.
Here’s some example code showing how path resolution works in Viv:
// Must be a file in the same directory as this fileinclude "tropes.viv"
// Path is treated as relative to this fileinclude "../tropes/tropes.viv"
// No resolution requiredinclude "/Users/vivian/Documents/viv/tropes/tropes.viv"Recursive includes
Section titled “Recursive includes”Consider the case of a file A being the entry file submitted to the compiler. If A includes a file B, which itself includes a file C, the contents of all three will be merged. Of course, there is directionality here, such that submitting B to the compiler would only cause C to be included.
Idempotency
Section titled “Idempotency”A given file will be processed only once, even if it is included multiple times in the course of resolving recursive includes.
Circular dependencies
Section titled “Circular dependencies”Circular dependencies are permitted. For example, if a file A includes B, and B includes A, the result would be A and B merged, with no duplicates (and no compiler error).
Concatenated source
Section titled “Concatenated source”The final result of include handling is a concatenated source, where all the constructs encountered during the recursive search are included, with no duplication. (At this point, includes have been handled and thus MAY be discarded.) As noted in their respective chapters, uniqueness among construct names is enforced in a concatenated source.
Concatenated source units are orderless
Section titled “Concatenated source units are orderless”As noted previously, the constructs within a source file are conceptually orderless. This is also the case in a concatenated source.
Errors
Section titled “Errors”If a specified file cannot be found, the compiler will halt with an error indicating the path of the nonexistent include target.