#include <CalcAssembler.h>
Public Member Functions | |
CalcAssembler (Calculator *calc) | |
~CalcAssembler () | |
CalcLexer & | getLexer () |
int | assemble (const char *program) |
int | assemble () |
Instruction * | createInstruction (string &name, string &function, vector< RegisterReference * > &operands, CalcYYLocType &location) |
Static Public Member Functions | |
static TupleData * | createTupleData (TupleDescriptor const &tupleDes, FixedBuffer **buf) |
static RegisterReference * | createRegisterReference (RegisterReference::ERegisterSet setIndex, TRegisterIndex regIndex, StandardTypeDescriptorOrdinal regType) |
static Instruction * | createInstruction (string &name, vector< RegisterReference * > const &operands, CalcYYLocType &location) |
static Instruction * | createInstruction (string &name, RegisterReference *result, RegisterReference *operand1, RegisterReference *operand2, CalcYYLocType &location) |
static Instruction * | createInstruction (string &name, RegisterReference *result, RegisterReference *operand1, CalcYYLocType &location) |
static Instruction * | createInstruction (string &name, RegisterReference *result, CalcYYLocType &location) |
static Instruction * | createInstruction (string &name, CalcYYLocType &location) |
static Instruction * | createInstruction (string &name, TProgramCounter pc, CalcYYLocType &location) |
static Instruction * | createInstruction (string &name, TProgramCounter pc, RegisterReference *operand, CalcYYLocType &location) |
static void | setTupleDatum (StandardTypeDescriptorOrdinal type, TupleDatum &tupleDatum, TupleAttributeDescriptor &desc, double value) |
static void | setTupleDatum (StandardTypeDescriptorOrdinal type, TupleDatum &tupleDatum, TupleAttributeDescriptor &desc, uint64_t value) |
static void | setTupleDatum (StandardTypeDescriptorOrdinal type, TupleDatum &tupleDatum, TupleAttributeDescriptor &desc, int64_t value) |
static void | setTupleDatum (StandardTypeDescriptorOrdinal type, TupleDatum &tupleDatum, TupleAttributeDescriptor &desc, string value) |
static void | setTupleDatum (StandardTypeDescriptorOrdinal type, TupleDatum &tupleDatum, TupleAttributeDescriptor &desc, PConstBuffer buffer) |
Protected Member Functions | |
void | init () |
Initializes the assembler. | |
void | allocateTuples () |
Allocates memory (creating TupleData structure) for the literal, local, and status registers. | |
void | bindRegisters () |
Binds registers to the calculator CalcYYparse should call this function after parsing the register definitions and literal values to bind the TupleData to the calculator registers. | |
template<typename T> | |
void | bindRegisterValue (RegisterReference::ERegisterSet setIndex, TRegisterIndex regIndex, T value) |
Binds the templated value to the specified register. | |
template<typename T> | |
void | bindNextLiteral (T value) |
Binds the templated value to the next literal register. | |
void | bindLiteralDone () |
Finishes binding literal values to registers. | |
void | selectRegisterSet (RegisterReference::ERegisterSet setIndex) |
Sets the current register set. | |
void | addRegister (StandardTypeDescriptorOrdinal regType, uint cbStorage=0) |
Adds a register to the current register set. | |
void | addRegister (RegisterReference::ERegisterSet setIndex, StandardTypeDescriptorOrdinal regType, uint cbStorage=0) |
Adds a register to the specified register set. | |
void | addInstruction (Instruction *inst) |
Adds an instruction to the calulator. | |
TRegisterIndex | getRegisterSize (RegisterReference::ERegisterSet setIndex) |
Returns the number of registers in a register set. | |
RegisterReference * | getRegister (RegisterReference::ERegisterSet setIndex, TRegisterIndex regIndex) |
Returns a specified RegisterReference. | |
StandardTypeDescriptorOrdinal | getRegisterType (RegisterReference::ERegisterSet setIndex, TRegisterIndex regIndex) |
Returns the type of register given the set index and the register index. | |
TupleData * | getTupleData (RegisterReference::ERegisterSet setIndex) |
Returns a pointer to the TupleData for a register set. | |
TupleDescriptor & | getTupleDescriptor (RegisterReference::ERegisterSet setIndex) |
Returns the TupleDescriptoro for a register set. | |
void | checkPC (TProgramCounter pc, CalcYYLocType &loc) |
Verifies that the program counter is valid. | |
void | saveMaxPC (TProgramCounter pc) |
Saves the maximum PC. | |
Protected Attributes | |
CalcLexer | mLexer |
Lexer for the assembler. | |
Calculator * | mCalc |
Calculator to be assembled. | |
TupleDescriptor | mRegisterSetDescriptor [RegisterReference::ELastSet] |
TupleDescriptors for the register sets. | |
TupleData * | mRegisterTupleData [RegisterReference::ELastSet] |
Pointers to the tuple data Once they have been bound to the calculator, it is the calculator's responsibility to destroy the tuple data and the buffers. | |
FixedBuffer * | mBuffers [RegisterReference::ELastSet] |
Actual storage used by the CalcAssembler for the literal, local and status registers. | |
StandardTypeDescriptorFactory | mTypeFactory |
Factory used to create TupleAttributeDescriptor. | |
RegisterReference::ERegisterSet | mCurrentRegSet |
Register set that the assembler is currently parsing. | |
TRegisterIndex | mLiteralIndex |
Index of the next literal register to bind. | |
TProgramCounter | mMaxPC |
Saved information about the maximum PC. | |
CalcYYLocType | mMaxPCLoc |
Friends | |
int | CalcYYparse (void *) |
The CalcAssembler will do the following:
Definition at line 62 of file CalcAssembler.h.
CalcAssembler::CalcAssembler | ( | Calculator * | calc | ) | [inline, explicit] |
Definition at line 66 of file CalcAssembler.h.
00066 { 00067 assert(calc != NULL); 00068 mCalc = calc; 00069 }
CalcAssembler::~CalcAssembler | ( | ) |
Definition at line 34 of file CalcAssembler.cpp.
References RegisterReference::EFirstSet, RegisterReference::ELastSet, mBuffers, mCalc, Calculator::mRegisterSetBinding, and mRegisterTupleData.
00035 { 00036 for (uint i = RegisterReference::EFirstSet; 00037 i < RegisterReference::ELastSet; 00038 i++) 00039 { 00040 if (mCalc->mRegisterSetBinding[i] == NULL) { 00041 // We did NOT successfully bind this register set to the calculator 00042 // Will need to delete it on our own 00043 if (mBuffers[i]) { 00044 delete[] mBuffers[i]; 00045 } 00046 if (mRegisterTupleData[i]) { 00047 delete mRegisterTupleData[i]; 00048 } 00049 } 00050 } 00051 }
CalcLexer& CalcAssembler::getLexer | ( | ) | [inline] |
Definition at line 73 of file CalcAssembler.h.
Referenced by assemble(), bindLiteralDone(), CalcYYlex(), and getRegister().
00073 { 00074 return mLexer; 00075 }
int CalcAssembler::assemble | ( | const char * | program | ) |
Definition at line 70 of file CalcAssembler.cpp.
References assemble(), mLexer, and CalcAssemblerException::setCode().
Referenced by Calculator::assemble().
00071 { 00072 int res = 0; 00073 istringstream istr(program); 00074 mLexer.switch_streams(&istr, 0); 00075 try { 00076 assemble(); 00077 } catch (CalcAssemblerException& ex) { 00078 ex.setCode(program); 00079 throw ex; 00080 } 00081 00082 return res; 00083 }
int CalcAssembler::assemble | ( | ) |
Definition at line 85 of file CalcAssembler.cpp.
References CalcYYparse, checkPC(), getLexer(), CalcLexer::getLocation(), FennelExcn::getMessage(), mCalc, Calculator::mIsAssembling, CalcAssemblerException::mLocValid, mMaxPC, mMaxPCLoc, and CalcAssemblerException::setLocation().
Referenced by assemble().
00086 { 00087 int res = 0; 00088 try { 00089 mCalc->mIsAssembling = true; 00090 res = CalcYYparse((void*) this); 00091 if (res != 0) { 00092 throw CalcAssemblerException( 00093 "Error assembling program", getLexer().getLocation()); 00094 } 00095 00096 // Done assembling - let's check the maximum PC (used in Jump 00097 // instruction) 00098 checkPC(mMaxPC, mMaxPCLoc); 00099 } catch (CalcAssemblerException& ex) { 00100 if (!ex.mLocValid) { 00101 ex.setLocation(getLexer().getLocation()); 00102 } 00103 throw ex; 00104 } catch (FennelExcn& ex) { 00105 throw CalcAssemblerException(ex.getMessage(), getLexer().getLocation()); 00106 } catch (std::exception& ex) { 00107 throw CalcAssemblerException(ex.what(), getLexer().getLocation()); 00108 } 00109 00110 return res; 00111 }
TupleData * CalcAssembler::createTupleData | ( | TupleDescriptor const & | tupleDes, | |
FixedBuffer ** | buf | |||
) | [static] |
Definition at line 456 of file CalcAssembler.cpp.
References TupleAccessor::compute(), FixedBuffer, TupleAccessor::getMaxByteCount(), TupleAccessor::setCurrentTupleBuf(), TUPLE_FORMAT_ALL_FIXED, and TupleAccessor::unmarshal().
Referenced by allocateTuples(), CalcAssemblerTestCase::assemble(), and CalcAssemblerTestCase::test().
00459 { 00460 assert(buf != NULL); 00461 00462 /* Prepare tuples - should only do this for literal/local */ 00463 /* Compute memory layout and access */ 00464 TupleAccessor tupleAccessor; 00465 tupleAccessor.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED); 00466 00467 int maxByteCount = tupleAccessor.getMaxByteCount(); 00468 00469 /* Allocate memory */ 00470 *buf = new FixedBuffer[maxByteCount]; 00471 00472 /* Zero the memory. */ 00473 memset(*buf, 0, maxByteCount); 00474 00475 /* Link memory - Who will delete this????? */ 00476 tupleAccessor.setCurrentTupleBuf(*buf, false); 00477 00478 /* Create Tuple Data - to be deleted by the calculator */ 00479 TupleData* pTupleData = new TupleData(tupleDesc); 00480 00481 /* Link Tuple Data with Tuple Accessor memory */ 00482 tupleAccessor.unmarshal(*pTupleData); 00483 return pTupleData; 00484 }
RegisterReference * CalcAssembler::createRegisterReference | ( | RegisterReference::ERegisterSet | setIndex, | |
TRegisterIndex | regIndex, | |||
StandardTypeDescriptorOrdinal | regType | |||
) | [static] |
Definition at line 369 of file CalcAssembler.cpp.
References STANDARD_TYPE_BINARY, STANDARD_TYPE_BOOL, STANDARD_TYPE_CHAR, STANDARD_TYPE_DOUBLE, STANDARD_TYPE_INT_16, STANDARD_TYPE_INT_32, STANDARD_TYPE_INT_64, STANDARD_TYPE_INT_8, STANDARD_TYPE_REAL, STANDARD_TYPE_UINT_16, STANDARD_TYPE_UINT_32, STANDARD_TYPE_UINT_64, STANDARD_TYPE_UINT_8, STANDARD_TYPE_VARBINARY, STANDARD_TYPE_VARCHAR, and RegisterReference::toString().
00373 { 00374 // TODO: check setIndex and regIndex 00375 RegisterReference* regRef = NULL; 00376 switch (regType) { 00377 case STANDARD_TYPE_INT_8: 00378 regRef = new RegisterRef<int8_t>(setIndex, regIndex, regType); 00379 break; 00380 case STANDARD_TYPE_UINT_8: 00381 regRef = new RegisterRef<uint8_t>(setIndex, regIndex, regType); 00382 break; 00383 case STANDARD_TYPE_INT_16: 00384 regRef = new RegisterRef<int16_t>(setIndex, regIndex, regType); 00385 break; 00386 case STANDARD_TYPE_UINT_16: 00387 regRef = new RegisterRef<uint16_t>(setIndex, regIndex, regType); 00388 break; 00389 case STANDARD_TYPE_INT_32: 00390 regRef = new RegisterRef<int32_t>(setIndex, regIndex, regType); 00391 break; 00392 case STANDARD_TYPE_UINT_32: 00393 regRef = new RegisterRef<uint32_t>(setIndex, regIndex, regType); 00394 break; 00395 case STANDARD_TYPE_INT_64: 00396 regRef = new RegisterRef<int64_t>(setIndex, regIndex, regType); 00397 break; 00398 case STANDARD_TYPE_UINT_64: 00399 regRef = new RegisterRef<uint64_t>(setIndex, regIndex, regType); 00400 break; 00401 case STANDARD_TYPE_REAL: 00402 regRef = new RegisterRef<float>(setIndex, regIndex, regType); 00403 break; 00404 case STANDARD_TYPE_DOUBLE: 00405 regRef = new RegisterRef<double>(setIndex, regIndex, regType); 00406 break; 00407 case STANDARD_TYPE_BOOL: 00408 regRef = new RegisterRef<bool>(setIndex, regIndex, regType); 00409 break; 00410 case STANDARD_TYPE_CHAR: 00411 case STANDARD_TYPE_VARCHAR: 00412 regRef = new RegisterRef<char*>(setIndex, regIndex, regType); 00413 break; 00414 case STANDARD_TYPE_BINARY: 00415 case STANDARD_TYPE_VARBINARY: 00416 regRef = new RegisterRef<int8_t*>(setIndex, regIndex, regType); 00417 break; 00418 default: 00419 ostringstream errorStr(""); 00420 errorStr << "Error creating register reference for " 00421 << RegisterReference::toString(setIndex, regIndex) << ": "; 00422 errorStr << "Unsupported register type " << regType; 00423 throw CalcAssemblerException(errorStr.str()); 00424 break; 00425 } 00426 return regRef; 00427 }
static Instruction* CalcAssembler::createInstruction | ( | string & | name, | |
vector< RegisterReference * > const & | operands, | |||
CalcYYLocType & | location | |||
) | [inline, static] |
Definition at line 93 of file CalcAssembler.h.
References InstructionFactory::createInstruction(), and FennelExcn::getMessage().
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 }
static Instruction* CalcAssembler::createInstruction | ( | string & | name, | |
RegisterReference * | result, | |||
RegisterReference * | operand1, | |||
RegisterReference * | operand2, | |||
CalcYYLocType & | location | |||
) | [inline, static] |
Definition at line 124 of file CalcAssembler.h.
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 }
static Instruction* CalcAssembler::createInstruction | ( | string & | name, | |
RegisterReference * | result, | |||
RegisterReference * | operand1, | |||
CalcYYLocType & | location | |||
) | [inline, static] |
Definition at line 139 of file CalcAssembler.h.
00144 { 00145 vector<RegisterReference*> operands; 00146 operands.push_back(result); 00147 operands.push_back(operand1); 00148 return createInstruction(name, operands, location); 00149 }
static Instruction* CalcAssembler::createInstruction | ( | string & | name, | |
RegisterReference * | result, | |||
CalcYYLocType & | location | |||
) | [inline, static] |
Definition at line 151 of file CalcAssembler.h.
00155 { 00156 vector<RegisterReference*> operands; 00157 operands.push_back(result); 00158 return createInstruction(name, operands, location); 00159 }
static Instruction* CalcAssembler::createInstruction | ( | string & | name, | |
CalcYYLocType & | location | |||
) | [inline, static] |
Definition at line 161 of file CalcAssembler.h.
00164 { 00165 vector<RegisterReference*> operands; 00166 return createInstruction(name, operands, location); 00167 }
static Instruction* CalcAssembler::createInstruction | ( | string & | name, | |
TProgramCounter | pc, | |||
CalcYYLocType & | location | |||
) | [inline, static] |
Definition at line 169 of file CalcAssembler.h.
00173 { 00174 return createInstruction(name, pc, NULL, location); 00175 }
static Instruction* CalcAssembler::createInstruction | ( | string & | name, | |
TProgramCounter | pc, | |||
RegisterReference * | operand, | |||
CalcYYLocType & | location | |||
) | [inline, static] |
Definition at line 178 of file CalcAssembler.h.
References InstructionFactory::createInstruction(), FennelExcn::getMessage(), and RegisterReference::toString().
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 }
Instruction* CalcAssembler::createInstruction | ( | string & | name, | |
string & | function, | |||
vector< RegisterReference * > & | operands, | |||
CalcYYLocType & | location | |||
) | [inline] |
Definition at line 205 of file CalcAssembler.h.
References InstructionSignature::compute(), InstructionFactory::createInstruction(), and FennelExcn::getMessage().
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 }
void CalcAssembler::setTupleDatum | ( | StandardTypeDescriptorOrdinal | type, | |
TupleDatum & | tupleDatum, | |||
TupleAttributeDescriptor & | desc, | |||
double | value | |||
) | [static] |
Definition at line 122 of file CalcAssembler.cpp.
References TupleDatum::pData, STANDARD_TYPE_DOUBLE, and STANDARD_TYPE_REAL.
00127 { 00128 switch (type) { 00129 case STANDARD_TYPE_REAL: 00130 00131 *(reinterpret_cast<float *>(const_cast<PBuffer>(tupleDatum.pData))) = 00132 boost::numeric_cast<float>(value); 00133 00134 // Check for underflow where the value becomes 0 00135 // NOTE: Underflows that causes precision loss but does not become 0 00136 // are ignored for now. 00137 if ((value != 0) && 00138 (*(reinterpret_cast<float *>(const_cast<PBuffer>(tupleDatum.pData))) 00139 == 0)) 00140 { 00141 throw InvalidValueException<double>( 00142 "bad numeric cast: underflow", type, value); 00143 } 00144 break; 00145 case STANDARD_TYPE_DOUBLE: 00146 *(reinterpret_cast<double *>(const_cast<PBuffer>(tupleDatum.pData))) = 00147 boost::numeric_cast<double>(value); 00148 break; 00149 default: 00150 // Invalid real type - horrible, horrible 00151 throw InvalidValueException<double>( 00152 "Cannot assign double", type, value); 00153 } 00154 }
void CalcAssembler::setTupleDatum | ( | StandardTypeDescriptorOrdinal | type, | |
TupleDatum & | tupleDatum, | |||
TupleAttributeDescriptor & | desc, | |||
uint64_t | value | |||
) | [static] |
Definition at line 156 of file CalcAssembler.cpp.
References max(), TupleDatum::pData, STANDARD_TYPE_BOOL, STANDARD_TYPE_INT_16, STANDARD_TYPE_INT_32, STANDARD_TYPE_INT_64, STANDARD_TYPE_INT_8, STANDARD_TYPE_UINT_16, STANDARD_TYPE_UINT_32, STANDARD_TYPE_UINT_64, and STANDARD_TYPE_UINT_8.
00161 { 00162 switch (type) { 00163 case STANDARD_TYPE_INT_8: 00164 *(reinterpret_cast<int8_t *>(const_cast<PBuffer>(tupleDatum.pData))) = 00165 boost::numeric_cast<int8_t>(value); 00166 break; 00167 case STANDARD_TYPE_UINT_8: 00168 *(reinterpret_cast<uint8_t *>(const_cast<PBuffer>(tupleDatum.pData))) = 00169 boost::numeric_cast<uint8_t>(value); 00170 break; 00171 case STANDARD_TYPE_INT_16: 00172 *(reinterpret_cast<int16_t *>(const_cast<PBuffer>(tupleDatum.pData))) = 00173 boost::numeric_cast<int16_t>(value); 00174 break; 00175 case STANDARD_TYPE_UINT_16: 00176 *(reinterpret_cast<uint16_t *>(const_cast<PBuffer>(tupleDatum.pData))) = 00177 boost::numeric_cast<uint16_t>(value); 00178 break; 00179 case STANDARD_TYPE_INT_32: 00180 *(reinterpret_cast<int32_t *>(const_cast<PBuffer>(tupleDatum.pData))) = 00181 boost::numeric_cast<int32_t>(value); 00182 break; 00183 case STANDARD_TYPE_UINT_32: 00184 *(reinterpret_cast<uint32_t *>(const_cast<PBuffer>(tupleDatum.pData))) = 00185 boost::numeric_cast<uint32_t>(value); 00186 break; 00187 case STANDARD_TYPE_INT_64: 00188 // Explicitly check for overflow of int64_t because the boost 00189 // boost::numeric_cast does not throw an exception in this case 00190 if (value > std::numeric_limits<int64_t>::max()) { 00191 throw InvalidValueException<uint64_t>( 00192 "bad numeric cast: overflow", type, value); 00193 } 00194 *(reinterpret_cast<int64_t *>(const_cast<PBuffer>(tupleDatum.pData))) = 00195 boost::numeric_cast<int64_t>(value); 00196 break; 00197 case STANDARD_TYPE_UINT_64: 00198 *(reinterpret_cast<uint64_t *>(const_cast<PBuffer>(tupleDatum.pData))) = 00199 boost::numeric_cast<uint64_t>(value); 00200 break; 00201 case STANDARD_TYPE_BOOL: 00202 // Booleans are specifed as 0 or 1 00203 if (value == 1) { 00204 *(reinterpret_cast<bool *>(const_cast<PBuffer>(tupleDatum.pData))) = 00205 true; 00206 } else if (value == 0) { 00207 *(reinterpret_cast<bool *>(const_cast<PBuffer>(tupleDatum.pData))) = 00208 false; 00209 } else { 00210 // Invalid boolean value 00211 throw InvalidValueException<uint64_t>( 00212 "Boolean value should be 0 or 1", type, value); 00213 } 00214 break; 00215 default: 00216 // Invalid unsigned integer type - horrible, horrible 00217 throw InvalidValueException<uint64_t>( 00218 "Cannot assign unsigned integer", type, value); 00219 } 00220 }
void CalcAssembler::setTupleDatum | ( | StandardTypeDescriptorOrdinal | type, | |
TupleDatum & | tupleDatum, | |||
TupleAttributeDescriptor & | desc, | |||
int64_t | value | |||
) | [static] |
Definition at line 222 of file CalcAssembler.cpp.
References TupleDatum::pData, STANDARD_TYPE_INT_16, STANDARD_TYPE_INT_32, STANDARD_TYPE_INT_64, and STANDARD_TYPE_INT_8.
00227 { 00228 switch (type) { 00229 case STANDARD_TYPE_INT_8: 00230 *(reinterpret_cast<int8_t *>(const_cast<PBuffer>(tupleDatum.pData))) = 00231 boost::numeric_cast<int8_t>(value); 00232 break; 00233 case STANDARD_TYPE_INT_16: 00234 *(reinterpret_cast<int16_t *>(const_cast<PBuffer>(tupleDatum.pData))) = 00235 boost::numeric_cast<int16_t>(value); 00236 break; 00237 case STANDARD_TYPE_INT_32: 00238 *(reinterpret_cast<int32_t *>(const_cast<PBuffer>(tupleDatum.pData))) = 00239 boost::numeric_cast<int32_t>(value); 00240 break; 00241 case STANDARD_TYPE_INT_64: 00242 *(reinterpret_cast<int64_t *>(const_cast<PBuffer>(tupleDatum.pData))) = 00243 boost::numeric_cast<int64_t>(value); 00244 break; 00245 default: 00246 throw InvalidValueException<int64_t>( 00247 "Cannot assign signed integer", type, value); 00248 } 00249 }
void CalcAssembler::setTupleDatum | ( | StandardTypeDescriptorOrdinal | type, | |
TupleDatum & | tupleDatum, | |||
TupleAttributeDescriptor & | desc, | |||
string | value | |||
) | [static] |
Definition at line 251 of file CalcAssembler.cpp.
References TupleDatum::cbData, TupleAttributeDescriptor::cbStorage, TupleDatum::pData, STANDARD_TYPE_BINARY, STANDARD_TYPE_CHAR, STANDARD_TYPE_VARBINARY, and STANDARD_TYPE_VARCHAR.
00256 { 00257 ostringstream errorStr; 00258 char* ptr = reinterpret_cast<char*>(const_cast<PBuffer>(tupleDatum.pData)); 00259 switch (type) { 00260 case STANDARD_TYPE_CHAR: 00261 case STANDARD_TYPE_BINARY: 00262 // Fixed length storage 00263 // For fixed length arrays, cbData should be the same as cbStorage 00264 assert(tupleDatum.cbData == desc.cbStorage); 00265 00266 // Fixed width arrays should be padded to be the specifed width 00267 // Verify that the number of bytes matches the specified width 00268 if (str.length() != tupleDatum.cbData) { 00269 ostringstream ostr(""); 00270 ostr << "String length " << str.length() 00271 << " not equal to fixed size array of length " 00272 << tupleDatum.cbData; 00273 throw FennelExcn(ostr.str()); 00274 } 00275 00276 // Copy the string 00277 memcpy(ptr, str.data(), str.length()); 00278 break; 00279 00280 case STANDARD_TYPE_VARCHAR: 00281 case STANDARD_TYPE_VARBINARY: 00282 // Variable length storage 00283 00284 // Verify that there the length of the string is not larger than the 00285 // maximum length 00286 if (str.length() > desc.cbStorage) { 00287 ostringstream ostr(""); 00288 ostr << "String length " << str.length() 00289 << " too long for variabled sized array of maximum length " 00290 << desc.cbStorage; 00291 throw FennelExcn(ostr.str()); 00292 } 00293 00294 // Copy the string 00295 memcpy(ptr, str.data(), str.length()); 00296 tupleDatum.cbData = str.length(); 00297 break; 00298 00299 default: 00300 throw InvalidValueException<string>("Cannot assign string", type, str); 00301 } 00302 }
void CalcAssembler::setTupleDatum | ( | StandardTypeDescriptorOrdinal | type, | |
TupleDatum & | tupleDatum, | |||
TupleAttributeDescriptor & | desc, | |||
PConstBuffer | buffer | |||
) | [static] |
Definition at line 113 of file CalcAssembler.cpp.
References TupleDatum::pData.
00118 { 00119 tupleDatum.pData = buffer; 00120 }
void CalcAssembler::init | ( | ) | [protected] |
Initializes the assembler.
Definition at line 53 of file CalcAssembler.cpp.
References RegisterReference::EFirstSet, RegisterReference::ELastSet, RegisterReference::EUnknown, mBuffers, mCurrentRegSet, mLiteralIndex, mMaxPC, mRegisterSetDescriptor, and mRegisterTupleData.
00054 { 00055 mCurrentRegSet = RegisterReference::EUnknown; 00056 mLiteralIndex = 0; 00057 mMaxPC = 0; 00058 00059 /* Initialize tuple descriptors and tuple data */ 00060 for (uint i = RegisterReference::EFirstSet; 00061 i < RegisterReference::ELastSet; 00062 i++) 00063 { 00064 mRegisterSetDescriptor[i].clear(); 00065 mRegisterTupleData[i] = NULL; 00066 mBuffers[i] = NULL; 00067 } 00068 }
void CalcAssembler::allocateTuples | ( | ) | [protected] |
Allocates memory (creating TupleData structure) for the literal, local, and status registers.
CalcYYparse should call this function after parsing the register definitions and before parsing the literal values.
Definition at line 487 of file CalcAssembler.cpp.
References createTupleData(), RegisterReference::EFirstSet, RegisterReference::ELastSet, RegisterReference::ELiteral, RegisterReference::ELocal, RegisterReference::EStatus, mBuffers, mRegisterSetDescriptor, and mRegisterTupleData.
00488 { 00489 /* Allocate memory for the tuples */ 00490 for (uint reg = RegisterReference::EFirstSet; 00491 reg < RegisterReference::ELastSet; 00492 reg++) 00493 { 00494 /* Verify that tuples have not already been allocated */ 00495 assert(mRegisterTupleData[reg] == NULL); 00496 assert(mBuffers[reg] == NULL); 00497 00498 if (reg == RegisterReference::ELiteral || 00499 reg == RegisterReference::EStatus || 00500 reg == RegisterReference::ELocal) 00501 { 00502 /* Allocate tuple for literal/status/local registers */ 00503 mRegisterTupleData[reg] = createTupleData( 00504 mRegisterSetDescriptor[reg], 00505 &mBuffers[reg]); 00506 } 00507 00508 /* Do not need to create input/output tuple data */ 00509 } 00510 }
void CalcAssembler::bindRegisters | ( | ) | [protected] |
Binds registers to the calculator CalcYYparse should call this function after parsing the register definitions and literal values to bind the TupleData to the calculator registers.
Definition at line 512 of file CalcAssembler.cpp.
References Calculator::bind(), RegisterReference::EInput, RegisterReference::ELiteral, RegisterReference::ELocal, RegisterReference::EOutput, RegisterReference::EStatus, getTupleData(), getTupleDescriptor(), mBuffers, Calculator::mBuffers, mCalc, and Calculator::mRegisterSetDescriptor.
00513 { 00514 /* Bind registers to calculator */ 00515 RegisterReference::ERegisterSet reg; 00516 00517 /* Bind literal */ 00518 reg = RegisterReference::ELiteral; 00519 mCalc->mBuffers.push_back(mBuffers[reg]); 00520 mCalc->bind(reg, getTupleData(reg), getTupleDescriptor(reg)); 00521 00522 /* Bind status */ 00523 reg = RegisterReference::EStatus; 00524 mCalc->mBuffers.push_back(mBuffers[reg]); 00525 mCalc->bind(reg, getTupleData(reg), getTupleDescriptor(reg)); 00526 00527 /* Bind local */ 00528 reg = RegisterReference::ELocal; 00529 mCalc->mBuffers.push_back(mBuffers[reg]); 00530 mCalc->bind(reg, getTupleData(reg), getTupleDescriptor(reg)); 00531 00532 /* Do not create input/output tuple data - we still need to bind 00533 the tuple descriptor */ 00534 reg = RegisterReference::EInput; 00535 mCalc->mRegisterSetDescriptor[reg] = 00536 new TupleDescriptor(getTupleDescriptor(reg)); 00537 00538 reg = RegisterReference::EOutput; 00539 mCalc->mRegisterSetDescriptor[reg] = 00540 new TupleDescriptor(getTupleDescriptor(reg)); 00541 }
void CalcAssembler::bindRegisterValue | ( | RegisterReference::ERegisterSet | setIndex, | |
TRegisterIndex | regIndex, | |||
T | value | |||
) | [inline, protected] |
Binds the templated value to the specified register.
A CalcAssemblerException with the location of the current token is thrown if there is an error binding the value to the register.
setIndex | Register set index | |
regIndex | Register index | |
value | Value to bind to the register |
CalcAssemblerException |
Definition at line 303 of file CalcAssembler.h.
References FennelExcn::getMessage(), and RegisterReference::toString().
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 // Just pass this exception up 00318 throw ex; 00319 } catch (FennelExcn& ex) { 00320 // Other exception - let's make the error clearer 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 // Other exception - let's make the error clearer 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 }
void CalcAssembler::bindNextLiteral | ( | T | value | ) | [inline, protected] |
Binds the templated value to the next literal register.
A CalcAssemblerException with the location of the current token is thrown if there is an error binding the value to the register.
value | Value to bind to the register |
CalcAssemblerException |
Definition at line 354 of file CalcAssembler.h.
References RegisterReference::ELiteral.
00355 { 00356 bindRegisterValue<T>(RegisterReference::ELiteral, mLiteralIndex, value); 00357 mLiteralIndex++; 00358 }
void CalcAssembler::bindLiteralDone | ( | ) | [protected] |
Finishes binding literal values to registers.
This function should be called by CalcYYparse after all parsing literal values to check that all literal registers have been initialized.
Definition at line 304 of file CalcAssembler.cpp.
References RegisterReference::ELiteral, getLexer(), CalcLexer::getLocation(), getRegisterSize(), and mLiteralIndex.
00305 { 00306 // We are done with binding literals 00307 // Check that all literals have been a value 00308 TRegisterIndex regSize = getRegisterSize(RegisterReference::ELiteral); 00309 if (mLiteralIndex != regSize) { 00310 ostringstream errorStr(""); 00311 errorStr << "Error binding literals: " << regSize 00312 << " literal registers, only " << mLiteralIndex 00313 << " registers bound"; 00314 throw CalcAssemblerException(errorStr.str(), getLexer().getLocation()); 00315 } 00316 }
void CalcAssembler::selectRegisterSet | ( | RegisterReference::ERegisterSet | setIndex | ) | [protected] |
Sets the current register set.
setIndex | Register set index |
Definition at line 318 of file CalcAssembler.cpp.
References mCurrentRegSet.
00319 { 00320 mCurrentRegSet = setIndex; 00321 }
void CalcAssembler::addRegister | ( | StandardTypeDescriptorOrdinal | regType, | |
uint | cbStorage = 0 | |||
) | [protected] |
Adds a register to the current register set.
regType | type of the register to add | |
cbStorage | space to allocate for the register (used for arrays) |
void CalcAssembler::addRegister | ( | RegisterReference::ERegisterSet | setIndex, | |
StandardTypeDescriptorOrdinal | regType, | |||
uint | cbStorage = 0 | |||
) | [protected] |
Adds a register to the specified register set.
setIndex | Register set index | |
regType | type of the register to add | |
cbStorage | space to allocate for the register (used for arrays) |
void CalcAssembler::addInstruction | ( | Instruction * | inst | ) | [protected] |
Adds an instruction to the calulator.
inst | Instruction to add |
Definition at line 543 of file CalcAssembler.cpp.
References Calculator::appendInstruction(), and mCalc.
00544 { 00545 assert(inst != NULL); 00546 mCalc->appendInstruction(inst); 00547 }
TRegisterIndex CalcAssembler::getRegisterSize | ( | RegisterReference::ERegisterSet | setIndex | ) | [protected] |
Returns the number of registers in a register set.
setIndex | Register set index |
Definition at line 348 of file CalcAssembler.cpp.
References RegisterReference::ELastSet, mCalc, and Calculator::mRegisterRef.
Referenced by bindLiteralDone(), and getRegister().
00350 { 00351 assert(setIndex < RegisterReference::ELastSet); 00352 return mCalc->mRegisterRef[setIndex].size(); 00353 }
RegisterReference * CalcAssembler::getRegister | ( | RegisterReference::ERegisterSet | setIndex, | |
TRegisterIndex | regIndex | |||
) | [protected] |
Returns a specified RegisterReference.
setIndex | Register set index | |
regIndex | Register index |
FennelExcn | Exception indicating the register index is out of bounds |
Definition at line 332 of file CalcAssembler.cpp.
References RegisterReference::ELastSet, getLexer(), CalcLexer::getLocation(), getRegisterSize(), RegisterReference::getSetName(), mCalc, and Calculator::mRegisterRef.
Referenced by getRegisterType().
00335 { 00336 assert(setIndex < RegisterReference::ELastSet); 00337 TRegisterIndex size = getRegisterSize(setIndex); 00338 if (regIndex >= size) { 00339 ostringstream errorStr(""); 00340 errorStr << "Register index " << regIndex << " out of bounds."; 00341 errorStr << " Register set " << RegisterReference::getSetName(setIndex) 00342 << " has " << size << " registers."; 00343 throw CalcAssemblerException(errorStr.str(), getLexer().getLocation()); 00344 } 00345 return mCalc->mRegisterRef[setIndex][regIndex]; 00346 }
StandardTypeDescriptorOrdinal CalcAssembler::getRegisterType | ( | RegisterReference::ERegisterSet | setIndex, | |
TRegisterIndex | regIndex | |||
) | [protected] |
Returns the type of register given the set index and the register index.
setIndex | Register set index | |
regIndex | Register index |
FennelExcn | Exception indicating the register index is out of bounds |
Definition at line 323 of file CalcAssembler.cpp.
References getRegister(), and RegisterReference::type().
00326 { 00327 RegisterReference* regRef = getRegister(setIndex, regIndex); 00328 assert(regRef != NULL); 00329 return regRef->type(); 00330 }
TupleData * CalcAssembler::getTupleData | ( | RegisterReference::ERegisterSet | setIndex | ) | [protected] |
Returns a pointer to the TupleData for a register set.
setIndex | Register set index |
Definition at line 355 of file CalcAssembler.cpp.
References RegisterReference::ELastSet, and mRegisterTupleData.
Referenced by bindRegisters().
00356 { 00357 assert(setIndex < RegisterReference::ELastSet); 00358 return mRegisterTupleData[setIndex]; 00359 }
TupleDescriptor & CalcAssembler::getTupleDescriptor | ( | RegisterReference::ERegisterSet | setIndex | ) | [protected] |
Returns the TupleDescriptoro for a register set.
setIndex | Register set index |
Definition at line 361 of file CalcAssembler.cpp.
References RegisterReference::ELastSet, and mRegisterSetDescriptor.
Referenced by bindRegisters().
00363 { 00364 assert(setIndex < RegisterReference::ELastSet); 00365 return mRegisterSetDescriptor[setIndex]; 00366 }
void CalcAssembler::checkPC | ( | TProgramCounter | pc, | |
CalcYYLocType & | loc | |||
) | [inline, protected] |
Verifies that the program counter is valid.
pc | the program counter | |
loc |
CalcAssemblerException | Exception indicating that the PC is invalid |
Definition at line 459 of file CalcAssembler.h.
Referenced by assemble().
00459 { 00460 assert(mCalc->mCode.size() > 0); 00461 if (pc >= static_cast<TProgramCounter>(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 }
void CalcAssembler::saveMaxPC | ( | TProgramCounter | pc | ) | [inline, protected] |
Saves the maximum PC.
It is impossible to check the PC until we have assembled the entire program and it is too much trouble to keep track of every PC to see if they are valid or not. Instead, we will just keep track of the maximum PC, and if it is valid, then all PCs should be valid. If it is not, then we will just report on that PC.
Definition at line 476 of file CalcAssembler.h.
00477 { 00478 assert(pc > 0); 00479 if (pc > mMaxPC) { 00480 mMaxPC = pc; 00481 mMaxPCLoc = getLexer().getLocation(); 00482 } 00483 }
int CalcYYparse | ( | void * | ) | [friend] |
Referenced by assemble().
CalcLexer CalcAssembler::mLexer [protected] |
Calculator* CalcAssembler::mCalc [protected] |
Calculator to be assembled.
Definition at line 487 of file CalcAssembler.h.
Referenced by addInstruction(), assemble(), bindRegisters(), getRegister(), getRegisterSize(), and ~CalcAssembler().
TupleDescriptor CalcAssembler::mRegisterSetDescriptor[RegisterReference::ELastSet] [protected] |
TupleDescriptors for the register sets.
Definition at line 490 of file CalcAssembler.h.
Referenced by allocateTuples(), getTupleDescriptor(), and init().
TupleData* CalcAssembler::mRegisterTupleData[RegisterReference::ELastSet] [protected] |
Pointers to the tuple data Once they have been bound to the calculator, it is the calculator's responsibility to destroy the tuple data and the buffers.
Definition at line 495 of file CalcAssembler.h.
Referenced by allocateTuples(), getTupleData(), init(), and ~CalcAssembler().
FixedBuffer* CalcAssembler::mBuffers[RegisterReference::ELastSet] [protected] |
Actual storage used by the CalcAssembler for the literal, local and status registers.
Definition at line 498 of file CalcAssembler.h.
Referenced by allocateTuples(), bindRegisters(), init(), and ~CalcAssembler().
Register set that the assembler is currently parsing.
Definition at line 504 of file CalcAssembler.h.
Referenced by init(), and selectRegisterSet().
TRegisterIndex CalcAssembler::mLiteralIndex [protected] |
Index of the next literal register to bind.
Definition at line 507 of file CalcAssembler.h.
Referenced by bindLiteralDone(), and init().
TProgramCounter CalcAssembler::mMaxPC [protected] |
Saved information about the maximum PC.
Definition at line 510 of file CalcAssembler.h.
Referenced by assemble(), and init().
CalcYYLocType CalcAssembler::mMaxPCLoc [protected] |