TuttleOFX
1
|
00001 #include <CtlSimdInterpreter.h> 00002 #include <CtlModuleSet.h> 00003 #include <CtlModule.h> 00004 #include <CtlLContext.h> 00005 #include <CtlSymbolTable.h> 00006 #include <CtlParser.h> 00007 #include <CtlExc.h> 00008 // 00009 00010 #include "CTLPlugin.hpp" 00011 #include "CTLDefinitions.hpp" 00012 #include "CTLProcess.hpp" 00013 00014 // Ctl code 00015 #if 0 00016 #include <iostream> 00017 #define debug(x) (cout << x << endl) 00018 #else 00019 #define debug(x) 00020 #endif 00021 00022 namespace Ctl { 00023 using namespace std; 00024 using namespace Iex; 00025 using namespace IlmThread; 00026 // we redeclare locally... (because in lib CTL, it's declared into a cpp file) 00027 struct Interpreter::Data 00028 { 00029 SymbolTable symtab; 00030 ModuleSet moduleSet; 00031 Mutex mutex; 00032 }; 00033 } 00034 00035 namespace tuttle { 00036 namespace plugin { 00037 namespace ctl { 00038 00039 using namespace std; 00040 using namespace Iex; 00041 using namespace IlmThread; 00042 using namespace Ctl; 00043 00044 void loadModule( Ctl::Interpreter& interpreter, const std::string &moduleName, const std::string& code ) 00045 { 00046 debug ("Interpreter::loadModule (moduleName = " << moduleName << ")"); 00047 00048 Lock lock( interpreter._data->mutex ); 00049 loadModuleRecursive( interpreter, moduleName, code ); 00050 } 00051 00052 00053 void loadModuleRecursive( Ctl::Interpreter& interpreter, const std::string &moduleName, const std::string& code ) 00054 { 00055 debug ("Interpreter::loadModuleRecursive " 00056 "(moduleName = " << moduleName << ")"); 00057 00058 if( interpreter.moduleIsLoadedInternal(moduleName) ) 00059 { 00060 debug ("\talready loaded"); 00061 return; 00062 } 00063 00064 // 00065 // Input source code of the module comes from a string instead of a file. 00066 // 00067 const std::string fileName = moduleName; 00068 std::istringstream codeStream( code ); 00069 00070 debug ("\tloading from code \"" << fileName << "\""); 00071 00072 Module *module = 0; 00073 LContext *lcontext = 0; 00074 00075 try 00076 { 00077 // 00078 // Create a Module, an Lcontext and a Parser 00079 // 00080 00081 module = interpreter.newModule (moduleName, fileName); 00082 interpreter._data->moduleSet.addModule (module); 00083 lcontext = interpreter.newLContext (codeStream, module, interpreter._data->symtab); 00084 Parser parser (*lcontext, interpreter); 00085 00086 // 00087 // Parse the source code and generate executable code 00088 // for the module 00089 // 00090 00091 debug ("\tparsing input"); 00092 SyntaxNodePtr syntaxTree = parser.parseInput (); 00093 00094 if (syntaxTree && lcontext->numErrors() == 0) 00095 { 00096 debug ("\tgenerating code"); 00097 syntaxTree->generateCode (*lcontext); 00098 } 00099 00100 if (lcontext->numErrors() > 0) 00101 { 00102 lcontext->printDeclaredErrors(); 00103 THROW (LoadModuleExc, 00104 "Failed to load CTL module \"" << moduleName << "\"."); 00105 } 00106 00107 // 00108 // Run the module's initialization code 00109 // 00110 00111 debug ("\trunning module initialization code"); 00112 module->runInitCode(); 00113 00114 // 00115 // Cleanup: the LContext and the module's local symbols 00116 // are no longer needed, but we keep the global symbols. 00117 // 00118 00119 debug ("\tcleanup"); 00120 delete lcontext; 00121 interpreter._data->symtab.deleteAllLocalSymbols (module); 00122 } 00123 catch (...) 00124 { 00125 // 00126 // Something went wrong while loading the module, clean up 00127 // 00128 00129 delete lcontext; 00130 interpreter._data->symtab.deleteAllSymbols (module); 00131 interpreter._data->moduleSet.removeModule (moduleName); 00132 throw; 00133 } 00134 } 00135 00136 00137 } 00138 } 00139 }