Fennel: CalcAssembler Class Reference (original) (raw)

The CalcAssembler is responsible for taking a textual representation of a calculator program and forming a calculator. More...

#include <[CalcAssembler.h](CalcAssembler%5F8h-source.html)>

List of all members.

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
void bindRegisterValue (RegisterReference::ERegisterSet setIndex, TRegisterIndex regIndex, T value)
Binds the templated value to the specified register.
template
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 *)

Detailed Description

The CalcAssembler is responsible for taking a textual representation of a calculator program and forming a calculator.

The CalcAssembler will do the following:

  1. Create TupleDescriptors to describe all registers
  2. Create Literal, Local, and Status Tuples and bind them to the Calculator register sets
  3. Initializes literal values in the Literal Register Set
  4. Create and insert instructions into the Calculator
  5. Verifies the format of serialized programs
  6. Performs type checking The CalcAssembler is a temporal object that is used by the Calculator, with the Calculator responsible for the deallocation of any objects that are allocated by the CalcAssembler.

Definition at line 62 of file CalcAssembler.h.


Constructor & Destructor Documentation

CalcAssembler::CalcAssembler ( Calculator * calc ) [inline, explicit]

| CalcAssembler::~CalcAssembler | ( | | ) | | ------------------------------ | - | | - |


Member Function Documentation

| CalcLexer& CalcAssembler::getLexer | ( | | ) | [inline] | | --------------------------------------------------------- | - | | - | ---------- |

int CalcAssembler::assemble ( const char * program )

| 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().

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
00375 RegisterReference* regRef = NULL; 00376 switch (regType) { 00377 case STANDARD_TYPE_INT_8: 00378 regRef = new RegisterRef(setIndex, regIndex, regType); 00379 break; 00380 case STANDARD_TYPE_UINT_8: 00381 regRef = new RegisterRef(setIndex, regIndex, regType); 00382 break; 00383 case STANDARD_TYPE_INT_16: 00384 regRef = new RegisterRef(setIndex, regIndex, regType); 00385 break; 00386 case STANDARD_TYPE_UINT_16: 00387 regRef = new RegisterRef(setIndex, regIndex, regType); 00388 break; 00389 case STANDARD_TYPE_INT_32: 00390 regRef = new RegisterRef(setIndex, regIndex, regType); 00391 break; 00392 case STANDARD_TYPE_UINT_32: 00393 regRef = new RegisterRef(setIndex, regIndex, regType); 00394 break; 00395 case STANDARD_TYPE_INT_64: 00396 regRef = new RegisterRef(setIndex, regIndex, regType); 00397 break; 00398 case STANDARD_TYPE_UINT_64: 00399 regRef = new RegisterRef(setIndex, regIndex, regType); 00400 break; 00401 case STANDARD_TYPE_REAL: 00402 regRef = new RegisterRef(setIndex, regIndex, regType); 00403 break; 00404 case STANDARD_TYPE_DOUBLE: 00405 regRef = new RegisterRef(setIndex, regIndex, regType); 00406 break; 00407 case STANDARD_TYPE_BOOL: 00408 regRef = new RegisterRef(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 }

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 }

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 }

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 }

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(tupleDatum.pData))) = 00165 boost::numeric_cast(value); 00166 break; 00167 case STANDARD_TYPE_UINT_8: 00168 *(reinterpret_cast<uint8_t *>(const_cast(tupleDatum.pData))) = 00169 boost::numeric_cast(value); 00170 break; 00171 case STANDARD_TYPE_INT_16: 00172 *(reinterpret_cast<int16_t *>(const_cast(tupleDatum.pData))) = 00173 boost::numeric_cast(value); 00174 break; 00175 case STANDARD_TYPE_UINT_16: 00176 *(reinterpret_cast<uint16_t *>(const_cast(tupleDatum.pData))) = 00177 boost::numeric_cast(value); 00178 break; 00179 case STANDARD_TYPE_INT_32: 00180 *(reinterpret_cast<int32_t *>(const_cast(tupleDatum.pData))) = 00181 boost::numeric_cast(value); 00182 break; 00183 case STANDARD_TYPE_UINT_32: 00184 *(reinterpret_cast<uint32_t *>(const_cast(tupleDatum.pData))) = 00185 boost::numeric_cast(value); 00186 break; 00187 case STANDARD_TYPE_INT_64: 00188
00189
00190 if (value > std::numeric_limits::max()) { 00191 throw InvalidValueException( 00192 "bad numeric cast: overflow", type, value); 00193 } 00194 *(reinterpret_cast<int64_t *>(const_cast(tupleDatum.pData))) = 00195 boost::numeric_cast(value); 00196 break; 00197 case STANDARD_TYPE_UINT_64: 00198 *(reinterpret_cast<uint64_t *>(const_cast(tupleDatum.pData))) = 00199 boost::numeric_cast(value); 00200 break; 00201 case STANDARD_TYPE_BOOL: 00202
00203 if (value == 1) { 00204 *(reinterpret_cast<bool *>(const_cast(tupleDatum.pData))) = 00205 true; 00206 } else if (value == 0) { 00207 *(reinterpret_cast<bool *>(const_cast(tupleDatum.pData))) = 00208 false; 00209 } else { 00210
00211 throw InvalidValueException( 00212 "Boolean value should be 0 or 1", type, value); 00213 } 00214 break; 00215 default: 00216
00217 throw InvalidValueException( 00218 "Cannot assign unsigned integer", type, value); 00219 } 00220 }

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(tupleDatum.pData)); 00259 switch (type) { 00260 case STANDARD_TYPE_CHAR: 00261 case STANDARD_TYPE_BINARY: 00262
00263
00264 assert(tupleDatum.cbData == desc.cbStorage); 00265 00266
00267
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
00277 memcpy(ptr, str.data(), str.length()); 00278 break; 00279 00280 case STANDARD_TYPE_VARCHAR: 00281 case STANDARD_TYPE_VARBINARY: 00282
00283 00284
00285
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
00295 memcpy(ptr, str.data(), str.length()); 00296 tupleDatum.cbData = str.length(); 00297 break; 00298 00299 default: 00300 throw InvalidValueException("Cannot assign string", type, str); 00301 } 00302 }

