Module
Every parser definition is a module. A module is the top-level container
for a parser — its actions, its parser block and any configuration all live
inside one module.
Naming a Module
A module is named with the program keyword. The declaration usually sits at
the very top of the source.
program MyParser;
A module’s name may be written in two parts: a preface in quotes, then the name the grammar uses.
program "algodal" json;
The full name is the two run together — algodaljson — and that is what the
module is actually called. The preface is ignored by the grammar; the second
part is the handle a link writes and a call goes through. It is there so a
family of modules can share a prefix without every grammar that uses them
having to spell it out.
program algodaljson; declares exactly the same module.
Linking Modules
One module can call the actions of another with the link keyword. A linked
module is a separate machine: it has its own stack, its own globals, its own
semvar sets and its own scopes. Linking does not merge two grammars, it lets one
call into the other.
program p1;
link p2;
parser {
"A" . p2::value . "B";
};
A linked action is always reached as module::action. The qualified name is
required, not decoration — it is what tells a call in p1 apart from a local
action of the same name.
Linking gives you the other module’s named actions. Anything it defines with a name, you can call. There is nothing to export and nothing to declare on either side: the name is the interface.
link "algodal" json; # the same as `link algodaljson;`
value := json::value; # call a named action of it
Link more than one module by repeating the keyword:
program p1;
link p2;
link p3;
parser { p2::start . p3::start; };
The link "algodal" json; form is sugar for link algodaljson;, exactly as
the two-part program declaration is.
Resolved when it loads, not when it compiles
The other module is not present when this one is compiled, so nothing about it can be checked here — not whether the action exists, and not what kind of action it is. Those names are carried in the binary and resolved by the loader, once, when the modules are brought together.
That is the trade for being able to compile modules separately and combine them later.
Running a linked set
The compiler builds each module on its own, and they are brought together when they load. From the command line:
apma html.apm -o html.apmb
apma javascript.apm -o javascript.apmb
apmr html.apmb page.html --link javascript.apmb
Without the link, a call into the other module reports that it was never resolved rather than failing somewhere stranger.
See also
To build the VM into your own program and run a module, see
How to Use. The parser block that drives a module is
described in Parser.
A module’s own name and every linked handle share the name space actions live
in, so neither may be a reserved word.