Fennel: /home/pub/open/dev/fennel/calctest/CalcAssemblerTest.cpp 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 #include "fennel/common/CommonPreamble.h" 00024 #include "fennel/test/TestBase.h" 00025 #include "fennel/common/TraceSource.h" 00026 00027 #include "fennel/tuple/TupleDataWithBuffer.h" 00028 #include "fennel/tuple/TuplePrinter.h" 00029 #include "fennel/calculator/CalcCommon.h" 00030 #include "fennel/calculator/CalcAssembler.h" 00031 #include "fennel/calculator/StringToHex.h" 00032 #include "fennel/common/FennelExcn.h" 00033 00034 #include <boost/test/test_tools.hpp> 00035 00036 #include <fstream.h> 00037 #include <strstream.h> 00038 #include <iomanip.h> 00039 00040 using namespace fennel; 00041 00042 bool verbose = false; 00043 bool showProgram = true; 00044 00045 00046 #define USING_NOISY_ARITHMETIC (1) 00047 00048 00049 template 00050 class RegisterTestInfo 00051 { 00052 public: 00053 enum ERegisterCheck { 00054 EINVALID = -1, 00055 ENULL = 0, 00056 EVALID = 1 00057 }; 00058 00059 explicit 00060 RegisterTestInfo(string desc, TProgramCounter pc): 00061 mDesc(desc), mCheckValue(EINVALID), mPC(pc) 00062 { 00063 } 00064 00065 explicit 00066 RegisterTestInfo(string desc, T v, TProgramCounter pc): 00067 mDesc(desc), mValue(v), mCheckValue(EVALID), mPC(pc) 00068 { 00069 } 00070 00071 explicit 00072 RegisterTestInfo(string desc, T* pV, TProgramCounter pc): 00073 mDesc(desc), mPC(pc) 00074 { 00075 if (pV == NULL) { 00076 mCheckValue = ENULL; 00077 } else { 00078 mValue = pV; 00079 mCheckValue = EVALID; 00080 } 00081 } 00082 00083 void setTupleDatum(TupleDatum& datum) 00084 { 00085 switch (mCheckValue) { 00086 case EINVALID: 00087
00088 break; 00089 case ENULL: 00090
00091 datum.pData = NULL; 00092 break; 00093 case EVALID: 00094 assert(datum.pData != NULL); 00095 (reinterpret_cast<T*>(const_cast(datum.pData))) = mValue; 00096 break; 00097 default: 00098 permAssert(false); 00099 } 00100 } 00101 00102 bool checkTupleDatum(TupleDatum& datum) 00103 { 00104 switch (mCheckValue) { 00105 case EINVALID: 00106
00107 return true; 00108 case ENULL: 00109
00110 return (datum.pData == NULL); 00111 case EVALID: 00112 if (datum.pData == NULL) { 00113 return false; 00114 } 00115 return (reinterpret_cast<const T*>(datum.pData) == mValue); 00116 default: 00117 permAssert(false); 00118 } 00119 } 00120 00121 string toString() 00122 { 00123 ostringstream ostr(""); 00124 switch (mCheckValue) { 00125 case EINVALID: 00126 break; 00127 case ENULL: 00128 ostr << "(NULL) for test "; 00129 break; 00130 case EVALID: 00131 ostr << "(" << mValue << ") for test "; 00132 break; 00133 default: 00134 permAssert(false); 00135 } 00136 00137 ostr << "'" << mDesc << "'" << " at PC=" << mPC; 00138 return ostr.str(); 00139 } 00140 00141 ~RegisterTestInfo() {} 00142 00143
00144 string mDesc; 00145 00146
00147 T mValue; 00148 00149
00150 ERegisterCheck mCheckValue; 00151 00152
00153 TProgramCounter mPC; 00154 }; 00155 00156 class CalcChecker 00157 { 00158 public: 00159 virtual ~CalcChecker() {} 00160 virtual bool checkResult(Calculator& calc, TupleData& output) = 0; 00161 }; 00162 00163 template 00164 class CalcTestInfo : public CalcChecker 00165 { 00166 public: 00167 explicit 00168 CalcTestInfo(StandardTypeDescriptorOrdinal type) 00169 : typeOrdinal(type) {} 00170 virtual ~CalcTestInfo() {} 00171 00172 void add(string desc, T
pV, TProgramCounter pc, uint line = 0) 00173 { 00174 if (line) { 00175 ostringstream ostr(""); 00176 ostr << " Line: " << line; 00177 desc += ostr.str(); 00178 } 00179 mOutRegInfo.push_back(RegisterTestInfo(desc, pV, pc)); 00180 } 00181 00182 void add(string desc, T v, TProgramCounter pc, uint line = 0) 00183 { 00184 if (line) { 00185 ostringstream ostr(""); 00186 ostr << " Line: " << line; 00187 desc += ostr.str(); 00188 } 00189 mOutRegInfo.push_back(RegisterTestInfo(desc, v, pc)); 00190 } 00191 00192 void addRegister(string desc, TProgramCounter pc) 00193 { 00194 mOutRegInfo.push_back(RegisterTestInfo(desc, pc)); 00195 } 00196 00197 void addWarning(const char
msg, TProgramCounter pc) 00198 { 00199 mWarnings.push_back(CalcMessage(msg, pc)); 00200 } 00201 00202 void add(string desc, const char
error, TProgramCounter pc, uint line = 0) 00203 { 00204 if (line) { 00205 ostringstream ostr(""); 00206 ostr << " Line: " << line; 00207 desc += ostr.str(); 00208 } 00209 addRegister(desc, pc); 00210 if (error != NULL) { 00211 addWarning(error, pc); 00212 } 00213 } 00214 00215 void setTupleData(TupleData& tuple) 00216 { 00217 assert(tuple.size() == mOutRegInfo.size()); 00218 00219
00220 for (uint i = 0; i < tuple.size(); i++) { 00221 mOutRegInfo[i].setTupleDatum(tuple[i]); 00222 } 00223 } 00224 00225 virtual bool checkResult(Calculator& calc, TupleData& outputTuple) 00226 { 00227 TupleDescriptor outputTupleDesc = calc.getOutputRegisterDescriptor(); 00228
00229 assert(outputTupleDesc.size() == outputTuple.size()); 00230 00231
00232 if (outputTupleDesc.size() != mOutRegInfo.size()) { 00233 ostringstream message(""); 00234 message << "Mismatch of output register number: Expected "; 00235 message << outputTupleDesc.size(); 00236 message << ", Actual " << mOutRegInfo.size(); 00237 BOOST_ERROR(message.str()); 00238 return false; 00239 } 00240 00241
00242 for (uint i = 0; i < outputTupleDesc.size(); i++) { 00243 if (outputTupleDesc[i].pTypeDescriptor->getOrdinal() != 00244 static_castStoredTypeDescriptor::Ordinal(typeOrdinal)) 00245 { 00246 ostringstream message(""); 00247 message << "Type ordinal mismatch: Expected "; 00248 message << outputTupleDesc[i].pTypeDescriptor->getOrdinal(); 00249 message << ", Actual"; 00250 message << static_castStoredTypeDescriptor::Ordinal( 00251 typeOrdinal); 00252 BOOST_ERROR(message.str()); 00253 return false; 00254 } 00255 00256 if (mOutRegInfo[i].checkTupleDatum(outputTuple[i])) { 00257 ostringstream message(""); 00258 message << "Tuple datum mismatch: Register " << i 00259 << " should be " << mOutRegInfo[i].toString() 00260 << "."; 00261 BOOST_ERROR(message.str()); 00262 return false; 00263 } 00264 } 00265 00266
00267 if (calc.mWarnings.size() != mWarnings.size()) { 00268 ostringstream message(""); 00269 message << "# of warnings should be " << mWarnings.size() 00270 << " not " << calc.mWarnings.size(); 00271 BOOST_ERROR(message.str()); 00272 return false; 00273 } 00274 00275 for (uint i = 0; i < mWarnings.size(); i++) { 00276 if (calc.mWarnings[i].pc != mWarnings[i].pc) { 00277 ostringstream message(""); 00278 message << "Warning expected at PC=" << mWarnings[i].pc 00279 << ". Got warning at PC=" 00280 << calc.mWarnings[i].pc; 00281 BOOST_ERROR(message.str()); 00282 return false; 00283 } 00284 00285 if (strcmp(calc.mWarnings[i].str, mWarnings[i].str)) { 00286 ostringstream message(""); 00287 message << "Message should be |" << mWarnings[i].str 00288 << "| not |" << calc.mWarnings[i].str << "| at PC=" 00289 << mWarnings[i].pc ; 00290 BOOST_ERROR(message.str()); 00291 return false; 00292 } 00293 } 00294 00295 return true; 00296 } 00297 00298 public: 00299
00300 vector< RegisterTestInfo > mOutRegInfo; 00301 00302
00303 deque mWarnings; 00304 00305 StandardTypeDescriptorOrdinal typeOrdinal; 00306 }; 00307 00308 class CalcAssemblerTestCase 00309 { 00310 public: 00311 static const uint MAX_WIDTH = 512; 00312 00313 explicit 00314 CalcAssemblerTestCase(uint line, const char* desc, const char* code) 00315 : mDescription(desc), mProgram(code), mAssemblerError(NULL), 00316 mInputTuple(NULL), mExpectedOutputTuple(NULL), mInputBuf(NULL), 00317 mExpOutputBuf(NULL), mFailed(false), mAssembled(false), 00318 mID(++testID), mLine(line), mCalc(0) 00319 { 00320 } 00321 00322 ~CalcAssemblerTestCase() 00323 { 00324 if (mInputTuple) { 00325 delete mInputTuple; 00326 } 00327 if (mExpectedOutputTuple) { 00328 delete mExpectedOutputTuple; 00329 } 00330 if (mInputBuf) { 00331 delete[] mInputBuf; 00332 } 00333 if (mExpOutputBuf) { 00334 delete[] mExpOutputBuf; 00335 } 00336 } 00337 00338 static uint getFailedNumber() 00339 { 00340 return nFailed; 00341 } 00342 00343 static uint getPassedNumber() 00344 { 00345 return nPassed; 00346 } 00347 00348 static uint getTestNumber() 00349 { 00350 return testID; 00351 } 00352 00353 void fail(const char exp, const char actual) 00354 { 00355 assert(exp); 00356 assert(actual); 00357 assert(mDescription); 00358 ostringstream message(""); 00359 message << "test " << mID << " failed: | "; 00360 message << mDescription << " | Got "" << actual << "" | "; 00361 message << "Expected "" << exp << "" | line " << mLine; 00362 BOOST_ERROR(message.str()); 00363 mFailed = true; 00364 nFailed++; 00365 } 00366 00367 void passed(const char exp, const char* actual) 00368 { 00369 assert(exp); 00370 assert(actual); 00371 assert(mDescription); 00372 if (verbose) { 00373 ostringstream message(""); 00374 message << "test " << mID << " passed: | "; 00375 message << mDescription << " | Got "" << actual << "" | "; 00376 message << "Expected "" << exp << "" | line " << mLine; 00377 BOOST_MESSAGE(message.str()); 00378 } 00379 nPassed++; 00380 } 00381 00382 bool assemble() 00383 { 00384 assert(mFailed && mAssembled); 00385 assert(mProgram != NULL); 00386 try { 00387 mCalc.outputRegisterByReference(false); 00388 mCalc.assemble(mProgram); 00389 00390 TupleDescriptor inputTupleDesc = mCalc.getInputRegisterDescriptor(); 00391 TupleDescriptor outputTupleDesc = 00392 mCalc.getOutputRegisterDescriptor(); 00393 00394 mInputTuple = CalcAssembler::createTupleData( 00395 inputTupleDesc, &mInputBuf); 00396 mExpectedOutputTuple = CalcAssembler::createTupleData( 00397 outputTupleDesc, &mExpOutputBuf); 00398 00399
00400 mAssembled = true; 00401 00402 if (mAssemblerError) { 00403
00404
00405 string errorStr = "Error assembling program: "; 00406 errorStr += mAssemblerError; 00407 fail(errorStr.c_str(), "Program assembled."); 00408 } 00409 } catch (CalcAssemblerException& ex) { 00410 if (mAssemblerError) { 00411
00412
00413 00414
00415 if (ex.getMessage().find(mAssemblerError) == string::npos) { 00416
00417 fail(mAssemblerError, ex.getMessage().c_str()); 00418 } else { 00419
00420 passed(mAssemblerError, ex.getMessage().c_str()); 00421 } 00422 } else { 00423 string errorStr = "Error assembling program: "; 00424 errorStr += ex.getMessage(); 00425 fail("Success assembling program", errorStr.c_str()); 00426 00427 if (showProgram) { 00428
00429 ostringstream prog(""); 00430 prog << "Program Code: " << endl; 00431 prog << ex.getCode() << endl; 00432 prog << "Program Snippet: " << endl; 00433 prog << ex.getCodeSnippet() << endl; 00434 BOOST_MESSAGE(prog.str()); 00435 } 00436 } 00437 } 00438 00439
00440 return (mAssembled && mFailed); 00441 } 00442 00443 static string tupleToString( 00444 TupleDescriptor const& tupleDesc, 00445 TupleData* tuple) 00446 { 00447 assert(tuple != NULL); 00448 ostringstream ostr(""); 00449 TuplePrinter tuplePrinter; 00450 tuplePrinter.print(ostr, tupleDesc, *tuple); 00451 return ostr.str(); 00452 } 00453 00454 bool test(CalcChecker* pChecker = NULL) 00455 { 00456 assert(mAssembled); 00457 bool res = true; 00458 00459 TupleDescriptor inputTupleDesc = mCalc.getInputRegisterDescriptor(); 00460 TupleDescriptor outputTupleDesc = mCalc.getOutputRegisterDescriptor(); 00461 00462 FixedBuffer* outputBuf; 00463 TupleData* outputTuple = CalcAssembler::createTupleData( 00464 outputTupleDesc, &outputBuf); 00465 00466 mCalc.bind(mInputTuple, outputTuple); 00467 00468 mCalc.exec(); 00469 00470 string instr = tupleToString(inputTupleDesc, mInputTuple); 00471 string outstr = tupleToString(outputTupleDesc, outputTuple); 00472 string expoutstr = tupleToString(outputTupleDesc, mExpectedOutputTuple); 00473 00474 if (pChecker == NULL) { 00475
00476
00477 res = (expoutstr == outstr); 00478 00479
00480 if (mCalc.mWarnings.empty()) { 00481 res = false; 00482 fail(expoutstr.c_str(), "Calculator warnings"); 00483 00484 00485 00486 00487 } 00488 } else { 00489 res = pChecker->checkResult(mCalc, outputTuple); 00490 } 00491 00492 if (res) { 00493
00494 string resStr = instr + " -> " + outstr; 00495 passed(expoutstr.c_str(), resStr.c_str()); 00496 } else { 00497 string errorStr = "Calculator result: " ; 00498 errorStr += instr + " -> " + outstr; 00499 fail(expoutstr.c_str(), errorStr.c_str()); 00500 } 00501 00502 delete outputTuple; 00503 delete[] outputBuf; 00504 return res; 00505 } 00506 00507 void expectAssemblerError(const char
err) 00508 { 00509 mAssemblerError = err; 00510 } 00511 00512 void writeMaxData(TupleDatum &datum, uint typeOrdinal); 00513 void writeMinData(TupleDatum &datum, uint typeOrdinal); 00514 string toLiteralString(TupleDatum &datum, uint typeOrdinal); 00515 00516 void setTupleDatumMax(TupleDatum& datum, TupleAttributeDescriptor& desc) 00517 { 00518 StoredTypeDescriptor::Ordinal type = desc.pTypeDescriptor->getOrdinal(); 00519 writeMaxData(datum, type); 00520 } 00521 00522 void setTupleDatumMin(TupleDatum& datum, TupleAttributeDescriptor& desc) 00523 { 00524 StoredTypeDescriptor::Ordinal type = desc.pTypeDescriptor->getOrdinal(); 00525 writeMinData(datum, type); 00526 } 00527 00528 void setTupleDatumNull(TupleDatum& datum) 00529 { 00530 datum.pData = NULL; 00531 } 00532 00533 template 00534 void setTupleDatum(TupleDatum& datum, T value) 00535 { 00536 (reinterpret_cast<T*>(const_cast(datum.pData))) = value; 00537 } 00538 00539 template 00540 void setTupleDatum( 00541 TupleDatum& datum, 00542 TupleAttributeDescriptor& desc, 00543 T buf, 00544 uint buflen) 00545 { 00546 assert(buf != NULL); 00547 StoredTypeDescriptor::Ordinal type = desc.pTypeDescriptor->getOrdinal(); 00548 00549 T
ptr = reinterpret_cast<T*>(const_cast(datum.pData)); 00550 switch (type) { 00551 case STANDARD_TYPE_CHAR: 00552 case STANDARD_TYPE_BINARY: 00553
00554 assert(buflen <= datum.cbData); 00555 memset((void*) ptr, 0, datum.cbData); 00556 memcpy((void*) ptr, buf, buflen); 00557 break; 00558 00559 case STANDARD_TYPE_VARCHAR: 00560 case STANDARD_TYPE_VARBINARY: 00561
00562 assert(buflen <= desc.cbStorage); 00563 memset((void*)ptr, 'I', desc.cbStorage); 00564 memcpy((void*)ptr, buf, buflen); 00565 datum.cbData = buflen; 00566 break; 00567 00568 default: 00569 permAssert(false); 00570 } 00571 } 00572 00573 void setInputMin(uint index) 00574 { 00575 assert(mInputTuple != NULL); 00576 assert(index < mInputTuple->size()); 00577 TupleDescriptor inputTupleDesc = mCalc.getInputRegisterDescriptor(); 00578 setTupleDatumMin((mInputTuple)[index], inputTupleDesc[index]); 00579 } 00580 00581 void setInputMax(uint index) 00582 { 00583 assert(mInputTuple != NULL); 00584 assert(index < mInputTuple->size()); 00585 TupleDescriptor inputTupleDesc = mCalc.getInputRegisterDescriptor(); 00586 setTupleDatumMax((mInputTuple)[index], inputTupleDesc[index]); 00587 } 00588 00589 void setInputNull(uint index) 00590 { 00591 assert(mInputTuple != NULL); 00592 assert(index < mInputTuple->size()); 00593 setTupleDatumNull((mInputTuple)[index]); 00594 } 00595 00596 template 00597 void setInput(uint index, T value) 00598 { 00599 assert(mInputTuple != NULL); 00600 assert(index < mInputTuple->size()); 00601 setTupleDatum((mInputTuple)[index], value); 00602 } 00603 00604 template 00605 void setInput(uint index, T* buf, uint buflen) 00606 { 00607 assert(mInputTuple != NULL); 00608 assert(index < mInputTuple->size()); 00609 TupleDescriptor inputTupleDesc = mCalc.getInputRegisterDescriptor(); 00610 setTupleDatum( 00611 (mInputTuple)[index], 00612 inputTupleDesc[index], 00613 buf, 00614 buflen); 00615 } 00616 00617 string getInput(uint index) 00618 { 00619 assert(mInputTuple != NULL); 00620 assert(index < mInputTuple->size()); 00621 TupleDescriptor inputTupleDesc = mCalc.getInputRegisterDescriptor(); 00622 return toLiteralString( 00623 (mInputTuple)[index], 00624 inputTupleDesc[index].pTypeDescriptor->getOrdinal()); 00625 } 00626 00627 TupleData* getInputTuple() 00628 { 00629 return mInputTuple; 00630 } 00631 00632
00633 void setExpectedOutputNull(uint index) 00634 { 00635 assert(mExpectedOutputTuple != NULL); 00636 assert(index < mExpectedOutputTuple->size()); 00637 setTupleDatumNull((mExpectedOutputTuple)[index]); 00638 } 00639 00640 void setExpectedOutputMax(uint index) 00641 { 00642 assert(mExpectedOutputTuple != NULL); 00643 assert(index < mExpectedOutputTuple->size()); 00644 TupleDescriptor outputTupleDesc = mCalc.getOutputRegisterDescriptor(); 00645 setTupleDatumMax( 00646 (mExpectedOutputTuple)[index], 00647 outputTupleDesc[index]); 00648 } 00649 void setExpectedOutputMin(uint index) 00650 { 00651 assert(mExpectedOutputTuple != NULL); 00652 assert(index < mExpectedOutputTuple->size()); 00653 TupleDescriptor outputTupleDesc = mCalc.getOutputRegisterDescriptor(); 00654 setTupleDatumMin( 00655 (mExpectedOutputTuple)[index], 00656 outputTupleDesc[index]); 00657 } 00658 00659 template 00660 void setExpectedOutput(uint index, T value) 00661 { 00662 assert(mExpectedOutputTuple != NULL); 00663 assert(index < mExpectedOutputTuple->size()); 00664 setTupleDatum((mExpectedOutputTuple)[index], value); 00665 } 00666 00667 template 00668 void setExpectedOutput(uint index, T* buf, uint buflen) 00669 { 00670 assert(mExpectedOutputTuple != NULL); 00671 assert(index < mExpectedOutputTuple->size()); 00672 TupleDescriptor outputTupleDesc = mCalc.getOutputRegisterDescriptor(); 00673 setTupleDatum( 00674 (mExpectedOutputTuple)[index], 00675 outputTupleDesc[index], 00676 buf, 00677 buflen); 00678 } 00679 00680 string getExpectedOutput(uint index) 00681 { 00682 assert(mExpectedOutputTuple != NULL); 00683 assert(index < mExpectedOutputTuple->size()); 00684 TupleDescriptor outputTupleDesc = mCalc.getOutputRegisterDescriptor(); 00685 return toLiteralString( 00686 (mExpectedOutputTuple)[index], 00687 outputTupleDesc[index].pTypeDescriptor->getOrdinal()); 00688 } 00689 00690 TupleData* getExpectedOutputTuple() 00691 { 00692 return mExpectedOutputTuple; 00693 } 00694 00695 bool failed() 00696 { 00697 return mFailed; 00698 } 00699 00700 protected: 00701 const char* mDescription; 00702 const char* mProgram; 00703 const char* mAssemblerError; 00704 TupleData* mInputTuple; 00705 TupleData* mExpectedOutputTuple; 00706 FixedBuffer* mInputBuf; 00707 FixedBuffer* mExpOutputBuf; 00708 bool mFailed; 00709 bool mAssembled; 00710 uint mID; 00711 uint mLine; 00712 00713 Calculator mCalc; 00714 static uint testID; 00715 static uint nFailed; 00716 static uint nPassed; 00717 }; 00718 00719 uint CalcAssemblerTestCase::testID = 0; 00720 uint CalcAssemblerTestCase::nFailed = 0; 00721 uint CalcAssemblerTestCase::nPassed = 0; 00722 00723 class CalcAssemblerTest : virtual public TestBase, public TraceSource 00724 { 00725 protected: 00726 void testAdd(); 00727 00728 void testBool(); 00729 void testPointer(); 00730 void testReturn(); 00731 void testJump(); 00732 void testExtended(); 00733 00734 void testLiteralBinding(); 00735 00736 void testInvalidPrograms(); 00737 void testStandardTypes(); 00738 00739 void testComments(); 00740 00741 void testBoolInstructions(StandardTypeDescriptorOrdinal type); 00742 00743 template 00744 void testNativeInstructions(StandardTypeDescriptorOrdinal type); 00745 00746 template 00747 void testIntegralNativeInstructions(StandardTypeDescriptorOrdinal type); 00748 00749 string getTypeString(StandardTypeDescriptorOrdinal type, uint arraylen = 0); 00750 string createRegisterString(string s, uint n, char c = ','); 00751 void addBinaryInstructions( 00752 ostringstream& ostr, 00753 string opcode, 00754 uint& outreg, 00755 uint n); 00756 00757 void addUnaryInstructions( 00758 ostringstream& ostr, 00759 string opcode, 00760 uint& outreg, 00761 uint n); 00762 00763 public: 00764 explicit CalcAssemblerTest() 00765 : TraceSource(shared_from_this(),"CalcAssemblerTest") 00766 { 00767 srand(time(NULL)); 00768 CalcInit::instance(); 00769 FENNEL_UNIT_TEST_CASE(CalcAssemblerTest, testLiteralBinding); 00770 FENNEL_UNIT_TEST_CASE(CalcAssemblerTest, testBool); 00771 FENNEL_UNIT_TEST_CASE(CalcAssemblerTest, testPointer); 00772 FENNEL_UNIT_TEST_CASE(CalcAssemblerTest, testAdd); 00773 FENNEL_UNIT_TEST_CASE(CalcAssemblerTest, testReturn); 00774 FENNEL_UNIT_TEST_CASE(CalcAssemblerTest, testJump); 00775 FENNEL_UNIT_TEST_CASE(CalcAssemblerTest, testExtended); 00776 FENNEL_UNIT_TEST_CASE(CalcAssemblerTest, testComments); 00777 00778
00779 #ifndef MSVC 00780 FENNEL_UNIT_TEST_CASE(CalcAssemblerTest, testInvalidPrograms); 00781 FENNEL_UNIT_TEST_CASE(CalcAssemblerTest, testStandardTypes); 00782 #endif 00783 } 00784 00785 virtual ~CalcAssemblerTest() 00786 { 00787 } 00788 00789 }; 00790 00791 00792 00793 00794 00795 string CalcAssemblerTestCase::toLiteralString( 00796 TupleDatum &datum, 00797 uint typeOrdinal) 00798 { 00799
00800
00801 00802 ostringstream ostr(""); 00803 if (datum.pData != NULL) { 00804 switch (typeOrdinal) { 00805 case STANDARD_TYPE_BOOL: 00806 if (reinterpret_cast<const bool*>(datum.pData)) { 00807 ostr << "1"; 00808 } else { 00809 ostr << "0"; 00810 } 00811 break; 00812 case STANDARD_TYPE_INT_8: 00813 ostr << (int64_t) (*reinterpret_cast<const int8_t*>(datum.pData)); 00814 break; 00815 case STANDARD_TYPE_UINT_8: 00816 ostr << (int64_t) (*reinterpret_cast<const uint8_t*>(datum.pData)); 00817 break; 00818 case STANDARD_TYPE_INT_16: 00819 ostr << (int64_t) (*reinterpret_cast<const int16_t*>(datum.pData)); 00820 break; 00821 case STANDARD_TYPE_UINT_16: 00822 ostr << (int64_t) (*reinterpret_cast<const uint16_t*>(datum.pData)); 00823 break; 00824 case STANDARD_TYPE_INT_32: 00825 ostr << (int64_t) (*reinterpret_cast<const int32_t*>(datum.pData)); 00826 break; 00827 case STANDARD_TYPE_UINT_32: 00828 ostr << (int64_t) (*reinterpret_cast<const uint32_t*>(datum.pData)); 00829 break; 00830 case STANDARD_TYPE_INT_64: 00831 ostr << (*reinterpret_cast<const int64_t*>(datum.pData)); 00832 break; 00833 case STANDARD_TYPE_UINT_64: 00834 ostr << (*reinterpret_cast<const uint64_t*>(datum.pData)); 00835 break; 00836 case STANDARD_TYPE_REAL: 00837 ostr << (*reinterpret_cast<const float*>(datum.pData)); 00838 break; 00839 case STANDARD_TYPE_DOUBLE: 00840 ostr << (*reinterpret_cast<const double*>(datum.pData)); 00841 break; 00842 case STANDARD_TYPE_BINARY: 00843 case STANDARD_TYPE_CHAR: 00844 case STANDARD_TYPE_VARCHAR: 00845 case STANDARD_TYPE_VARBINARY: 00846 ostr << "0x"; 00847 ostr << stringToHex( 00848 (reinterpret_cast<const char*>(datum.pData)), 00849 datum.cbData); 00850 break; 00851 default: 00852 permAssert(false); 00853 } 00854 } 00855 return ostr.str(); 00856 } 00857 00858 00859 void CalcAssemblerTestCase::writeMaxData(TupleDatum &datum, uint typeOrdinal) 00860 { 00861 PBuffer pData = const_cast(datum.pData); 00862 switch (typeOrdinal) { 00863 case STANDARD_TYPE_BOOL: 00864 (reinterpret_cast<bool *>(pData)) = true; 00865 break; 00866 case STANDARD_TYPE_INT_8: 00867 (reinterpret_cast<int8_t *>(pData)) = 00868 std::numeric_limits::max(); 00869 break; 00870 case STANDARD_TYPE_UINT_8: 00871 (reinterpret_cast<uint8_t *>(pData)) = 00872 std::numeric_limits::max(); 00873 break; 00874 case STANDARD_TYPE_INT_16: 00875 (reinterpret_cast<int16_t *>(pData)) = 00876 std::numeric_limits::max(); 00877 break; 00878 case STANDARD_TYPE_UINT_16: 00879 (reinterpret_cast<uint16_t *>(pData)) = 00880 std::numeric_limits::max(); 00881 break; 00882 case STANDARD_TYPE_INT_32: 00883 (reinterpret_cast<int32_t *>(pData)) = 00884 std::numeric_limits::max(); 00885 break; 00886 case STANDARD_TYPE_UINT_32: 00887 (reinterpret_cast<uint32_t *>(pData)) = 00888 std::numeric_limits::max(); 00889 break; 00890 case STANDARD_TYPE_INT_64: 00891 (reinterpret_cast<int64_t *>(pData)) = 00892 std::numeric_limits::max(); 00893 break; 00894 case STANDARD_TYPE_UINT_64: 00895 (reinterpret_cast<uint64_t *>(pData)) = 00896 std::numeric_limits::max(); 00897 break; 00898 case STANDARD_TYPE_REAL: 00899 (reinterpret_cast<float *>(pData)) = 00900 std::numeric_limits::max(); 00901 break; 00902 case STANDARD_TYPE_DOUBLE: 00903 (reinterpret_cast<double *>(pData)) = 00904 std::numeric_limits::max(); 00905 break; 00906 case STANDARD_TYPE_BINARY: 00907 memset(pData,0xFF,datum.cbData); 00908 break; 00909 case STANDARD_TYPE_CHAR: 00910 memset(pData,'z',datum.cbData); 00911 break; 00912 case STANDARD_TYPE_VARCHAR: 00913 datum.cbData = MAX_WIDTH; 00914 memset(pData,'z',datum.cbData); 00915 break; 00916 case STANDARD_TYPE_VARBINARY: 00917 datum.cbData = MAX_WIDTH; 00918 memset(pData,0xFF,datum.cbData); 00919 break; 00920 default: 00921 permAssert(false); 00922 } 00923 } 00924 00925 00926 void CalcAssemblerTestCase::writeMinData(TupleDatum &datum,uint typeOrdinal) 00927 { 00928 PBuffer pData = const_cast(datum.pData); 00929 switch (typeOrdinal) { 00930 case STANDARD_TYPE_BOOL: 00931 (reinterpret_cast<bool *>(pData)) = false; 00932 break; 00933 case STANDARD_TYPE_INT_8: 00934 (reinterpret_cast<int8_t *>(pData)) = 00935 std::numeric_limits::min(); 00936 break; 00937 case STANDARD_TYPE_UINT_8: 00938 (reinterpret_cast<uint8_t *>(pData)) = 00939 std::numeric_limits::min(); 00940 break; 00941 case STANDARD_TYPE_INT_16: 00942 (reinterpret_cast<int16_t *>(pData)) = 00943 std::numeric_limits::min(); 00944 break; 00945 case STANDARD_TYPE_UINT_16: 00946 (reinterpret_cast<uint16_t *>(pData)) = 00947 std::numeric_limits::min(); 00948 break; 00949 case STANDARD_TYPE_INT_32: 00950 (reinterpret_cast<int32_t *>(pData)) = 00951 std::numeric_limits::min(); 00952 break; 00953 case STANDARD_TYPE_UINT_32: 00954 (reinterpret_cast<uint32_t *>(pData)) = 00955 std::numeric_limits::min(); 00956 break; 00957 case STANDARD_TYPE_INT_64: 00958 (reinterpret_cast<int64_t *>(pData)) = 00959 std::numeric_limits::min(); 00960 break; 00961 case STANDARD_TYPE_UINT_64: 00962 (reinterpret_cast<uint64_t *>(pData)) = 00963 std::numeric_limits::min(); 00964 break; 00965 case STANDARD_TYPE_REAL: 00966 (reinterpret_cast<float *>(pData)) = 00967 std::numeric_limits::min(); 00968 break; 00969 case STANDARD_TYPE_DOUBLE: 00970 (reinterpret_cast<double *>(pData)) = 00971 std::numeric_limits::min(); 00972 break; 00973 case STANDARD_TYPE_BINARY: 00974 memset(pData,0,datum.cbData); 00975 break; 00976 case STANDARD_TYPE_CHAR: 00977 memset(pData,'A',datum.cbData); 00978 break; 00979 case STANDARD_TYPE_VARCHAR: 00980 case STANDARD_TYPE_VARBINARY: 00981 datum.cbData = 0; 00982 break; 00983 default: 00984 permAssert(false); 00985 } 00986 } 00987 00988 string CalcAssemblerTest::getTypeString( 00989 StandardTypeDescriptorOrdinal type, 00990 uint arraylen) 00991 { 00992 string typestr = StandardTypeDescriptor::toString(type); 00993 if (StandardTypeDescriptor::isArray(type)) { 00994 ostringstream size(""); 00995 size << "," << arraylen; 00996 typestr += size.str(); 00997 } 00998 return typestr; 00999 } 01000 01001 string CalcAssemblerTest::createRegisterString( 01002 string s, 01003 uint n, 01004 char c) 01005 { 01006 ostringstream ostr(""); 01007 for (uint i = 0; i < n; i++) { 01008 if (i > 0) { 01009 ostr << c; 01010 } 01011 ostr << s; 01012 } 01013 return ostr.str(); 01014 } 01015 01016 void CalcAssemblerTest::addUnaryInstructions( 01017 ostringstream& ostr, 01018 string opcode, 01019 uint& outreg, 01020 uint n) 01021 { 01022 for (uint i = 0; i < n; i++) { 01023 ostr << opcode << " O" << outreg++ << ", I" 01024 << i << ";" << endl; 01025 } 01026 } 01027 01028 void CalcAssemblerTest::addBinaryInstructions( 01029 ostringstream& ostr, 01030 string opcode, 01031 uint& outreg, 01032 uint n) 01033 { 01034 for (uint i = 0; i < n; i++) { 01035 for (uint j = 0; j < n; j++) { 01036 ostr << opcode << " O" << outreg++ << ", I" 01037 << i << ", I" << j << ";" << endl; 01038 } 01039 } 01040 } 01041 01042 template 01043 void CalcAssemblerTest::testIntegralNativeInstructions( 01044 StandardTypeDescriptorOrdinal type) 01045 { 01046 string typestr = getTypeString(type, CalcAssemblerTestCase::MAX_WIDTH); 01047 uint inregs = 4; 01048 01049
01050 ostringstream instostr(""); 01051 uint outreg = 0; 01052 CalcTestInfo expectedCalcOut(type); 01053 TProgramCounter pc = 0; 01054 T
pNULL = NULL; 01055 T zero = 0; 01056 T min = std::numeric_limits::min(); 01057 T max = std::numeric_limits::max(); 01058 T mid = 10; 01059 01060 const char
divbyzero = "22012"; 01061 01062
01063 string modstr = string("MOD ") + typestr; 01064 addBinaryInstructions(instostr, "MOD", outreg, inregs); 01065 if (min != zero) { 01066 expectedCalcOut.add( 01067 modstr, (T) (min % min), pc++, LINE); 01068 } else { 01069 expectedCalcOut.add( 01070 modstr, divbyzero, pc++, LINE);
01071 } 01072 expectedCalcOut.add( 01073 modstr, (T) (min % max), pc++, LINE);
01074 expectedCalcOut.add( 01075 modstr, pNULL, pc++, LINE);
01076 expectedCalcOut.add( 01077 modstr, (T) (min % mid), pc++, LINE); 01078 01079 if (min != zero) { 01080 expectedCalcOut.add( 01081 modstr, (T) (max % min), pc++, LINE); 01082 } else { 01083 expectedCalcOut.add( 01084 modstr, divbyzero, pc++, LINE);
01085 } 01086 expectedCalcOut.add( 01087 modstr, (T) (max % max), pc++, LINE);
01088 expectedCalcOut.add( 01089 modstr, pNULL, pc++, LINE);
01090 expectedCalcOut.add( 01091 modstr, (T) (max % mid), pc++, LINE);
01092 01093 expectedCalcOut.add( 01094 modstr, pNULL, pc++, LINE);
01095 expectedCalcOut.add( 01096 modstr, pNULL, pc++, LINE);
01097 expectedCalcOut.add( 01098 modstr, pNULL, pc++, LINE);
01099 expectedCalcOut.add( 01100 modstr, pNULL, pc++, LINE);
01101 01102 if (min != zero) { 01103 expectedCalcOut.add( 01104 modstr, (T) (mid % min), pc++, LINE); 01105 } else { 01106 expectedCalcOut.add( 01107 modstr, divbyzero, pc++, LINE);
01108 } 01109 expectedCalcOut.add( 01110 modstr, (T) (mid % max), pc++, LINE);
01111 expectedCalcOut.add( 01112 modstr, pNULL, pc++, LINE);
01113 expectedCalcOut.add( 01114 modstr, (T) (mid % mid), pc++, LINE);
01115 01116
01117 string andstr = string("AND ") + typestr; 01118 addBinaryInstructions(instostr, "AND", outreg, inregs); 01119 expectedCalcOut.add( 01120 andstr, (T) (min&min), pc++, LINE);
01121 expectedCalcOut.add( 01122 andstr, (T) (min&max), pc++, LINE);
01123 expectedCalcOut.add( 01124 andstr, pNULL, pc++, LINE);
01125 expectedCalcOut.add( 01126 andstr, (T) (min&mid), pc++, LINE);
01127 01128 expectedCalcOut.add( 01129 andstr, (T) (max&min), pc++, LINE);
01130 expectedCalcOut.add( 01131 andstr, (T) (max&max), pc++, LINE);
01132 expectedCalcOut.add( 01133 andstr, pNULL, pc++, LINE);
01134 expectedCalcOut.add( 01135 andstr, (T) (max&mid), pc++, LINE);
01136 01137 expectedCalcOut.add( 01138 andstr, pNULL, pc++, LINE);
01139 expectedCalcOut.add( 01140 andstr, pNULL, pc++, LINE);
01141 expectedCalcOut.add( 01142 andstr, pNULL, pc++, LINE);
01143 expectedCalcOut.add( 01144 andstr, pNULL, pc++, LINE);
01145 01146 expectedCalcOut.add( 01147 andstr, (T) (mid&min), pc++, LINE);
01148 expectedCalcOut.add( 01149 andstr, (T) (mid&max), pc++, LINE);
01150 expectedCalcOut.add( 01151 andstr, pNULL, pc++, LINE);
01152 expectedCalcOut.add( 01153 andstr, (T) (mid&mid), pc++, LINE);
01154 01155
01156 string orstr = string("OR ") + typestr; 01157 addBinaryInstructions(instostr, "OR", outreg, inregs); 01158 expectedCalcOut.add( 01159 orstr, (T) (min | min), pc++, LINE);
01160 expectedCalcOut.add( 01161 orstr, (T) (min | max), pc++, LINE);
01162 expectedCalcOut.add( 01163 orstr, pNULL, pc++, LINE);
01164 expectedCalcOut.add( 01165 orstr, (T) (min | mid), pc++, LINE); 01166 01167 expectedCalcOut.add( 01168 orstr, (T) (max | min), pc++, LINE);
01169 expectedCalcOut.add( 01170 orstr, (T) (max | max), pc++, LINE);
01171 expectedCalcOut.add( 01172 orstr, pNULL, pc++, LINE);
01173 expectedCalcOut.add( 01174 orstr, (T) (max | mid), pc++, LINE);
01175 01176 expectedCalcOut.add( 01177 orstr, pNULL, pc++, LINE);
01178 expectedCalcOut.add( 01179 orstr, pNULL, pc++, LINE);
01180 expectedCalcOut.add( 01181 orstr, pNULL, pc++, LINE);
01182 expectedCalcOut.add( 01183 orstr, pNULL, pc++, LINE);
01184 01185 expectedCalcOut.add( 01186 orstr, (T) (mid | min), pc++, LINE);
01187 expectedCalcOut.add( 01188 orstr, (T) (mid | max), pc++, LINE);
01189 expectedCalcOut.add( 01190 orstr, pNULL, pc++, LINE);
01191 expectedCalcOut.add( 01192 orstr, (T) (mid | mid), pc++, LINE);
01193 01194
01195 string shflstr = string("SHFL ") + typestr; 01196 addBinaryInstructions(instostr, "SHFL", outreg, inregs); 01197 expectedCalcOut.add( 01198 shflstr, (T) (min<<min), pc++, __LINE__);
01199 expectedCalcOut.add( 01200 shflstr, (T) (min<<max), pc++, __LINE__);
01201 expectedCalcOut.add( 01202 shflstr, pNULL, pc++, __LINE__);
01203 expectedCalcOut.add( 01204 shflstr, (T) (min<<mid), pc++, __LINE__);
01205 01206 expectedCalcOut.add( 01207 shflstr, (T) (max<<min), pc++, __LINE__);
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218 expectedCalcOut.addRegister(shflstr, pc++);
01219 expectedCalcOut.add( 01220 shflstr, pNULL, pc++, __LINE__);
01221 expectedCalcOut.add( 01222 shflstr, (T) (max<<mid), pc++, __LINE__);
01223 01224 expectedCalcOut.add( 01225 shflstr, pNULL, pc++, __LINE__);
01226 expectedCalcOut.add( 01227 shflstr, pNULL, pc++, __LINE__);
01228 expectedCalcOut.add( 01229 shflstr, pNULL, pc++, __LINE__);
01230 expectedCalcOut.add( 01231 shflstr, pNULL, pc++, __LINE__);
01232 01233 expectedCalcOut.add( 01234 shflstr, (T) (mid<<min), pc++, __LINE__);
01235 expectedCalcOut.add( 01236 shflstr, (T) (mid<<max), pc++, __LINE__);
01237 expectedCalcOut.add( 01238 shflstr, pNULL, pc++, __LINE__);
01239 expectedCalcOut.add( 01240 shflstr, (T) (mid<<mid), pc++, __LINE__);
01241 01242
01243 string shfrstr = string("SHFR ") + typestr; 01244 addBinaryInstructions(instostr, "SHFR", outreg, inregs); 01245 expectedCalcOut.add( 01246 shfrstr, (T) (min >> min), pc++, LINE);
01247 expectedCalcOut.add( 01248 shfrstr, (T) (min >> max), pc++, LINE);
01249 expectedCalcOut.add( 01250 shfrstr, pNULL, pc++, LINE);
01251 expectedCalcOut.add( 01252 shfrstr, (T) (min >> mid), pc++, LINE); 01253 01254 expectedCalcOut.add( 01255 shfrstr, (T) (max >> min), pc++, LINE);
01256
01257 expectedCalcOut.addRegister(shfrstr, pc++);
01258 expectedCalcOut.add( 01259 shfrstr, pNULL, pc++, LINE);
01260 expectedCalcOut.add( 01261 shfrstr, (T) (max >> mid), pc++, LINE);
01262 01263 expectedCalcOut.add( 01264 shfrstr, pNULL, pc++, LINE);
01265 expectedCalcOut.add( 01266 shfrstr, pNULL, pc++, LINE);
01267 expectedCalcOut.add( 01268 shfrstr, pNULL, pc++, LINE);
01269 expectedCalcOut.add( 01270 shfrstr, pNULL, pc++, LINE);
01271 01272 expectedCalcOut.add( 01273 shfrstr, (T) (mid >> min), pc++, LINE);
01274 expectedCalcOut.add( 01275 shfrstr, (T) (mid >> max), pc++, LINE);
01276 expectedCalcOut.add( 01277 shfrstr, pNULL, pc++, LINE);
01278 expectedCalcOut.add( 01279 shfrstr, (T) (mid >> mid), pc++, LINE);
01280 01281 assert(outreg == static_cast(pc)); 01282 01283
01284 string testdesc = "testNativeInstructions: " + typestr; 01285 ostringstream testostr(""); 01286 01287 testostr << "I " << createRegisterString(typestr, inregs) << ";" << endl; 01288 testostr << "O " << createRegisterString(typestr, outreg) << ";" << endl; 01289 testostr << "T;" << endl; 01290 01291 testostr << instostr.str(); 01292 01293 string teststr = testostr.str(); 01294 01295 CalcAssemblerTestCase testCase1( 01296 __LINE__, testdesc.c_str(), 01297 teststr.c_str()); 01298 if (testCase1.assemble()) { 01299 testCase1.setInputMin(0); 01300 testCase1.setInputMax(1); 01301 testCase1.setInputNull(2); 01302 testCase1.template setInput(3, mid); 01303 TupleData
outputTuple = testCase1.getExpectedOutputTuple(); 01304 assert(outputTuple != NULL); 01305 expectedCalcOut.setTupleData(outputTuple); 01306 testCase1.test(&expectedCalcOut); 01307 } 01308 01309 } 01310 01323 template 01324 void CalcAssemblerTest::testNativeInstructions( 01325 StandardTypeDescriptorOrdinal type) 01326 { 01327 string typestr = getTypeString(type, CalcAssemblerTestCase::MAX_WIDTH); 01328 uint inregs = 4; 01329 01330
01331 ostringstream instostr(""); 01332 uint outreg = 0; 01333 CalcTestInfo expectedCalcOut(type); 01334 TProgramCounter pc = 0; 01335 T
pNULL = NULL; 01336 T zero = 0; 01337 T min = std::numeric_limits::min(); 01338 T max = std::numeric_limits::max(); 01339 T mid = 10; 01340 01341 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01342 const char overflow = "22003"; 01343 const char underflow = "22000"; 01344 01345 #endif 01346 const char divbyzero = "22012"; 01347 01348
01349 addBinaryInstructions(instostr, "ADD", outreg, inregs); 01350 string addstr = string("ADD ") + typestr; 01351 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01352 if (std::numeric_limits::is_signed 01353 && std::numeric_limits::is_integer) 01354 { 01355 expectedCalcOut.add( 01356 addstr, overflow, pc++, LINE); 01357 } else { 01358 expectedCalcOut.add( 01359 addstr, (T) (min + min), pc++, LINE); 01360 } 01361 #else 01362 expectedCalcOut.add( 01363 addstr, (T) (min + min), pc++, LINE);
01364 #endif 01365 expectedCalcOut.add( 01366 addstr, (T) (min + max), pc++, LINE);
01367 expectedCalcOut.add( 01368 addstr, pNULL, pc++, LINE);
01369 expectedCalcOut.add( 01370 addstr, (T) (min + mid), pc++, LINE); 01371 01372 expectedCalcOut.add( 01373 addstr, (T) (max + min), pc++, LINE);
01374 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01375 expectedCalcOut.add( 01376 addstr, overflow, pc++, LINE);
01377 #else 01378 expectedCalcOut.add( 01379 addstr, (T) (max + max), pc++, LINE);
01380 #endif 01381 expectedCalcOut.add( 01382 addstr, pNULL, pc++, LINE);
01383 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01384 if (std::numeric_limits::is_integer) { 01385 expectedCalcOut.add( 01386 addstr, overflow, pc++, LINE);
01387 } else { 01388 expectedCalcOut.add( 01389 addstr, (T) (max + mid), pc++, LINE);
01390 } 01391 #else 01392 expectedCalcOut.add( 01393 addstr, (T) (max + mid), pc++, LINE);
01394 #endif 01395 01396 01397 expectedCalcOut.add( 01398 addstr, pNULL, pc++, LINE);
01399 expectedCalcOut.add( 01400 addstr, pNULL, pc++, LINE);
01401 expectedCalcOut.add( 01402 addstr, pNULL, pc++, LINE);
01403 expectedCalcOut.add( 01404 addstr, pNULL, pc++, LINE);
01405 01406 expectedCalcOut.add( 01407 addstr, (T) (mid + min), pc++, LINE);
01408 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01409 if (std::numeric_limits::is_integer) { 01410 expectedCalcOut.add( 01411 addstr, overflow, pc++, LINE);
01412 } else { 01413 expectedCalcOut.add( 01414 addstr, (T) (mid + max), pc++, LINE);
01415 } 01416 #else 01417 expectedCalcOut.add( 01418 addstr, (T) (mid + max), pc++, LINE);
01419 #endif 01420 expectedCalcOut.add( 01421 addstr, pNULL, pc++, LINE);
01422 expectedCalcOut.add( 01423 addstr, (T) (mid + mid), pc++, LINE);
01424 01425
01426 addBinaryInstructions(instostr, "SUB", outreg, inregs); 01427 string substr = string("SUB ") + typestr; 01428 expectedCalcOut.add( 01429 substr, (T) (min - min), pc++, LINE);
01430 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01431 if (std::numeric_limits::is_integer) { 01432 expectedCalcOut.add( 01433 substr, overflow, pc++, LINE);
01434 } else { 01435 expectedCalcOut.add( 01436 substr, (T) (min - max), pc++, LINE);
01437 } 01438 #else 01439 expectedCalcOut.add( 01440 substr, (T) (min - max), pc++, LINE);
01441 #endif 01442 expectedCalcOut.add( 01443 substr, pNULL, pc++, LINE);
01444 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01445 if (std::numeric_limits::is_integer) { 01446 expectedCalcOut.add( 01447 substr, overflow, pc++, LINE);
01448 } else { 01449 expectedCalcOut.add( 01450 substr, (T) (min - mid), pc++, LINE); 01451 } 01452 #else 01453 expectedCalcOut.add( 01454 substr, (T) (min - mid), pc++, LINE); 01455 #endif 01456 01457 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01458 if (std::numeric_limits::is_signed 01459 && std::numeric_limits::is_integer) 01460 { 01461 expectedCalcOut.add( 01462 substr, overflow, pc++, LINE);
01463 } else { 01464 expectedCalcOut.add( 01465 substr, (T) (max - min), pc++, LINE);
01466 } 01467 #else 01468 expectedCalcOut.add( 01469 substr, (T) (max - min), pc++, LINE);
01470 #endif 01471 expectedCalcOut.add( 01472 substr, (T) (max - max), pc++, LINE);
01473 expectedCalcOut.add( 01474 substr, pNULL, pc++, LINE);
01475 expectedCalcOut.add( 01476 substr, (T) (max - mid), pc++, LINE);
01477 01478 expectedCalcOut.add( 01479 substr, pNULL, pc++, LINE);
01480 expectedCalcOut.add( 01481 substr, pNULL, pc++, LINE);
01482 expectedCalcOut.add( 01483 substr, pNULL, pc++, LINE);
01484 expectedCalcOut.add( 01485 substr, pNULL, pc++, LINE);
01486 01487 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01488 if (std::numeric_limits::is_signed 01489 && std::numeric_limits::is_integer) 01490 { 01491 expectedCalcOut.add( 01492 substr, overflow, pc++, LINE);
01493 } else { 01494 expectedCalcOut.add( 01495 substr, (T) (mid - min), pc++, LINE);
01496 } 01497 #else 01498 expectedCalcOut.add( 01499 substr, (T) (mid - min), pc++, LINE);
01500 #endif 01501 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01502 if (!std::numeric_limits::is_signed) { 01503 expectedCalcOut.add( 01504 substr, overflow, pc++, LINE);
01505 } else { 01506 expectedCalcOut.add( 01507 substr, (T) (mid - max), pc++, LINE);
01508 } 01509 #else 01510 expectedCalcOut.add( 01511 substr, (T) (mid - max), pc++, LINE);
01512 #endif 01513 expectedCalcOut.add( 01514 substr, pNULL, pc++, LINE);
01515 expectedCalcOut.add( 01516 substr, (T) (mid - mid), pc++, LINE);
01517 01518
01519 addBinaryInstructions(instostr, "MUL", outreg, inregs); 01520 string mulstr = string("MUL ") + typestr; 01521 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01522 if (!std::numeric_limits::is_signed) { 01523 expectedCalcOut.add( 01524 mulstr, (T) (min * min), pc++, LINE);
01525 } else if (std::numeric_limits::is_integer) { 01526 expectedCalcOut.add( 01527 mulstr, overflow, pc++, LINE);
01528 } else { 01529 expectedCalcOut.add( 01530 mulstr, underflow, pc++, LINE);
01531 } 01532 #else 01533 expectedCalcOut.add( 01534 mulstr, (T) (min * min), pc++, LINE);
01535 #endif 01536 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01537 if (std::numeric_limits::is_signed 01538 && std::numeric_limits::is_integer) 01539 { 01540 expectedCalcOut.add( 01541 mulstr, overflow, pc++, LINE);
01542 } else { 01543 expectedCalcOut.add( 01544 mulstr, (T) (min * max), pc++, LINE);
01545 } 01546 #else 01547 expectedCalcOut.add( 01548 mulstr, (T) (min
max), pc++, LINE);
01549 #endif 01550 expectedCalcOut.add( 01551 mulstr, pNULL, pc++, LINE);
01552 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01553 if (std::numeric_limits::is_signed 01554 && std::numeric_limits::is_integer) 01555 { 01556 expectedCalcOut.add( 01557 mulstr, overflow, pc++, LINE);
01558 } else { 01559 expectedCalcOut.add( 01560 mulstr, (T) (min
mid), pc++, LINE);
01561 } 01562 #else 01563 expectedCalcOut.add( 01564 mulstr, (T) (min
mid), pc++, LINE);
01565 #endif 01566 01567 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01568 if (std::numeric_limits::is_signed 01569 && std::numeric_limits::is_integer) 01570 { 01571 expectedCalcOut.add( 01572 mulstr, overflow, pc++, LINE);
01573 } else { 01574 expectedCalcOut.add( 01575 mulstr, (T) (max * min), pc++, LINE);
01576 } 01577 #else 01578 expectedCalcOut.add( 01579 mulstr, (T) (max * min), pc++, LINE);
01580 #endif 01581 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01582 expectedCalcOut.add( 01583 mulstr, overflow, pc++, LINE);
01584 #else 01585 expectedCalcOut.add( 01586 mulstr, (T) (max
max), pc++, LINE);
01587 #endif 01588 expectedCalcOut.add( 01589 mulstr, pNULL, pc++, LINE);
01590 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01591 expectedCalcOut.add( 01592 mulstr, overflow, pc++, LINE);
01593 #else 01594 expectedCalcOut.add( 01595 mulstr, (T) (max
mid), pc++, LINE);
01596 #endif 01597 01598 expectedCalcOut.add( 01599 mulstr, pNULL, pc++, LINE);
01600 expectedCalcOut.add( 01601 mulstr, pNULL, pc++, LINE);
01602 expectedCalcOut.add( 01603 mulstr, pNULL, pc++, LINE);
01604 expectedCalcOut.add( 01605 mulstr, pNULL, pc++, LINE);
01606 01607 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01608 if (std::numeric_limits::is_signed 01609 && std::numeric_limits::is_integer) 01610 { 01611 expectedCalcOut.add( 01612 mulstr, overflow, pc++, LINE);
01613 } else { 01614 expectedCalcOut.add( 01615 mulstr, (T) (mid
min), pc++, LINE);
01616 } 01617 #else 01618 expectedCalcOut.add( 01619 mulstr, (T) (mid
min), pc++, LINE);
01620 #endif 01621 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01622 expectedCalcOut.add( 01623 mulstr, overflow, pc++, LINE);
01624 #else 01625 expectedCalcOut.add( 01626 mulstr, (T) (mid
max), pc++, LINE);
01627 #endif 01628 expectedCalcOut.add( 01629 mulstr, pNULL, pc++, LINE);
01630 expectedCalcOut.add( 01631 mulstr, (T) (mid
mid), pc++, LINE);
01632 01633
01634 addBinaryInstructions(instostr, "DIV", outreg, inregs); 01635 string divstr = string("DIV ") + typestr; 01636 if (min != zero) { 01637 expectedCalcOut.add( 01638 divstr, (T) (min / min), pc++, LINE); 01639 } else { 01640 expectedCalcOut.add( 01641 divstr, divbyzero, pc++, LINE);
01642 } 01643 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01644 if (std::numeric_limits::is_integer) { 01645 expectedCalcOut.add( 01646 divstr, (T) (min / max), pc++, LINE); 01647 } else { 01648 expectedCalcOut.add( 01649 divstr, underflow, pc++, LINE);
01650 } 01651 #else 01652 expectedCalcOut.add( 01653 divstr, (T) (min / max), pc++, LINE);
01654 #endif 01655 expectedCalcOut.add( 01656 divstr, pNULL, pc++, LINE);
01657 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01658 if (std::numeric_limits::is_integer) { 01659 expectedCalcOut.add( 01660 divstr, (T) (min / mid), pc++, LINE);
01661 } else { 01662 expectedCalcOut.add( 01663 divstr, underflow, pc++, LINE);
01664 } 01665 #else 01666 expectedCalcOut.add( 01667 divstr, (T) (min / mid), pc++, LINE);
01668 #endif 01669 01670 if (min != zero) { 01671 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01672 if (std::numeric_limits::is_integer) { 01673 expectedCalcOut.add( 01674 divstr, (T) (max / min), pc++, LINE); 01675 } else { 01676 expectedCalcOut.add( 01677 divstr, overflow, pc++, LINE);
01678 } 01679 #else 01680 expectedCalcOut.add( 01681 divstr, (T) (max / min), pc++, LINE); 01682 #endif 01683 } else { 01684 expectedCalcOut.add( 01685 divstr, divbyzero, pc++, LINE);
01686 } 01687 expectedCalcOut.add( 01688 divstr, (T) (max / max), pc++, LINE);
01689 expectedCalcOut.add( 01690 divstr, pNULL, pc++, LINE);
01691 expectedCalcOut.add( 01692 divstr, (T) (max / mid), pc++, LINE);
01693 01694 expectedCalcOut.add( 01695 divstr, pNULL, pc++, LINE);
01696 expectedCalcOut.add( 01697 divstr, pNULL, pc++, LINE);
01698 expectedCalcOut.add( 01699 divstr, pNULL, pc++, LINE);
01700 expectedCalcOut.add( 01701 divstr, pNULL, pc++, LINE);
01702 01703 if (min != zero) { 01704 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01705 if (std::numeric_limits::is_integer) { 01706 expectedCalcOut.add( 01707 divstr, (T) (mid / min), pc++); 01708 } else { 01709 expectedCalcOut.add( 01710 divstr, overflow, pc++, LINE);
01711 } 01712 #else 01713 expectedCalcOut.add( 01714 divstr, (T) (mid / min), pc++); 01715 #endif 01716 } else { 01717 expectedCalcOut.add( 01718 divstr, divbyzero, pc++);
01719 } 01720 expectedCalcOut.add( 01721 divstr, (T) (mid / max), pc++);
01722 expectedCalcOut.add( 01723 divstr, pNULL, pc++);
01724 expectedCalcOut.add( 01725 divstr, (T) (mid / mid), pc++);
01726 01727
01728 addUnaryInstructions(instostr, "NEG", outreg, inregs); 01729 string negstr = string("NEG ") + typestr; 01730 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01731 if (std::numeric_limits::is_signed 01732 && std::numeric_limits::is_integer) 01733 { 01734 expectedCalcOut.add( 01735 negstr, overflow, pc++, LINE);
01736 } else { 01737 expectedCalcOut.add( 01738 negstr, (T) (-min), pc++, LINE);
01739 } 01740 #else 01741 expectedCalcOut.add( 01742 negstr, (T) (-min), pc++, LINE);
01743 #endif 01744 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01745 if (!std::numeric_limits::is_signed) { 01746 expectedCalcOut.add( 01747 negstr, overflow, pc++, LINE);
01748 } else { 01749 expectedCalcOut.add( 01750 negstr, (T) (-max), pc++, LINE);
01751 } 01752 #else 01753 expectedCalcOut.add( 01754 negstr, (T) (-max), pc++, LINE);
01755 #endif 01756 expectedCalcOut.add( 01757 negstr, pNULL, pc++, LINE);
01758 #if defined(USING_NOISY_ARITHMETIC) && USING_NOISY_ARITHMETIC 01759 if (std::numeric_limits::is_signed) { 01760 expectedCalcOut.add( 01761 negstr, (T) (-mid), pc++, LINE); 01762 } else { 01763 expectedCalcOut.add( 01764 negstr, overflow, pc++, LINE);
01765 } 01766 #else 01767 expectedCalcOut.add( 01768 negstr, (T) (-mid), pc++, LINE);
01769 #endif 01770 01771 assert(outreg == static_cast(pc)); 01772 01773
01774 string testdesc = "testNativeInstructions: " + typestr; 01775 ostringstream testostr(""); 01776 01777 testostr << "I " << createRegisterString(typestr, inregs) << ";" << endl; 01778 testostr << "O " << createRegisterString(typestr, outreg) << ";" << endl; 01779 testostr << "T;" << endl; 01780 01781 testostr << instostr.str(); 01782 01783 string teststr = testostr.str(); 01784 01785 CalcAssemblerTestCase testCase1( 01786 __LINE__, testdesc.c_str(), 01787 teststr.c_str()); 01788 if (testCase1.assemble()) { 01789 testCase1.setInputMin(0); 01790 testCase1.setInputMax(1); 01791 testCase1.setInputNull(2); 01792 testCase1.template setInput(3, mid); 01793 TupleData
outputTuple = testCase1.getExpectedOutputTuple(); 01794 assert(outputTuple != NULL); 01795 expectedCalcOut.setTupleData(outputTuple); 01796 testCase1.test(&expectedCalcOut); 01797 } 01798 } 01799 01812 void CalcAssemblerTest::testBoolInstructions(StandardTypeDescriptorOrdinal type) 01813 { 01814 string typestr = getTypeString(type, CalcAssemblerTestCase::MAX_WIDTH); 01815 string boolstr = getTypeString(STANDARD_TYPE_BOOL); 01816 uint inregs = 3; 01817 01818
01819 ostringstream instostr(""); 01820 uint outreg = 0; 01821 vector<bool*> boolout; 01822 bool bFalse = false; 01823 bool bTrue = true; 01824 bool
pFalse = &bFalse; 01825 bool
pTrue = &bTrue; 01826 01827
01828 instostr << "MOVE L0, I0;" << endl; 01829 instostr << "MOVE L1, I1;" << endl; 01830 instostr << "MOVE L2, I2;" << endl; 01831 01832
01833 addUnaryInstructions(instostr, "ISNULL", outreg, inregs); 01834 boolout.push_back(pFalse); 01835 boolout.push_back(pFalse); 01836 boolout.push_back(pTrue);
01837 01838
01839 addUnaryInstructions(instostr, "ISNOTNULL", outreg, inregs); 01840 boolout.push_back(pTrue);
01841 boolout.push_back(pTrue);
01842 boolout.push_back(pFalse); 01843 01844
01845
01846 instostr << "EQ O" << outreg++ <<", L0, I0;" << endl; 01847 boolout.push_back(pTrue); 01848 instostr << "EQ O" << outreg++ <<", L1, I1;" << endl; 01849 boolout.push_back(pTrue); 01850 01851
01852 addBinaryInstructions(instostr, "EQ", outreg, inregs); 01853 boolout.push_back(pTrue);
01854 boolout.push_back(pFalse); 01855 boolout.push_back(NULL);
01856 boolout.push_back(pFalse); 01857 boolout.push_back(pTrue);
01858 boolout.push_back(NULL);
01859 boolout.push_back(NULL);
01860 boolout.push_back(NULL);
01861 boolout.push_back(NULL);
01862 01863
01864
01865 instostr << "NE O" << outreg++ <<", L0, I0;" << endl; 01866 boolout.push_back(pFalse); 01867 instostr << "NE O" << outreg++ <<", L1, I1;" << endl; 01868 boolout.push_back(pFalse); 01869 01870
01871 addBinaryInstructions(instostr, "NE", outreg, inregs); 01872 boolout.push_back(pFalse); 01873 boolout.push_back(pTrue);
01874 boolout.push_back(NULL);
01875 boolout.push_back(pTrue);
01876 boolout.push_back(pFalse); 01877 boolout.push_back(NULL);
01878 boolout.push_back(NULL);
01879 boolout.push_back(NULL);
01880 boolout.push_back(NULL);
01881 01882
01883 addBinaryInstructions(instostr, "GT", outreg, inregs); 01884 boolout.push_back(pFalse); 01885 boolout.push_back(pFalse); 01886 boolout.push_back(NULL);
01887 boolout.push_back(pTrue);
01888 boolout.push_back(pFalse); 01889 boolout.push_back(NULL);
01890 boolout.push_back(NULL);
01891 boolout.push_back(NULL);
01892 boolout.push_back(NULL);
01893 01894
01895 addBinaryInstructions(instostr, "LT", outreg, inregs); 01896 boolout.push_back(pFalse); 01897 boolout.push_back(pTrue);
01898 boolout.push_back(NULL);
01899 boolout.push_back(pFalse); 01900 boolout.push_back(pFalse); 01901 boolout.push_back(NULL);
01902 boolout.push_back(NULL);
01903 boolout.push_back(NULL);
01904 boolout.push_back(NULL);
01905 01906 if (type == STANDARD_TYPE_BOOL) { 01907
01908 addUnaryInstructions(instostr, "NOT", outreg, inregs); 01909 boolout.push_back(pTrue);
01910 boolout.push_back(pFalse); 01911 boolout.push_back(NULL);
01912 01913
01914 addBinaryInstructions(instostr, "IS", outreg, inregs); 01915 boolout.push_back(pTrue);
01916 boolout.push_back(pFalse); 01917 boolout.push_back(pFalse); 01918 boolout.push_back(pFalse); 01919 boolout.push_back(pTrue);
01920 boolout.push_back(pFalse); 01921 boolout.push_back(pFalse); 01922 boolout.push_back(pFalse); 01923 boolout.push_back(pTrue);
01924 01925
01926 addBinaryInstructions(instostr, "ISNOT", outreg, inregs); 01927 boolout.push_back(pFalse); 01928 boolout.push_back(pTrue);
01929 boolout.push_back(pTrue);
01930 boolout.push_back(pTrue);
01931 boolout.push_back(pFalse); 01932 boolout.push_back(pTrue);
01933 boolout.push_back(pTrue);
01934 boolout.push_back(pTrue);
01935 boolout.push_back(pFalse); 01936 01937
01938 addBinaryInstructions(instostr, "AND", outreg, inregs); 01939 boolout.push_back(pFalse); 01940 boolout.push_back(pFalse); 01941 boolout.push_back(pFalse); 01942 boolout.push_back(pFalse); 01943 boolout.push_back(pTrue);
01944 boolout.push_back(NULL);
01945 boolout.push_back(pFalse); 01946 boolout.push_back(NULL);
01947 boolout.push_back(NULL);
01948 01949
01950 addBinaryInstructions(instostr, "OR", outreg, inregs); 01951 boolout.push_back(pFalse); 01952 boolout.push_back(pTrue);
01953 boolout.push_back(NULL);
01954 boolout.push_back(pTrue);
01955 boolout.push_back(pTrue);
01956 boolout.push_back(pTrue);
01957 boolout.push_back(NULL);
01958 boolout.push_back(pTrue);
01959 boolout.push_back(NULL);
01960 } else { 01961
01962 addBinaryInstructions(instostr, "GE", outreg, inregs); 01963 boolout.push_back(pTrue);
01964 boolout.push_back(pFalse); 01965 boolout.push_back(NULL);
01966 boolout.push_back(pTrue);
01967 boolout.push_back(pTrue);
01968 boolout.push_back(NULL);
01969 boolout.push_back(NULL);
01970 boolout.push_back(NULL);
01971 boolout.push_back(NULL);
01972 01973
01974 addBinaryInstructions(instostr, "LE", outreg, inregs); 01975 boolout.push_back(pTrue);
01976 boolout.push_back(pTrue);
01977 boolout.push_back(NULL);
01978 boolout.push_back(pFalse); 01979 boolout.push_back(pTrue);
01980 boolout.push_back(NULL);
01981 boolout.push_back(NULL);
01982 boolout.push_back(NULL);
01983 boolout.push_back(NULL);
01984 } 01985 01986 assert(outreg == boolout.size()); 01987 01988
01989 string testdesc = "testBoolInstructions: " + typestr; 01990 ostringstream testostr(""); 01991 01992 testostr << "I " << createRegisterString(typestr, inregs) << ";" << endl; 01993 testostr << "L " << createRegisterString(typestr, inregs) << ";" << endl; 01994 testostr << "O " << createRegisterString(boolstr, outreg) << ";" << endl; 01995 testostr << "T;" << endl; 01996 01997 testostr << instostr.str(); 01998 01999 string teststr = testostr.str(); 02000 02001 CalcAssemblerTestCase testCase1( 02002 __LINE__, testdesc.c_str(), teststr.c_str()); 02003 if (testCase1.assemble()) { 02004 testCase1.setInputMin(0); 02005 testCase1.setInputMax(1); 02006 testCase1.setInputNull(2); 02007 for (uint i = 0; i < outreg; i++) { 02008 if (boolout[i]) { 02009 testCase1.setExpectedOutput(i, boolout[i]); 02010 } else { 02011 testCase1.setExpectedOutputNull(i); 02012 } 02013 } 02014 testCase1.test(); 02015 } 02016 } 02017 02018 void CalcAssemblerTest::testStandardTypes() 02019 { 02020 string max[STANDARD_TYPE_END_NO_UNICODE]; 02021 string min[STANDARD_TYPE_END_NO_UNICODE]; 02022 string overflow[STANDARD_TYPE_END_NO_UNICODE]; 02023 string underflow[STANDARD_TYPE_END_NO_UNICODE]; 02024 02025 min[STANDARD_TYPE_BOOL] = "0"; 02026 max[STANDARD_TYPE_BOOL] = "1"; 02027 underflow[STANDARD_TYPE_BOOL] = "-1"; 02028 overflow[STANDARD_TYPE_BOOL] = "2"; 02029 02030 min[STANDARD_TYPE_INT_8] = "-128"; 02031 max[STANDARD_TYPE_INT_8] = "127"; 02032 min[STANDARD_TYPE_UINT_8] = "0"; 02033 max[STANDARD_TYPE_UINT_8] = "255"; 02034 02035 underflow[STANDARD_TYPE_INT_8] = "-129"; 02036 overflow[STANDARD_TYPE_INT_8] = "128"; 02037 underflow[STANDARD_TYPE_UINT_8] = "-1"; 02038 overflow[STANDARD_TYPE_UINT_8] = "256"; 02039 02040 min[STANDARD_TYPE_INT_16] = "-32768"; 02041 max[STANDARD_TYPE_INT_16] = "32767"; 02042 min[STANDARD_TYPE_UINT_16] = "0"; 02043 max[STANDARD_TYPE_UINT_16] = "65535"; 02044 02045 underflow[STANDARD_TYPE_INT_16] = "-32769"; 02046 overflow[STANDARD_TYPE_INT_16] = "32768"; 02047 underflow[STANDARD_TYPE_UINT_16] = "-1"; 02048 overflow[STANDARD_TYPE_UINT_16] = "65536"; 02049 02050 min[STANDARD_TYPE_INT_32] = "-2147483648"; 02051 max[STANDARD_TYPE_INT_32] = "2147483647"; 02052 min[STANDARD_TYPE_UINT_32] = "0"; 02053 max[STANDARD_TYPE_UINT_32] = "4294967295"; 02054 02055 underflow[STANDARD_TYPE_INT_32] = "-2147483649"; 02056 overflow[STANDARD_TYPE_INT_32] = "2147483648"; 02057 underflow[STANDARD_TYPE_UINT_32] = "-1"; 02058 overflow[STANDARD_TYPE_UINT_32] = "4294967296"; 02059 02060 min[STANDARD_TYPE_INT_64] = "-9223372036854775808"; 02061 max[STANDARD_TYPE_INT_64] = "9223372036854775807"; 02062 min[STANDARD_TYPE_UINT_64] = "0"; 02063 max[STANDARD_TYPE_UINT_64] = "18446744073709551615"; 02064 02065 underflow[STANDARD_TYPE_INT_64] = "-9223372036854775809"; 02066 overflow[STANDARD_TYPE_INT_64] = "9223372036854775808"; 02067 underflow[STANDARD_TYPE_UINT_64] = "-1"; 02068 overflow[STANDARD_TYPE_UINT_64] = "18446744073709551616"; 02069 02070 min[STANDARD_TYPE_REAL] = "1.17549e-38"; 02071 max[STANDARD_TYPE_REAL] = "3.40282e+38"; 02072 min[STANDARD_TYPE_DOUBLE] = "2.22507e-308"; 02073 max[STANDARD_TYPE_DOUBLE] = "1.79769e+308"; 02074 02075
02076
02077 underflow[STANDARD_TYPE_REAL] = "1.17549e-46"; 02078 overflow[STANDARD_TYPE_REAL] = "3.40282e+39"; 02079 underflow[STANDARD_TYPE_DOUBLE] = "2.22507e-324"; 02080 overflow[STANDARD_TYPE_DOUBLE] = "1.79769e+309"; 02081 02082 for (uint i = STANDARD_TYPE_MIN; i < STANDARD_TYPE_END_NO_UNICODE; i++) { 02083
02084
02085
02086 StandardTypeDescriptorOrdinal type = StandardTypeDescriptorOrdinal(i); 02087 string typestr = getTypeString(type, CalcAssemblerTestCase::MAX_WIDTH); 02088 string testdesc = "testStandardTypes: " + typestr; 02089 ostringstream testostr(""); 02090 testostr << "I " << createRegisterString(typestr, 3) << ";" << endl; 02091 testostr << "O " << createRegisterString(typestr, 4) << ";" << endl; 02092 testostr << "T;" << endl; 02093 testostr << "MOVE O0, I0;" << endl; 02094 testostr << "MOVE O1, I1;" << endl; 02095 testostr << "MOVE O2, I2;" << endl; 02096 testostr << "TONULL O3;" << endl; 02097 string teststr = testostr.str(); 02098 02099 CalcAssemblerTestCase testCase1( 02100 __LINE__, testdesc.c_str(), teststr.c_str()); 02101 if (testCase1.assemble()) { 02102 testCase1.setInputMin(0); 02103 testCase1.setExpectedOutputMin(0); 02104 testCase1.setInputMax(1); 02105 testCase1.setExpectedOutputMax(1); 02106 testCase1.setInputNull(2); 02107 testCase1.setExpectedOutputNull(2); 02108 testCase1.setExpectedOutputNull(3); 02109 testCase1.test(); 02110 } 02111 02112 if (StandardTypeDescriptor::isArray(type)) { 02113
02114 assert (testCase1.getInput(0) == min[type]); 02115 assert (testCase1.getInput(1) == max[type]); 02116 } 02117 02118
02119
02120 ostringstream testostr2(""); 02121 testostr2 << "O " << createRegisterString(typestr, 3) << ";" << endl; 02122 testostr2 << "C " << createRegisterString(typestr, 3) << ";" << endl; 02123 testostr2 << "V " << testCase1.getInput(0) 02124 << ", " << testCase1.getInput(1) 02125 << ", " << testCase1.getInput(2) 02126 << ";" << endl; 02127 testostr2 << "T;" << endl; 02128 testostr2 << "MOVE O0, C0;" << endl; 02129 testostr2 << "MOVE O1, C1;" << endl; 02130 testostr2 << "MOVE O2, C2;" << endl; 02131 string teststr2 = testostr2.str(); 02132 02133 CalcAssemblerTestCase testCase2( 02134 __LINE__, testdesc.c_str(), teststr2.c_str()); 02135 if (testCase2.assemble()) { 02136 testCase2.setExpectedOutputMin(0); 02137 testCase2.setExpectedOutputMax(1); 02138 testCase2.setExpectedOutputNull(2); 02139 testCase2.test(); 02140 } 02141 02142 if (StandardTypeDescriptor::isArray(type)) { 02143
02144
02145 ostringstream testostr3(""); 02146 testostr3 << "O " << createRegisterString(typestr, 1) 02147 << ";" << endl; 02148 testostr3 << "C " << createRegisterString(typestr, 1) 02149 << ";" << endl; 02150 testostr3 << "V " << underflow[type] << ";" << endl; 02151 testostr3 << "T;" << endl; 02152 testostr3 << "MOVE O0, C0;" << endl; 02153 02154 string teststr3 = testostr3.str(); 02155 02156 CalcAssemblerTestCase testCase3( 02157 __LINE__, testdesc.c_str(), teststr3.c_str()); 02158 if (type == STANDARD_TYPE_INT_64 || type == STANDARD_TYPE_DOUBLE) { 02159 testCase3.expectAssemblerError("out of"); 02160 } else if (underflow[type] == "-1") { 02161 testCase3.expectAssemblerError("Invalid value"); 02162 } else { 02163 testCase3.expectAssemblerError( 02164 "bad numeric"); 02165 } 02166 testCase3.assemble(); 02167 02168
02169 ostringstream testostr4(""); 02170 testostr4 << "O " << createRegisterString(typestr, 1) 02171 << ";" << endl; 02172 testostr4 << "C " << createRegisterString(typestr, 1) 02173 << ";" << endl; 02174 testostr4 << "V " << overflow[type] << ";" << endl; 02175 testostr4 << "T;" << endl; 02176 testostr4 << "MOVE O0, C0;" << endl; 02177 02178 string teststr4 = testostr4.str(); 02179 02180 CalcAssemblerTestCase testCase4( 02181 __LINE__, testdesc.c_str(), 02182 teststr4.c_str()); 02183 if (type == STANDARD_TYPE_UINT_64 || type == STANDARD_TYPE_DOUBLE) { 02184 testCase4.expectAssemblerError("out of range"); 02185 } else if (type == STANDARD_TYPE_BOOL) { 02186 testCase4.expectAssemblerError("Invalid value"); 02187 } else { 02188 testCase4.expectAssemblerError( 02189 "bad numeric"); 02190 } 02191 testCase4.assemble(); 02192 } 02193 02194 testBoolInstructions(type); 02195 02196 switch (type) { 02197 case STANDARD_TYPE_UINT_8: 02198 testNativeInstructions(type); 02199 testIntegralNativeInstructions(type); 02200 break; 02201 02202 case STANDARD_TYPE_INT_8: 02203 testNativeInstructions(type); 02204 testIntegralNativeInstructions(type); 02205 break; 02206 02207 case STANDARD_TYPE_UINT_16: 02208 testNativeInstructions(type); 02209 testIntegralNativeInstructions(type); 02210 break; 02211 02212 case STANDARD_TYPE_INT_16: 02213 testNativeInstructions(type); 02214 testIntegralNativeInstructions(type); 02215 break; 02216 02217 case STANDARD_TYPE_UINT_32: 02218 testNativeInstructions(type); 02219 testIntegralNativeInstructions(type); 02220 break; 02221 02222 case STANDARD_TYPE_INT_32: 02223 testNativeInstructions(type); 02224 testIntegralNativeInstructions(type); 02225 break; 02226 02227 case STANDARD_TYPE_UINT_64: 02228 testNativeInstructions(type); 02229 testIntegralNativeInstructions(type); 02230 break; 02231 02232 case STANDARD_TYPE_INT_64: 02233 testNativeInstructions(type); 02234 testIntegralNativeInstructions(type); 02235 break; 02236 02237 case STANDARD_TYPE_REAL: 02238 testNativeInstructions(type); 02239 break; 02240 02241 case STANDARD_TYPE_DOUBLE: 02242 testNativeInstructions(type); 02243 break; 02244 02245 default: 02246 break; 02247 } 02248 } 02249 } 02250 02251 void CalcAssemblerTest::testLiteralBinding() 02252 { 02253
02254
02255 CalcAssemblerTestCase testCase1( 02256 LINE, "OVERFLOW U2", 02257 "O u2; C u2; V 777777; T; ADD O0, C0, C0;"); 02258 testCase1.expectAssemblerError( 02259 "bad numeric conversion"); 02260 testCase1.assemble(); 02261 02262
02263 CalcAssemblerTestCase testCase2( 02264 LINE, "BADVALUE U2", 02265 "O u2; C u2; V 2451.342; T; ADD O0, C0, C0;"); 02266 testCase2.expectAssemblerError("Invalid value"); 02267 testCase2.assemble(); 02268 02269
02270 CalcAssemblerTestCase testCase2b( 02271 LINE, "EXP", 02272 "O r, r; C r, r;\nV 24.0e-4, 54.0E6;\n" 02273 "T;\nMOVE O0, C0; MOVE O1, C1;"); 02274 if (testCase2b.assemble()) { 02275 testCase2b.setExpectedOutput(0, 0.0024); 02276 testCase2b.setExpectedOutput(1, 54000000.0); 02277 testCase2b.test(); 02278 } 02279 02280
02281 CalcAssemblerTestCase testCase3( 02282 LINE, "NEGVALUE U4", 02283 "O u4; C u4; V -513; T; ADD O0, C0, C0;"); 02284 testCase3.expectAssemblerError("Invalid value"); 02285 testCase3.assemble(); 02286 02287
02288 CalcAssemblerTestCase testCase4( 02289 LINE, "NEGVALUE U4", 02290 "O s2; C s2; V 40000; T; ADD O0, C0, C0;"); 02291 testCase4.expectAssemblerError( 02292 "bad numeric conversion"); 02293 testCase4.assemble(); 02294 02295
02296 CalcAssemblerTestCase testCase5( 02297 LINE, "BAD INDEX", "I s1; C s1; V 1, 2;"); 02298 testCase5.expectAssemblerError("out of bounds"); 02299 testCase5.assemble(); 02300 02301 CalcAssemblerTestCase testCase6( 02302 LINE, "LREG/VAL MISMATCH", "I bo; C s1, s4; V 1;"); 02303 testCase6.expectAssemblerError("Error binding literal"); 02304 testCase6.assemble(); 02305 02306
02307 CalcAssemblerTestCase testCase7( 02308 LINE, "LREG/VAL MISMATCH", "I s1, s4; V 1, 4; T; RETURN;"); 02309 testCase7.expectAssemblerError(""); 02310 testCase7.assemble(); 02311 02312
02313 CalcAssemblerTestCase testCase8(LINE, "BOOL = 2", "I bo; C bo; V 2;"); 02314 testCase8.expectAssemblerError("Invalid value"); 02315 testCase8.assemble(); 02316 02317
02318 string teststr9; 02319 teststr9 = "O c,4, u8; C c,4, u8; V 0x"; 02320 teststr9 += stringToHex("test"); 02321 teststr9 += ", 60000000; T; MOVE O0, C0; MOVE O1, C1;"; 02322 CalcAssemblerTestCase testCase9( 02323 LINE, "STRING (CHAR) = "test"", teststr9.c_str()); 02324 if (testCase9.assemble()) { 02325 testCase9.setExpectedOutput(0, "test", 4); 02326 testCase9.setExpectedOutput<uint64_t>(1, 60000000); 02327 testCase9.test(); 02328 } 02329 02330
02331 string teststr10; 02332 teststr10 = "O vc,8; C vc,8; V 0x"; 02333 teststr10 += stringToHex("short"); 02334 teststr10 += "; T; MOVE O0, C0;"; 02335 CalcAssemblerTestCase testCase10( 02336 LINE, "STRING (VARCHAR) = "short"", teststr10.c_str()); 02337 if (testCase10.assemble()) { 02338 testCase10.setExpectedOutput(0, "short", 5); 02339 testCase10.test(); 02340 } 02341 02342
02343 string teststr11; 02344 teststr11 = "O vc,8, u8; C vc,8, u8; V 0x"; 02345 teststr11 += stringToHex("muchtoolongstring"); 02346 teststr11 += "; T; MOVE O0, C0;"; 02347 02348 CalcAssemblerTestCase testCase11( 02349 LINE, "STRING (VARCHAR) TOO LONG", teststr11.c_str()); 02350 testCase11.expectAssemblerError("too long"); 02351 testCase11.assemble(); 02352 02353
02354 string teststr12; 02355 teststr12 = "O c,100, u8; C c,100, u8; V 0x"; 02356 teststr12 += stringToHex("binarytooshort"); 02357 teststr12 += ", 60000000; T; MOVE O0, C0; MOVE O1, C1;"; 02358 CalcAssemblerTestCase testCase12( 02359 LINE, "STRING (BINARY) TOO SHORT", teststr12.c_str()); 02360 testCase12.expectAssemblerError("not equal"); 02361 testCase12.assemble(); 02362 02363
02364 string teststr13; 02365 teststr13 = "O b,1, vb,1; C b,1, vb,1; V 0xFF,0xFF;"; 02366 teststr13 += "T; MOVE O0, C0; MOVE O1, C1;"; 02367 CalcAssemblerTestCase testCase13( 02368 LINE, "STRING (BINARY) 1", teststr13.c_str()); 02369 if (testCase13.assemble()) { 02370 uint8_t tmp = 0xFF; 02371 testCase13.setExpectedOutput<uint8_t>(0, &tmp, 1); 02372 testCase13.setExpectedOutput<uint8_t>(1, &tmp, 1); 02373 testCase13.test(); 02374 } 02375 } 02376 02377 void CalcAssemblerTest::testAdd() 02378 { 02379 CalcAssemblerTestCase testCase1( 02380 LINE, "ADD U4", "I u4, u4;\nO u4;\nT;\nADD O0, I0, I1;"); 02381 if (testCase1.assemble()) { 02382 testCase1.setInput<uint32_t>(0, 100); 02383 testCase1.setInput<uint32_t>(1, 4030); 02384 testCase1.setExpectedOutput<uint32_t>(0, 4130); 02385 testCase1.test(); 02386 } 02387 02388 CalcAssemblerTestCase testCase2( 02389 LINE, "ADD UNKNOWN INST", 02390 "I u2, u4;\nO u4;\nT;\nADD O0, I0, I1;"); 02391 testCase2.expectAssemblerError("not a registered instruction"); 02392 testCase2.assemble(); 02393 02394 CalcAssemblerTestCase testCase3( 02395 LINE, "ADD O0 I0", 02396 "I u2, u4;\nO u4;\nT;\nADD O0, I0;"); 02397 testCase3.expectAssemblerError("not a registered instruction"); 02398 testCase3.assemble(); 02399 02400 CalcAssemblerTestCase testCase4(LINE, "ADD FLOAT", "I r, r;\nO r, r;\n" 02401 "C r, r;\nV 0.3, -2.3;\n" 02402 "T;\nADD O0, I0, C0;\nADD O1, I1, C1;"); 02403 if (testCase4.assemble()) { 02404 testCase4.setInput(0, 200); 02405 testCase4.setInput(1, 3000); 02406 testCase4.setExpectedOutput(0, 200+0.3); 02407 testCase4.setExpectedOutput(1, 3000-2.3); 02408 testCase4.test(); 02409 } 02410 } 02411 02412 void CalcAssemblerTest::testBool() 02413 { 02414 CalcAssemblerTestCase testCase1( 02415 LINE, "AND 1 1", 02416 "O bo;\nC bo, bo;\nV 1, 1; T;\n" 02417 "AND O0, C0, C1;"); 02418 if (testCase1.assemble()) { 02419 testCase1.setExpectedOutput(0, true); 02420 testCase1.test(); 02421 } 02422 02423 CalcAssemblerTestCase testCase2( 02424 LINE, "EQ 1 0", 02425 "O bo;\nC bo, bo;\nV 1, 0; T;\n" 02426 "EQ O0, C0, C1;"); 02427 if (testCase2.assemble()) { 02428 testCase2.setExpectedOutput(0, false); 02429 testCase2.test(); 02430 } 02431 } 02432 02433 void CalcAssemblerTest::testPointer() 02434 { 02435 CalcAssemblerTestCase testCase1( 02436 LINE, "CHAR EQ", 02437 "I c,10, c,10;\nO bo, bo;\nT;\n" 02438 "EQ O0, I0, I1; EQ O1, I0, I0;"); 02439 if (testCase1.assemble()) { 02440 testCase1.setInput(0, "test", 4); 02441 testCase1.setInput(1, "junk", 4); 02442 testCase1.setExpectedOutput(0, false); 02443 testCase1.setExpectedOutput(1, true); 02444 testCase1.test(); 02445 } 02446 02447 CalcAssemblerTestCase testCase2( 02448 LINE, "VARCHAR EQ/ADD", 02449 "I vc,255, vc,255;\n" 02450 "O bo, bo, vc,255, u4;\nC u4; V 10;T;\n" 02451 "EQ O0, I0, I1; EQ O1, I0, I0; ADD O2, I0, C0; GETS O3, I0;"); 02452 if (testCase2.assemble()) { 02453 testCase2.setInput( 02454 0, "test varchar equal and add ....", 31); 02455 testCase2.setInput(1, "junk", 4); 02456 testCase2.setExpectedOutput(0, false); 02457 testCase2.setExpectedOutput(1, true); 02458 testCase2.setExpectedOutput(2, "ar equal and add ....", 21); 02459 testCase2.setExpectedOutput<uint32_t>(3, 31); 02460 testCase2.test(); 02461 } 02462 } 02463 02464 void CalcAssemblerTest::testJump() 02465 { 02466
02467 CalcAssemblerTestCase testCase1( 02468 LINE, "JUMP TRUE", 02469 "I u2, u2;\nO u2, u2;\nL bo;\n" 02470 "C u2, u2;\nV 0, 1;\nT;\n" 02471 "MOVE O0, C0;\nMOVE O1, C0;\n" 02472 "ADD O0, O0, I0;\nADD O1, O1, C1;\n" 02473 "LT L0, O1, I1;\nJMPT @2, L0;\n"); 02474 if (testCase1.assemble()) { 02475 testCase1.setInput<uint16_t>(0, 3); 02476 testCase1.setInput<uint16_t>(1, 4); 02477 testCase1.setExpectedOutput<uint16_t>(0, 12); 02478 testCase1.setExpectedOutput<uint16_t>(1, 4); 02479 testCase1.test(); 02480 } 02481 02482
02483 CalcAssemblerTestCase testCase2( 02484 LINE, "INVALID PC", "I u2; O u2; T; JMP @10;"); 02485 testCase2.expectAssemblerError("Invalid PC"); 02486 testCase2.assemble(); 02487 02488
02489 CalcAssemblerTestCase testCase3( 02490 LINE, "VALID PC", 02491 "I u2; O u2;\n" 02492 "C bo; V 0; T;\n" 02493 "MOVE O0, I0;\n" 02494 "JMPF @4, C0;\n" 02495 "ADD O0, O0, I0;\n" 02496 "ADD O0, O0, I0;\n" 02497 "ADD O0, O0, I0;\n"); 02498 if (testCase3.assemble()) { 02499 testCase3.setInput<uint16_t>(0, 15); 02500 testCase3.setExpectedOutput<uint16_t>(0, 30); 02501 testCase3.test(); 02502 } 02503 } 02504 02505 void CalcAssemblerTest::testReturn() 02506 { 02507
02508 CalcAssemblerTestCase testCase1( 02509 LINE, "RETURN", 02510 "I u2;\nO u2;\n" 02511 "T;\n" 02512 "MOVE O0, I0;\n" 02513 "RETURN;\n" 02514 "ADD O0, I0, I0;\n"); 02515 if (testCase1.assemble()) { 02516 testCase1.setInput<uint16_t>(0, 100); 02517 testCase1.setExpectedOutput<uint16_t>(0, 100); 02518 testCase1.test(); 02519 } 02520 } 02521 02522 void convertFloatToInt( 02523 RegisterRef
regOut, 02524 RegisterRef
regIn) 02525 { 02526 regOut->value((int)regIn->value()); 02527 } 02528 02529 void CalcAssemblerTest::testExtended() 02530 { 02531
02532 ExtendedInstructionTable
table = 02533 InstructionFactory::getExtendedInstructionTable(); 02534 assert(table != NULL); 02535 02536 vector parameterTypes; 02537 02538
02539 parameterTypes.resize(2); 02540 parameterTypes[0] = STANDARD_TYPE_UINT_32; 02541 parameterTypes[1] = STANDARD_TYPE_REAL; 02542 table->add( 02543 "convert", 02544 parameterTypes, 02545 (ExtendedInstruction2<int32_t, float>
) NULL, 02546 &convertFloatToInt); 02547 02548
02549 CalcAssemblerTestCase testCase1( 02550 LINE, "CONVERT FLOAT TO INT", 02551 "I r; O u4;\n" 02552 "T;\n" 02553 "CALL 'convert(O0, I0);\n"); 02554 if (testCase1.assemble()) { 02555 testCase1.setInput(0, 53.34); 02556 testCase1.setExpectedOutput<uint32_t>(0, 53); 02557 testCase1.test(); 02558 } 02559 02560 CalcAssemblerTestCase testCase2( 02561 LINE, "CONVERT INT TO FLOAT (NOT REGISTERED)", 02562 "I u4; O r;\n" 02563 "T;\n" 02564 "CALL 'convert(O0, I0);\n"); 02565 testCase2.expectAssemblerError("not registered"); 02566 testCase2.assemble(); 02567 } 02568 02569 void CalcAssemblerTest::testInvalidPrograms() 02570 { 02571 const char
parse_error = "error"; 02572 02573 CalcAssemblerTestCase testCase1(LINE, "JUNK", "Junk"); 02574 testCase1.expectAssemblerError(parse_error); 02575 testCase1.assemble(); 02576 02577
02578 CalcAssemblerTestCase testCase2( 02579 LINE, "UNKNOWN INST", "I u2, u4;\nO u4;\nT;\nBAD O0, I0;"); 02580 testCase2.expectAssemblerError("not a registered instruction"); 02581 testCase2.assemble(); 02582 02583
02584 CalcAssemblerTestCase testCase3( 02585 LINE, "AND float", "I d, d;\nO d;\nT;\nAND O0, I0, I1;"); 02586 testCase3.expectAssemblerError("not a registered instruction"); 02587 testCase3.assemble(); 02588 02589 CalcAssemblerTestCase testCase4( 02590 LINE, "BAD SIGNATURE", 02591 "I u2, u4;\nO u4;\nT;\nBAD O0, I0, I0, I1;"); 02592 testCase4.expectAssemblerError(parse_error); 02593 testCase4.assemble(); 02594 02595 CalcAssemblerTestCase testCase5( 02596 LINE, "BAD INST", "I u2, u4;\nO u4;\nT;\nklk34dfw;"); 02597 testCase5.expectAssemblerError(parse_error); 02598 testCase5.assemble(); 02599 02600
02601 CalcAssemblerTestCase testCase6( 02602 LINE, "BAD REG INDEX", "I u2, u4;\nO u4;\nT;\n\nADD O0, I0, I12;"); 02603 testCase6.expectAssemblerError("out of bounds"); 02604 testCase6.assemble(); 02605 02606
02607 CalcAssemblerTestCase testCase7( 02608 LINE, "BAD REG INDEX", 02609 "I u2, u4;\nO u4;\nT;\n" 02610 "ADD O0, I0, I888888888888888888888888888888888888888888;"); 02611 testCase7.expectAssemblerError("out of range"); 02612 testCase7.assemble(); 02613 02614
02615 } 02616 02617 void CalcAssemblerTest::testComments() 02618 { 02619 const char
parse_error = "error"; 02620 02621 CalcAssemblerTestCase testCase1( 02622 LINE, "COMMENTS (ONE LINE)", 02623 "I u2;\nO /
comments / u2;\n" 02624 "T;\n" 02625 "MOVE O0, I0;\n" 02626 "RETURN;\n" 02627 "ADD O0, I0, I0;\n"); 02628 if (testCase1.assemble()) { 02629 testCase1.setInput<uint16_t>(0, 100); 02630 testCase1.setExpectedOutput<uint16_t>(0, 100); 02631 testCase1.test(); 02632 } 02633 02634 CalcAssemblerTestCase testCase2( 02635 LINE, "COMMENTS (MULTILINE)", 02636 "I u2;\nO u2; / \n/\n" 02637 "T;\n" 02638 "MOVE O0, I0;\n" 02639 "RETURN;\n" 02640 "ADD O0, I0, I0;\n"); 02641 if (testCase2.assemble()) { 02642 testCase2.setInput<uint16_t>(0, 100); 02643 testCase2.setExpectedOutput<uint16_t>(0, 100); 02644 testCase2.test(); 02645 } 02646 02647 CalcAssemblerTestCase testCase3( 02648 LINE, "COMMENTS (MULTIPLE)", 02649 "I u2;\nO u2;\n" 02650 "T;\n" 02651 "MOVE O0, /
/
MOVE\n
\nO0 / I0;\n" 02652 "RETURN;\n" 02653 "ADD / FOR '0x' / O0, I0, I0;\n"); 02654 if (testCase3.assemble()) { 02655 testCase3.setInput<uint16_t>(0, 100); 02656 testCase3.setExpectedOutput<uint16_t>(0, 100); 02657 testCase3.test(); 02658 } 02659 02660 CalcAssemblerTestCase testCase4( 02661 LINE, "UNCLOSED COMMENT", 02662 "I u2;\nO u2;\n" 02663 "T;\n" 02664 "MOVE O0, / I0;\n" 02665 "RETURN;\n" 02666 "ADD O0, I0, I0;\n"); 02667 testCase4.expectAssemblerError("Unterminated comment"); 02668 testCase4.assemble(); 02669 02670 CalcAssemblerTestCase testCase5( 02671 LINE, "CLOSE COMMENT ONLY", 02672 "I u2;\nO u2;\n" 02673 "T;\n" 02674 "MOVE O0, */ I0;\n" 02675 "RETURN;\n" 02676 "ADD O0, I0, I0;\n"); 02677
02678
02679
02680 testCase5.expectAssemblerError(parse_error); 02681 testCase5.assemble(); 02682 } 02683 02684 #if 0 02685 int main (int argc, char **argv) 02686 { 02687 ProgramName = argv[0]; 02688 InstructionFactory inst(); 02689 InstructionFactory::registerInstructions(); 02690 02691 try { 02692 CalcAssemblerTest test; 02693 test.testAssembler(); 02694 } catch (exception& ex) { 02695 cerr << ex.what() << endl; 02696 } 02697 02698 cout << CalcAssemblerTestCase::getPassedNumber() << "/" 02699 << CalcAssemblerTestCase::getTestNumber() << " tests passed" << endl; 02700 return CalcAssemblerTestCase::getFailedNumber(); 02701 } 02702 02703 #endif 02704 FENNEL_UNIT_TEST_SUITE(CalcAssemblerTest); 02705 02706