| void CalcAssembler::init | ( | | ) | [protected] | | ------------------------ | - | | - | ------------- |

| 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.

Note:

This function must be called before attempting to initialize 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.

| 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.

Note:

This function must be called after all tuples have been allocated and literal values initialized

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.

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.

Parameters:

setIndex Register set index
regIndex Register index
value Value to bind to the register

Exceptions:

Note:

The assembler is only responsible for binding literal values. This function is used by bindNextLiteral for binding literal values. There should be no reason to use this function directly.

See also:

bindNextLiteral

Definition at line 303 of file CalcAssembler.h.

References FennelExcn::getMessage(), and RegisterReference::toString().

template

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.

Parameters:

value Value to bind to the register

Exceptions:

Note:

CalcYYparse calls this function to bind individual literal value as they are parsed one by one. Before calling this function, bindRegisters() should be called to allocate memory for the TupleData and bind them to the registers. After all literal values are bound, bindLiteralsDone() should be called to check that all literal registers have been initialized.

See also:

bindLiteralsDone()

bindRegisters()

Definition at line 354 of file CalcAssembler.h.

References RegisterReference::ELiteral.

| void CalcAssembler::bindLiteralDone | ( | | ) | [protected] | | ----------------------------------- | - | | - | ------------- |

Adds a register to the current register set.

Parameters:

regType type of the register to add
cbStorage space to allocate for the register (used for arrays)

Note:

Use selectRegisterSet to set the current register set

Adds a register to the specified register set.

Parameters:

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]

Returns the type of register given the set index and the register index.

Parameters:

setIndex Register set index
regIndex Register index

Returns:

Type of the register

Exceptions:

FennelExcn Exception indicating the register index is out of bounds

Definition at line 323 of file CalcAssembler.cpp.

References getRegister(), and RegisterReference::type().

Verifies that the program counter is valid.

Parameters:

pc the program counter
loc

Exceptions:

Definition at line 459 of file CalcAssembler.h.

Referenced by assemble().

00459 { 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 }

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.


| int CalcYYparse | ( | void * | | ) | [friend] | | --------------- | - | ------- | | - | ---------- |


Member Data Documentation


The documentation for this class was generated from the following files:


Generated on Mon Jun 22 04:00:27 2009 for Fennel by doxygen 1.5.1