Implements the lowering of modules into procedures and objects. The AST of a module is separated into declarative and imperative nodes: both are gathered into separate statement lists, with the imperative one then being transformed into a procedure (the module's init procedure).
For integration with the passes interface, a simple adapter pass is provided. It sets up and populates a ModuleList instance, which can then be retrieved from the ModuleGraph via takeModuleList after all passes have run.
The collection part is somewhat similar to the rodfile-based IC backend, but instead of reading the modules' content from the rodfiles, it's collected via the pass interface.
Types
Module = object sym*: PSym ## module symbol idgen*: IdGenerator ## the ID generator associated with the module decls*: PNode ## all declarative statements (type, routine, and constant ## definitions) structs*: ModuleStructs ## the contents of the module's structs dataInit*: PSym ## the procedure responsible for initializing data associated with the ## module. This is data that must be initialized at run-time but does ## not depend on user-defined globals init*: PSym ## the procedure responsible for initializing the module's globals destructor*: PSym ## the procedure responsible for de-initializing the module's ## globals threadDestructor*: PSym ## the procedure responsible for de-initializing the module's ## thread-local variables preInit*: PSym ## the procedure for initializing the module's lifted globals postDestructor*: PSym ## the procedure for destroying the module's lifted globals threadPostDestructor*: PSym ## the procedure for destroying the module's lifted threadvars dynlibInit*: PSym ## the procedure for loading the dynamic libraries, procedure, and ## variables associated with the module
- Represents the contents of a fully analysed module, intended for use by the compiler backend. Source Edit
ModuleList = object modules*: SeqMap[FileIndex, Module] modulesClosed*: seq[FileIndex] ## stores the modules in the order they were closed. The first closed ## module comes first, then the next, etc. systemPos, mainPos: FileIndex
- Source Edit
ModuleStructs = object globals*: seq[PSym] ## all top-level globals part of the module nestedGlobals*: seq[PSym] ## all globals defined at the module *level* but not in the outermost ## *scope*. Ideally, these would be locals instead threadvars*: seq[PSym] ## all thread-local variables part of the module
- Source Edit
Consts
collectPass = (open: myOpen, process: myProcess, close: myClose, isFrontend: false)
- Source Edit
Procs
func mainModule(modules: ModuleList): lent Module {....raises: [], tags: [].}
- Source Edit
proc setupModule(graph: ModuleGraph; idgen: IdGenerator; m: PSym; decls, imperative: seq[PNode]): Module {. ...raises: [KeyError, Exception], tags: [ReadDirEffect, RootEffect].}
- Creates a Module instance from decls and imperative. The module structs are populated with the initial items (top-level globals defined in the outermost scope, and threadvars) and the module-bound operators are set up. Source Edit
func systemModule(modules: ModuleList): lent Module {....raises: [], tags: [].}
- Source Edit
proc takeModuleList(graph: ModuleGraph): ModuleList {....raises: [], tags: [].}
- Moves the ModuleList set up by the collector pass out of the graph.backend field and returns it. Source Edit
Iterators
iterator closed(modules: ModuleList): lent Module {....raises: [], tags: [].}
- Convenience iterator for returning all modules that need to be passed to code generation, in the order they were closed. Source Edit
iterator rclosed(modules: ModuleList): lent Module {....raises: [], tags: [].}
- Convenience iterator for returning all modules that need to be passed to code generation, in the reverse order they were closed. Source Edit