-
Notifications
You must be signed in to change notification settings - Fork 44
Module System
The modules
branch contains an implementation of a basic(-ish) module system for Links, and will be merged into sessions once we decide on a merging strategy at a Links development meeting.
Main features:
- In-file modules
- Multi-file modules
- Partially- and fully-qualified name resolution
As some kinks may not yet be worked out, modules are disabled by default. To enable them, use the -m
flag. Without the -m
flag, files containing modules, fully-qualified names, or import statements will not compile, and will exit with an error.
Additionally, --path=/path1/to/import:path2/to/import
will look for included modules in:
/path1/to/import
path2/to/import
a.links
:
open B
foo()
b.links
:
module C {
fun bar() { .. }
}
fun foo() { C.bar() }
The module system works by resolving names to fully-qualified names, and flattening out modules to standard bindings. As an example, b.links
would become:
fun B.C.bar() { .. }
fun B.foo() { B.C.bar() }
To do this, there are several extra passes that we need:
uniquify.ml
- Generates unique names for all binders and references
scopeGraph.ml
- A name resolution algorithm, adapted from A Theory of Name Resolution by Neron et al.
- Allows reference names to be resolved to declaration names.
- Also provides a mapping from unique declaration names to (plain) fully-qualified names.
-
chaser.ml
(called fromfrontend.ml
)
- Recursively finds all unresolvable external references from
open
statements and qualified names - Performs a topological sort to get correct dependency ordering
- At this point, cyclic dependencies are detected and reported
- Adds all bindings in the correct order to the top of the file
desugarModules.ml
- Takes a file with modules, imports, and qualified references
- Produces a file without the above constructs, and with all references and declarations resolved to fully-qualified names
The pipeline afterwards is unaffected.
- Signature files
- Optimisations
- Better integration with prelude loading. Ideally the prelude would be handled as part of the module system as opposed to a special case.
- Caching of imported modules (which is unsupported at present)