void Interpreter::loadModuleRecursive (const string &moduleName) { debug ("Interpreter::loadModuleRecursive " "(moduleName = " << moduleName << ")"); if (moduleIsLoadedInternal (moduleName)) { debug ("\talready loaded"); return; } // // Using the module search path, locate the file that contains the // source code for the module. Open the file. // string fileName = findModule (moduleName); ifstream file (fileName.c_str()); if (!file) { THROW_ERRNO ("Cannot load CTL module \"" << moduleName << "\". " "Opening file \"" << fileName << "\" for reading " "failed (%T)."); } debug ("\tloading from file \"" << fileName << "\""); Module *module = 0; LContext *lcontext = 0; try { // // Create a Module, an Lcontext and a Parser // module = newModule (moduleName, fileName); _data->moduleSet.addModule (module); lcontext = newLContext (file, module, _data->symtab); Parser parser (*lcontext, *this); // // Parse the source code and generate executable code // for the module // debug ("\tparsing input"); SyntaxNodePtr syntaxTree = parser.parseInput (); if (syntaxTree && lcontext->numErrors() == 0) { debug ("\tgenerating code"); syntaxTree->generateCode (*lcontext); } if (lcontext->numErrors() > 0) { lcontext->printDeclaredErrors(); THROW (LoadModuleExc, "Failed to load CTL module \"" << moduleName << "\"."); } // // Run the module's initialization code // debug ("\trunning module initialization code"); module->runInitCode(); // // Cleanup: the LContext and the module's local symbols // are no longer needed, but we keep the global symbols. // debug ("\tcleanup"); delete lcontext; _data->symtab.deleteAllLocalSymbols (module); } catch (...) { // // Something went wrong while loading the module, clean up // delete lcontext; _data->symtab.deleteAllSymbols (module); _data->moduleSet.removeModule (moduleName); throw; } }