+ return nmodule
+ end
+
+ # Try to load a module and its imported modules using a path.
+ # Display an error if there is a problem (IO / lexer / parser / importation) and return null
+ # Note: usually, you do not need this method, use `get_mmodule_by_name` instead.
+ fun load_module(filename: String): nullable AModule
+ do
+ # Look for the module
+ var file = identify_file(filename)
+ if file == null then return null # forward error
+
+ # Already known and loaded? then return it
+ var mmodule = file.mmodule
+ if mmodule != null then
+ return mmodule2nmodule[mmodule]
+ end
+
+ # Load it manually
+ var nmodule = load_module_ast(file.filepath)
+ if nmodule == null then return null # forward error
+
+ # build the mmodule and load imported modules
+ mmodule = build_a_mmodule(file.mgroup, file.name, nmodule)
+
+ if mmodule == null then return null # forward error
+
+ # Update the file information
+ file.mmodule = mmodule
+
+ # Load imported module
+ build_module_importation(nmodule)
+
+ return nmodule
+ end
+
+ fun load_rt_module(parent: MModule, nmodule: AModule, mod_name: String): nullable AModule
+ do
+ # Create the module
+ var mmodule = new MModule(model, parent.mgroup, mod_name, nmodule.location)
+ nmodule.mmodule = mmodule
+ nmodules.add(nmodule)
+ self.mmodule2nmodule[mmodule] = nmodule
+
+ var imported_modules = new Array[MModule]
+
+ imported_modules.add(parent)
+ mmodule.set_visibility_for(parent, intrude_visibility)
+
+ mmodule.set_imported_mmodules(imported_modules)
+
+ return nmodule
+ end
+
+ # Visit the AST and create the `MModule` object
+ private fun build_a_mmodule(mgroup: nullable MGroup, mod_name: String, nmodule: AModule): nullable MModule
+ do