Fennel: /home/pub/open/dev/fennel/calculator/CalcAssembler.h Source File (original) (raw)

00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 #ifndef Fennel_CalcAssembler_Included 00024 #define Fennel_CalcAssembler_Included 00025 00026 #include "fennel/calculator/CalcLexer.h" 00027 #include "fennel/calculator/CalcAssemblerException.h" 00028 #include "fennel/calculator/InstructionFactory.h" 00029 00030 #include 00031 00032 FENNEL_BEGIN_NAMESPACE 00033 00034 using namespace std; 00035 00036 typedef size_t TRegisterIndex; 00037 00038 class Calculator; 00039 class RegisterReference; 00040 class TupleDescriptor; 00041 class StoredTypeDescriptorFactory; 00042 00043 extern int CalcYYparse (void ); 00044 00062 class FENNEL_CALCULATOR_EXPORT CalcAssembler 00063 { 00064 public: 00065 explicit 00066 CalcAssembler(Calculator calc) { 00067 assert(calc != NULL); 00068 mCalc = calc; 00069 } 00070 00071 ~CalcAssembler(); 00072 00073 CalcLexer& getLexer() { 00074 return mLexer; 00075 } 00076 00077 int assemble(const char* program); 00078 int assemble(); 00079 00080
00081 static TupleData* 00082 createTupleData( 00083 TupleDescriptor const& tupleDes, 00084 FixedBuffer** buf); 00085 00086 static RegisterReference* 00087 createRegisterReference( 00088 RegisterReference::ERegisterSet setIndex, 00089 TRegisterIndex regIndex, 00090 StandardTypeDescriptorOrdinal regType); 00091 00092 static Instruction* 00093 createInstruction( 00094 string& name, 00095 vector<RegisterReference*> const &operands, 00096 CalcYYLocType& location) 00097 { 00098 Instruction* inst = NULL; 00099 try { 00100 inst = InstructionFactory::createInstruction(name, operands); 00101 } catch (FennelExcn& ex) { 00102 throw CalcAssemblerException(ex.getMessage(), location); 00103 } catch (std::exception& ex) { 00104 throw CalcAssemblerException(ex.what(), location); 00105 } 00106 if (inst == NULL) { 00107 string error; 00108 error = "Error instantiating instruction: " + name; 00109 if (operands.size() > 0) { 00110 error += " "; 00111 int i; 00112 for (i = 0; i < operands.size(); i++) { 00113 error += operands[i]->toString(); 00114 if (i + 1 < operands.size()) { 00115 error += ", "; 00116 } 00117 } 00118 } 00119 throw CalcAssemblerException(error, location); 00120 } 00121 return inst; 00122 } 00123 00124 static Instruction* createInstruction( 00125 string& name, 00126 RegisterReference* result, 00127 RegisterReference* operand1, 00128 RegisterReference* operand2, 00129 CalcYYLocType& location) 00130 { 00131 vector<RegisterReference*> operands; 00132 operands.push_back(result); 00133 operands.push_back(operand1); 00134 operands.push_back(operand2); 00135 return createInstruction(name, operands, location); 00136 } 00137 00138 00139 static Instruction* createInstruction( 00140 string& name, 00141 RegisterReference* result, 00142 RegisterReference* operand1, 00143 CalcYYLocType& location) 00144 { 00145 vector<RegisterReference*> operands; 00146 operands.push_back(result); 00147 operands.push_back(operand1); 00148 return createInstruction(name, operands, location); 00149 } 00150 00151 static Instruction* createInstruction( 00152 string& name, 00153 RegisterReference* result, 00154 CalcYYLocType& location) 00155 { 00156 vector<RegisterReference*> operands; 00157 operands.push_back(result); 00158 return createInstruction(name, operands, location); 00159 } 00160 00161 static Instruction* createInstruction( 00162 string& name, 00163 CalcYYLocType& location) 00164 { 00165 vector<RegisterReference*> operands; 00166 return createInstruction(name, operands, location); 00167 } 00168 00169 static Instruction* createInstruction( 00170 string& name, 00171 TProgramCounter pc, 00172 CalcYYLocType& location) 00173 { 00174 return createInstruction(name, pc, NULL, location); 00175 } 00176 00177 00178 static Instruction* createInstruction( 00179 string& name, 00180 TProgramCounter pc, 00181 RegisterReference* operand, 00182 CalcYYLocType& location) 00183 { 00184 Instruction* inst = NULL; 00185 00186 try { 00187 inst = InstructionFactory::createInstruction(name, pc, operand); 00188 } catch (FennelExcn& ex) { 00189 throw CalcAssemblerException(ex.getMessage(), location); 00190 } catch (std::exception& ex) { 00191 throw CalcAssemblerException(ex.what(), location); 00192 } 00193 00194 if (inst == NULL) { 00195 stringstream errorStr("Error instantiating instruction: "); 00196 errorStr << name << " " << pc << ", "; 00197 if (operand) { 00198 errorStr << operand->toString(); 00199 } 00200 throw CalcAssemblerException(errorStr.str(), location); 00201 } 00202 return inst; 00203 } 00204 00205 Instruction* createInstruction( 00206 string& name, 00207 string& function, 00208 vector<RegisterReference*>& operands, 00209 CalcYYLocType& location) 00210 { 00211 Instruction* inst = NULL; 00212 00213 try { 00214 inst = InstructionFactory::createInstruction( 00215 name, function, operands); 00216 } catch (FennelExcn& ex) { 00217 throw CalcAssemblerException(ex.getMessage(), location); 00218 } catch (std::exception& ex) { 00219 throw CalcAssemblerException(ex.what(), location); 00220 } 00221 00222 if (inst == NULL) { 00223 InstructionSignature sig(function, operands); 00224 stringstream errorStr("Error instantiating instruction: "); 00225 errorStr << name << " "; 00226 errorStr << sig.compute(); 00227 errorStr << " not registered "; 00228 throw CalcAssemblerException(errorStr.str(), location); 00229 } 00230 00231 return inst; 00232 } 00233 00234 static void setTupleDatum( 00235 StandardTypeDescriptorOrdinal type, 00236 TupleDatum& tupleDatum, 00237 TupleAttributeDescriptor& desc, 00238 double value); 00239 static void setTupleDatum( 00240 StandardTypeDescriptorOrdinal type, 00241 TupleDatum& tupleDatum, 00242 TupleAttributeDescriptor& desc, 00243 uint64_t value); 00244 static void setTupleDatum( 00245 StandardTypeDescriptorOrdinal type, 00246 TupleDatum& tupleDatum, 00247 TupleAttributeDescriptor& desc, 00248 int64_t value); 00249 static void setTupleDatum( 00250 StandardTypeDescriptorOrdinal type, 00251 TupleDatum& tupleDatum, 00252 TupleAttributeDescriptor& desc, 00253 string value); 00254 static void setTupleDatum( 00255 StandardTypeDescriptorOrdinal type, 00256 TupleDatum& tupleDatum, 00257 TupleAttributeDescriptor& desc, 00258 PConstBuffer buffer); 00259 00260 protected: 00261 friend int CalcYYparse (void ); 00262 00263
00264 00266 void init(); 00267 00276 void allocateTuples(); 00277 00286 void bindRegisters(); 00287 00302 template 00303 void bindRegisterValue( 00304 RegisterReference::ERegisterSet setIndex, 00305 TRegisterIndex regIndex, 00306 T value) 00307 { 00308 try { 00309 StandardTypeDescriptorOrdinal regType = getRegisterType( 00310 setIndex, regIndex); 00311 TupleData
tupleData = getTupleData(setIndex); 00312 assert(tupleData != NULL); 00313 TupleDatum& tupleDatum = (tupleData)[regIndex]; 00314 TupleDescriptor& tupleDesc = getTupleDescriptor(setIndex); 00315 setTupleDatum(regType, tupleDatum, tupleDesc[regIndex], value); 00316 } catch (CalcAssemblerException& ex) { 00317
00318 throw ex; 00319 } catch (FennelExcn& ex) { 00320
00321 ostringstream errorStr(""); 00322 errorStr << "Error binding register " 00323 << RegisterReference::toString(setIndex, regIndex) 00324 << ": " << ex.getMessage(); 00325 throw CalcAssemblerException( 00326 errorStr.str(), getLexer().getLocation()); 00327 } catch (exception& ex) { 00328
00329 ostringstream errorStr(""); 00330 errorStr << "Error binding register: " 00331 << RegisterReference::toString(setIndex, regIndex) 00332 << ": " << ex.what(); 00333 throw CalcAssemblerException( 00334 errorStr.str(), getLexer().getLocation()); 00335 } 00336 } 00337 00353 template 00354 void bindNextLiteral(T value) 00355 { 00356 bindRegisterValue(RegisterReference::ELiteral, mLiteralIndex, value); 00357 mLiteralIndex++; 00358 } 00359 00365 void bindLiteralDone(); 00366 00367
00368 00373 void selectRegisterSet(RegisterReference::ERegisterSet setIndex); 00374 00381 void addRegister( 00382 StandardTypeDescriptorOrdinal regType, 00383 uint cbStorage = 0); 00384 00391 void addRegister( 00392 RegisterReference::ERegisterSet setIndex, 00393 StandardTypeDescriptorOrdinal regType, 00394 uint cbStorage = 0); 00395 00396 00397
00398 00403 void addInstruction(Instruction
inst); 00404 00405
00406 00412 TRegisterIndex getRegisterSize(RegisterReference::ERegisterSet setIndex); 00413 00422 RegisterReference* getRegister( 00423 RegisterReference::ERegisterSet setIndex, 00424 TRegisterIndex regIndex); 00425 00434 StandardTypeDescriptorOrdinal getRegisterType( 00435 RegisterReference::ERegisterSet setIndex, 00436 TRegisterIndex regIndex); 00437 00443 TupleData* getTupleData(RegisterReference::ERegisterSet setIndex); 00444 00450 TupleDescriptor& getTupleDescriptor( 00451 RegisterReference::ERegisterSet setIndex); 00452 00459 void checkPC(TProgramCounter pc, CalcYYLocType& loc) { 00460 assert(mCalc->mCode.size() > 0); 00461 if (pc >= static_cast(mCalc->mCode.size())) { 00462 ostringstream errorStr(""); 00463 errorStr << "Invalid PC " << pc << ": PC should be between 0 and " 00464 << (mCalc->mCode.size() - 1); 00465 throw CalcAssemblerException(errorStr.str(), loc); 00466 } 00467 } 00468 00476 void saveMaxPC(TProgramCounter pc) 00477 { 00478 assert(pc > 0); 00479 if (pc > mMaxPC) { 00480 mMaxPC = pc; 00481 mMaxPCLoc = getLexer().getLocation(); 00482 } 00483 } 00484 00485 protected: 00486 CalcLexer mLexer; 00487 Calculator* mCalc;
00488 00490 TupleDescriptor mRegisterSetDescriptor[RegisterReference::ELastSet]; 00491 00495 TupleData* mRegisterTupleData[RegisterReference::ELastSet]; 00498 FixedBuffer* mBuffers[RegisterReference::ELastSet]; 00499 00501 StandardTypeDescriptorFactory mTypeFactory; 00502 00504 RegisterReference::ERegisterSet mCurrentRegSet; 00505 00507 TRegisterIndex mLiteralIndex; 00508 00510 TProgramCounter mMaxPC; 00511 CalcYYLocType mMaxPCLoc; 00512 }; 00513 00514 FENNEL_END_NAMESPACE 00515 00516 #endif 00517 00518