5.2.2. Modules
Spicy source code is structured around modules, which
introduce namespaces around other elements defined inside (e.g.,
types, functions). Accordingly, all Spicy input files must start with
module NAME;
, where NAME
is scope that’s being created.
After that initial module
statement, modules may contain arbitrary
list of declarations (types, globals, functions), as well as code
statements to execute. Any code defined at the global level will run
once at the module’s initialization time. That’s what enables Spicy’s
minimal hello-world
module to look like the following:
module Test;
print "Hello, world!";
# spicyc -j hello-world.spicy
Hello, world!
5.2.2.1. Importing
To make the contents of another module accessible, Spicy provides an
import NAME;
statement that pulls in all public identifiers of the
specified external module. Spicy then searches for name.spicy
(i.e., the lower-case version of the imported module NAME
plus a
.spicy
extension) along it’s module search path. By default,
that’s the current directory plus the location where Spicy’s pre-built
library modules are installed.
spicy-config --libdirs
shows the default search path. The Spicy
tools spicy
&& spicy-driver
provide --library-path
options
to add further custom directories. They also allow to fully replace the
built-in default search with a custom value by setting the environment
variable SPICY_PATH
.
There’s a second version of the import statement that allows to import
from relative locations inside the search path: import NAME from
X.Y.Z;
searches the module NAME
(i.e., NAME.spicy
) inside a
sub-directory X/Y/Z
along the search path.
Once Spicy code has imported a module, it can access identifiers by prefixing them with the module’s namespace:
import MyModule;
print MyModule::my_global_variable;
Generally, only identifiers declared as public
become accessible
across module boundaries. The one exception are types, which are
implicitly public.
Note
Spicy makes types implicitly public so that external unit hooks always have access to them. We may consider a more fine-grained model here in the future.
Spicy comes with a set of library modules that you may import in your code to gain access to their functionality.
5.2.2.2. Global Properties
A module may define the following global properties:
%byte-order = ORDER;
Defaults the byte order for any parsing inside this module to <expr>, where
ORDER
must be of type is type spicy::ByteOrder.%spicy-version = "VERSION";
Specifies that the module requires a given minimum version of Spicy, where
VERSION
must be a string of the formX.Y
orX.Y.Z
.%skip = REGEXP;
Specifies a pattern which should be skipped when encountered in the input stream in between parsing of unit fields (including before/after the first/last field).
%skip-pre = REGEXP;
Specifies a pattern which should be skipped when encountered in the input stream before parsing of a unit begins.
%skip-post = REGEXP;
Specifies a pattern which should be skipped when encountered in the input stream after parsing of a unit has finished.