TuttleOFX  1
CTLProcess.cpp
Go to the documentation of this file.
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 }