00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef Fennel_Calculator_Included
00023 #define Fennel_Calculator_Included
00024
00025 #include "fennel/tuple/TupleDescriptor.h"
00026 #include "fennel/tuple/TupleData.h"
00027 #include "fennel/tuple/TupleAccessor.h"
00028 #include "fennel/tuple/TuplePrinter.h"
00029
00030 #include <stdio.h>
00031 #include <assert.h>
00032
00033 #include <algorithm>
00034 #include <vector>
00035 #include <string>
00036 #include <deque>
00037
00038 FENNEL_BEGIN_NAMESPACE
00039
00040 class Instruction;
00041 class TupleData;
00042
00043 FENNEL_END_NAMESPACE
00044
00045 #include "fennel/calculator/CalcTypedefs.h"
00046 #include "fennel/calculator/CalcMessage.h"
00047 #include "fennel/calculator/RegisterReference.h"
00048 #include "fennel/exec/DynamicParam.h"
00049 #include "fennel/common/TraceSource.h"
00050
00051 FENNEL_BEGIN_NAMESPACE
00052
00053 using namespace std;
00054
00055
00056 class FENNEL_CALCULATOR_EXPORT Calculator
00057 : virtual public TraceSource
00058 {
00059 public:
00064 explicit
00065 Calculator(DynamicParamManager* dynamicParamManager);
00066
00077 explicit
00078 Calculator(
00079 DynamicParamManager* dynamicParamManager,
00080 int codeSize, int literalSize, int inputSize,
00081 int outputSize, int localSize, int statusSize);
00082
00083 ~Calculator();
00084
00086 inline DynamicParamManager* getDynamicParamManager() const {
00087 return mPDynamicParamManager;
00088 }
00089
00090
00091
00092
00093
00117 void outputRegisterByReference(bool flag);
00118
00120 void appendInstruction(Instruction* newInst)
00121 {
00122 assert(mIsUsingAssembler ? mIsAssembling : true);
00123 mCode.push_back(newInst);
00124 }
00125
00129 void appendRegRef(RegisterReference* newRef)
00130 {
00131 assert(mIsUsingAssembler ? mIsAssembling : true);
00132 assert(newRef->setIndex() < RegisterReference::ELastSet);
00133
00134
00135 assert(!mRegisterSetBinding[RegisterReference::ELiteral]);
00136 assert(!mRegisterSetBinding[RegisterReference::EInput]);
00137 assert(!mRegisterSetBinding[RegisterReference::EOutput]);
00138 assert(!mRegisterSetBinding[RegisterReference::ELocal]);
00139 assert(!mRegisterSetBinding[RegisterReference::EStatus]);
00140
00141 mRegisterRef[newRef->setIndex()].push_back(newRef);
00142 newRef->setCalc(this);
00143 }
00144
00149 void assemble(const char *program);
00150
00157 void bind(
00158 RegisterReference::ERegisterSet regset,
00159 TupleData* data,
00160 const TupleDescriptor& desc);
00161
00168 TupleDescriptor getOutputRegisterDescriptor() const;
00169
00176 TupleDescriptor getInputRegisterDescriptor() const;
00177
00184 TupleDescriptor getStatusRegisterDescriptor() const;
00185
00186
00191 TupleData const * const getStatusRegister() const;
00192
00199 void zeroStatusRegister();
00200
00201
00211
00217 void bind(
00218 TupleData* input,
00219 TupleData* output,
00220 bool takeOwnership = false,
00221 const TupleData* outputWrite = 0);
00222
00225 void continueOnException(bool c);
00226
00227
00228
00229
00230
00232 void exec();
00233
00234
00235
00236
00237
00243 string warnings();
00244
00248 deque<CalcMessage> mWarnings;
00249
00250 protected:
00251
00252
00253 template <typename TMPLT> friend class RegisterRef;
00254 friend class RegisterReference;
00255 friend class CalcAssembler;
00256
00258 vector<Instruction *> mCode;
00259
00263 RegisterSetBinding* mRegisterSetBinding[RegisterReference::ELastSet];
00264
00268 vector<RegisterReference *> mRegisterRef[RegisterReference::ELastSet];
00269
00273 vector<RegisterReference *> mRegisterReset;
00274
00281 TupleDescriptor* mRegisterSetDescriptor[RegisterReference::ELastSet];
00282
00284 const bool mIsUsingAssembler;
00286 bool mIsAssembling;
00288 bool mOutputRegisterByReference;
00291 bool mContinueOnException;
00292
00295 vector<FixedBuffer*> mBuffers;
00296
00298 DynamicParamManager* mPDynamicParamManager;
00299
00300 private:
00302 void init(
00303 int codeSize,
00304 int literalSize,
00305 int inputSize,
00306 int outputSize,
00307 int localSize,
00308 int statusSize);
00309
00311 void unbind(
00312 RegisterReference::ERegisterSet regset,
00313 bool unbindDescriptor = true);
00314 };
00315
00316 FENNEL_END_NAMESPACE
00317
00318 #endif
00319
00320
00321