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/StringToHex.h"
00031 #include "fennel/calculator/InstructionFactory.h"
00032 #include "fennel/common/FennelExcn.h"
00033 #include "fennel/calculator/ExtendedInstructionTable.h"
00034 #include "fennel/calculator/ExtendedInstruction.h"
00035
00036 #include <boost/test/test_tools.hpp>
00037 #include <boost/scoped_array.hpp>
00038 #include <string>
00039 #include <limits>
00040
00041
00042 using namespace fennel;
00043 using namespace std;
00044
00045
00046 class CalcExtContextTest : virtual public TestBase, public TraceSource
00047 {
00048 void setupExtendedTestInstructions();
00049 void testCalcExtContext();
00050 void testCalcExtContextPost();
00051
00052 void printOutput(
00053 TupleData const & tup,
00054 Calculator const & calc);
00055
00056 public:
00057 explicit CalcExtContextTest()
00058 : TraceSource(shared_from_this(),"CalcExtContextTest")
00059 {
00060 CalcInit::instance();
00061 FENNEL_UNIT_TEST_CASE(CalcExtContextTest, testCalcExtContext);
00062 FENNEL_UNIT_TEST_CASE(CalcExtContextTest, testCalcExtContextPost);
00063 }
00064
00065 virtual ~CalcExtContextTest()
00066 {
00067 }
00068 };
00069
00070
00071 void
00072 CalcExtContextTest::printOutput(
00073 TupleData const & tup,
00074 Calculator const & calc)
00075 {
00076 #if 0
00077 TuplePrinter tuplePrinter;
00078 tuplePrinter.print(cout, calc.getOutputRegisterDescriptor(), tup);
00079 cout << endl;
00080 #endif
00081 }
00082
00083
00084 class EICtx : public ExtendedInstructionContext
00085 {
00086 public:
00087 EICtx()
00088 {
00089 mCount++;
00090 BOOST_MESSAGE(mCount);
00091 }
00092 ~EICtx()
00093 {
00094 mCount--;
00095 BOOST_MESSAGE(mCount);
00096 }
00097 static int mCount;
00098 };
00099
00100 int EICtx::mCount = 0;
00101
00102 void
00103 ctxInst1(
00104 boost::scoped_ptr<ExtendedInstructionContext>& context,
00105 RegisterRef<bool>* op)
00106 {
00107 if (context.get()) {
00108 op->value(false);
00109 } else {
00110 context.reset(new EICtx);
00111 op->value(true);
00112 }
00113 }
00114
00115 void
00116 ctxInst2(
00117 boost::scoped_ptr<ExtendedInstructionContext>& context,
00118 RegisterRef<bool>* op,
00119 RegisterRef<bool>* dummy2)
00120 {
00121 if (context.get()) {
00122 op->value(false);
00123 } else {
00124 context.reset(new EICtx);
00125 op->value(true);
00126 }
00127 }
00128
00129 void
00130 ctxInst3(
00131 boost::scoped_ptr<ExtendedInstructionContext>& context,
00132 RegisterRef<bool>* op,
00133 RegisterRef<bool>* dummy2,
00134 RegisterRef<bool>* dummy3)
00135 {
00136 if (context.get()) {
00137 op->value(false);
00138 } else {
00139 context.reset(new EICtx);
00140 op->value(true);
00141 }
00142 }
00143
00144 void
00145 ctxInst4(
00146 boost::scoped_ptr<ExtendedInstructionContext>& context,
00147 RegisterRef<bool>* op,
00148 RegisterRef<bool>* dummy2,
00149 RegisterRef<bool>* dummy3,
00150 RegisterRef<bool>* dummy4)
00151 {
00152 if (context.get()) {
00153 op->value(false);
00154 } else {
00155 context.reset(new EICtx);
00156 op->value(true);
00157 }
00158 }
00159
00160 void
00161 ctxInst5(
00162 boost::scoped_ptr<ExtendedInstructionContext>& context,
00163 RegisterRef<bool>* op,
00164 RegisterRef<bool>* dummy2,
00165 RegisterRef<bool>* dummy3,
00166 RegisterRef<bool>* dummy4,
00167 RegisterRef<bool>* dummy5)
00168 {
00169 if (context.get()) {
00170 op->value(false);
00171 } else {
00172 context.reset(new EICtx);
00173 op->value(true);
00174 }
00175 }
00176
00177 void
00178 CalcExtContextTest::setupExtendedTestInstructions()
00179 {
00180 ExtendedInstructionTable* eit =
00181 InstructionFactory::getExtendedInstructionTable();
00182 ExtendedInstructionDef* inst;
00183
00184 vector<StandardTypeDescriptorOrdinal> params;
00185 params.push_back(STANDARD_TYPE_BOOL);
00186
00187 eit->add(
00188 "ctxInst1", params,
00189 (ExtendedInstruction1Context<bool>*) NULL,
00190 ctxInst1);
00191 inst = (*eit)["ctxInst1(bo)"];
00192 BOOST_REQUIRE(inst);
00193 BOOST_CHECK_EQUAL(inst->getName(),string("ctxInst1"));
00194 BOOST_CHECK_EQUAL(inst->getParameterTypes().size(), 1);
00195
00196
00197 params.push_back(STANDARD_TYPE_BOOL);
00198
00199 eit->add(
00200 "ctxInst2", params,
00201 (ExtendedInstruction2Context<bool,bool>*) NULL,
00202 ctxInst2);
00203 inst = (*eit)["ctxInst2(bo,bo)"];
00204 BOOST_REQUIRE(inst);
00205 BOOST_CHECK_EQUAL(inst->getName(),string("ctxInst2"));
00206 BOOST_CHECK_EQUAL(inst->getParameterTypes().size(), 2);
00207
00208
00209 params.push_back(STANDARD_TYPE_BOOL);
00210
00211 eit->add(
00212 "ctxInst3", params,
00213 (ExtendedInstruction3Context<bool,bool,bool>*) NULL,
00214 ctxInst3);
00215 inst = (*eit)["ctxInst3(bo,bo,bo)"];
00216 BOOST_REQUIRE(inst);
00217 BOOST_CHECK_EQUAL(inst->getName(),string("ctxInst3"));
00218 BOOST_CHECK_EQUAL(inst->getParameterTypes().size(), 3);
00219
00220
00221 params.push_back(STANDARD_TYPE_BOOL);
00222
00223 eit->add(
00224 "ctxInst4", params,
00225 (ExtendedInstruction4Context<bool,bool,bool,bool>*) NULL,
00226 ctxInst4);
00227 inst = (*eit)["ctxInst4(bo,bo,bo,bo)"];
00228 BOOST_REQUIRE(inst);
00229 BOOST_CHECK_EQUAL(inst->getName(),string("ctxInst4"));
00230 BOOST_CHECK_EQUAL(inst->getParameterTypes().size(), 4);
00231
00232
00233 params.push_back(STANDARD_TYPE_BOOL);
00234
00235 eit->add(
00236 "ctxInst5", params,
00237 (ExtendedInstruction5Context<bool,bool,bool,bool,bool>*) NULL,
00238 ctxInst5);
00239 inst = (*eit)["ctxInst5(bo,bo,bo,bo,bo)"];
00240 BOOST_REQUIRE(inst);
00241 BOOST_CHECK_EQUAL(inst->getName(),string("ctxInst5"));
00242 BOOST_CHECK_EQUAL(inst->getParameterTypes().size(), 5);
00243
00244 }
00245
00246
00247 void
00248 CalcExtContextTest::testCalcExtContext()
00249 {
00250
00251 setupExtendedTestInstructions();
00252
00253 ostringstream pg("");
00254
00255 pg << "O bo,bo,bo,bo,bo,bo;" << endl;
00256 pg << "L bo,bo,bo,bo,bo,bo;" << endl;
00257 pg << "C bo;" << endl;
00258 pg << "V 0;" << endl;
00259 pg << "T;" << endl;
00260 pg << "MOVE L1, C0;" << endl;
00261 pg << "MOVE L2, C0;" << endl;
00262 pg << "MOVE L3, C0;" << endl;
00263 pg << "MOVE L4, C0;" << endl;
00264 pg << "MOVE L5, C0;" << endl;
00265 pg << "CALL 'ctxInst1(L1);" << endl;
00266 pg << "CALL 'ctxInst2(L2,L0);" << endl;
00267 pg << "CALL 'ctxInst3(L3,L0,L0);" << endl;
00268 pg << "CALL 'ctxInst4(L4,L0,L0,L0);" << endl;
00269 pg << "CALL 'ctxInst5(L5,L0,L0,L0,L0);" << endl;
00270 pg << "REF O0, L0;" << endl;
00271 pg << "REF O1, L1;" << endl;
00272 pg << "REF O2, L2;" << endl;
00273 pg << "REF O3, L3;" << endl;
00274 pg << "REF O4, L4;" << endl;
00275 pg << "REF O5, L5;" << endl;
00276
00277
00278
00279 Calculator calc(0);
00280
00281 try {
00282 calc.assemble(pg.str().c_str());
00283 } catch (FennelExcn& ex) {
00284 BOOST_MESSAGE("Assemble exception " << ex.getMessage());
00285 BOOST_MESSAGE(pg.str());
00286 BOOST_REQUIRE(0);
00287 }
00288
00289 TupleDataWithBuffer outTuple(calc.getOutputRegisterDescriptor());
00290 TupleDataWithBuffer inTuple(calc.getInputRegisterDescriptor());
00291
00292 calc.bind(&inTuple, &outTuple);
00293 calc.exec();
00294 printOutput(outTuple, calc);
00295
00296 int i;
00297 for (i = 1; i <= 5; i++) {
00298 BOOST_CHECK_EQUAL(
00299 *(reinterpret_cast<bool *>(
00300 const_cast<PBuffer>((outTuple[i]).pData))),
00301 true);
00302 }
00303
00304
00305 calc.exec();
00306
00307 for (i = 1; i <= 5; i++) {
00308 BOOST_CHECK_EQUAL(
00309 *(reinterpret_cast<bool *>(
00310 const_cast<PBuffer>((outTuple[i]).pData))),
00311 false);
00312 }
00313
00314
00315 calc.exec();
00316
00317 for (i = 1; i <= 5; i++) {
00318 BOOST_CHECK_EQUAL(
00319 *(reinterpret_cast<bool *>(
00320 const_cast<PBuffer>((outTuple[i]).pData))),
00321 false);
00322 }
00323
00324 #if 0
00325 tuplePrinter.print(cout, calc.getOutputRegisterDescriptor(), outTuple);
00326 cout << endl;
00327 #endif
00328
00329 }
00330
00331
00332 void
00333 CalcExtContextTest::testCalcExtContextPost()
00334 {
00335 BOOST_CHECK_EQUAL(EICtx::mCount, 0);
00336 }
00337
00338
00339 FENNEL_UNIT_TEST_SUITE(CalcExtContextTest);
00340
00341