00001 #include <assert.h> 00002 00003 #include <QObject> 00004 #include "ThymioIntermediateRepresentation.h" 00005 00006 00007 namespace Aseba 00008 { 00009 00010 ThymioCompiler::ThymioCompiler() : 00011 buttonSet(), 00012 typeChecker(), 00013 syntaxChecker(), 00014 codeGenerator(), 00015 errorType(THYMIO_NO_TYPE_ERROR) 00016 { 00017 } 00018 00019 ThymioCompiler::~ThymioCompiler() 00020 { 00021 clear(); 00022 } 00023 00024 void ThymioCompiler::addButtonSet(ThymioIRButtonSet *set) 00025 { 00026 buttonSet.push_back(set); 00027 } 00028 00029 void ThymioCompiler::insertButtonSet(int row, ThymioIRButtonSet *set) 00030 { 00031 if(row < (int)buttonSet.size()) 00032 buttonSet.insert(buttonSet.begin()+row, set); 00033 else 00034 buttonSet.push_back(set); 00035 } 00036 00037 void ThymioCompiler::removeButtonSet(int row) 00038 { 00039 assert(row < (int)buttonSet.size()); 00040 buttonSet.erase(buttonSet.begin()+row); 00041 } 00042 00043 void ThymioCompiler::replaceButtonSet(int row, ThymioIRButtonSet *set) 00044 { 00045 if(row < (int)buttonSet.size()) 00046 buttonSet[row] = set; 00047 else 00048 buttonSet.push_back(set); 00049 } 00050 00051 void ThymioCompiler::swap(int row1, int row2) 00052 { 00053 ThymioIRButtonSet *set = buttonSet[row1]; 00054 buttonSet[row1] = buttonSet[row2]; 00055 buttonSet[row2] = set; 00056 } 00057 00058 int ThymioCompiler::buttonToCode(int id) const 00059 { 00060 return codeGenerator.buttonToCode(id); 00061 } 00062 00063 void ThymioCompiler::clear() 00064 { 00065 buttonSet.clear(); 00066 typeChecker.clear(); 00067 syntaxChecker.clear(); 00068 codeGenerator.clear(); 00069 00070 errorType = THYMIO_NO_TYPE_ERROR; 00071 } 00072 00073 ThymioIRErrorCode ThymioCompiler::getErrorCode() const 00074 { 00075 switch(errorType) 00076 { 00077 case THYMIO_SYNTAX_ERROR: 00078 return syntaxChecker.getErrorCode(); 00079 break; 00080 case THYMIO_TYPE_ERROR: 00081 return typeChecker.getErrorCode(); 00082 break; 00083 case THYMIO_CODE_ERROR: 00084 return codeGenerator.getErrorCode(); 00085 break; 00086 case THYMIO_NO_TYPE_ERROR: 00087 default: 00088 break; 00089 } 00090 00091 return THYMIO_NO_ERROR; 00092 } 00093 00094 bool ThymioCompiler::isSuccessful() const 00095 { 00096 return ( errorType == THYMIO_NO_TYPE_ERROR ? true : false ); 00097 } 00098 00099 int ThymioCompiler::getErrorLine() const 00100 { 00101 return ( errorType == THYMIO_NO_TYPE_ERROR ? -1 : errorLine ); 00102 } 00103 00104 vector<wstring>::const_iterator ThymioCompiler::beginCode() const 00105 { 00106 return codeGenerator.beginCode(); 00107 } 00108 00109 vector<wstring>::const_iterator ThymioCompiler::endCode() const 00110 { 00111 return codeGenerator.endCode(); 00112 } 00113 00114 void ThymioCompiler::compile() 00115 { 00116 errorType = THYMIO_NO_TYPE_ERROR; 00117 errorLine = -1; 00118 typeChecker.reset(); 00119 00120 vector<ThymioIRButtonSet*>::iterator itr = buttonSet.begin(); 00121 for( itr = buttonSet.begin(); itr != buttonSet.end(); ++itr ) 00122 { 00123 errorLine++; 00124 00125 (*itr)->accept(&syntaxChecker); 00126 if( !syntaxChecker.isSuccessful() ) 00127 { 00128 errorType = THYMIO_SYNTAX_ERROR; 00129 break; 00130 } 00131 00132 (*itr)->accept(&typeChecker); 00133 if( !typeChecker.isSuccessful() ) 00134 { 00135 errorType = THYMIO_TYPE_ERROR; 00136 break; 00137 } 00138 00139 } 00140 } 00141 00142 void ThymioCompiler::generateCode() 00143 { 00144 if( errorType == THYMIO_NO_TYPE_ERROR ) 00145 { 00146 codeGenerator.reset(); 00147 00148 vector<ThymioIRButtonSet*>::iterator itr = buttonSet.begin(); 00149 for( itr = buttonSet.begin(); itr != buttonSet.end(); ++itr ) 00150 { 00151 (*itr)->accept(&codeGenerator); 00152 if( !codeGenerator.isSuccessful() ) 00153 { 00154 errorType = THYMIO_CODE_ERROR; 00155 break; 00156 } 00157 } 00158 } 00159 } 00160 00161 }; // Aseba