00001 #ifndef CMA_INTERPRETER_DEFINED
00002 #define CMA_INTERPRETER_DEFINED
00003
00004 #include <stdlib.h>
00005 #include <vector>
00006
00007 #include "control.h"
00008
00009 namespace CMa
00010 {
00045 template<class Word, class Int, class Heap, class FreeStore, class Code> class Interpreter
00046 {
00047 public:
00048 Heap heap;
00049 Code code;
00050
00051 FreeStore freeStore;
00052
00053
00054 Int PC;
00055 Int FP;
00056
00057 private:
00058 #include "operations.h"
00059
00060 public:
00061
00062 Interpreter() : freeStore(heap){}
00063
00064 void execute(Control<Word>* pControl)
00065 {
00066 try
00067 {
00068
00069 Op::Code opCode;
00070 Int codeArg[CMA_MAX_OP_CODE_ARG_COUNT];
00071
00072 Int newPC;
00073 Int newSP;
00074
00075
00076 PC = (Int)0;
00077 FP = (Int)0;
00078
00079
00080 heap.init();
00081 freeStore.init();
00082 code.init();
00083
00084
00085 int tillBreak = pControl->onBreak();
00086
00087 while (tillBreak != 0 )
00088 {
00089
00090 readOperation(opCode, codeArg, newPC, newSP);
00091
00092
00093
00094 switch (opCode)
00095 {
00096
00097 case Op::MINUS: unary_minus(newSP); break;
00098 case Op::INC: inc(newSP); break;
00099 case Op::DEC: inc(newSP); break;
00100 case Op::MUL: mul(newSP); break;
00101 case Op::ADD: add(newSP); break;
00102 case Op::SUB: sub(newSP); break;
00103 case Op::DIV: div(newSP); break;
00104 case Op::MOD: mod(newSP); break;
00105
00106 case Op::NOT: log_neg(newSP); break;
00107 case Op::AND: log_and(newSP); break;
00108 case Op::OR: log_or(newSP); break;
00109
00110 case Op::EQ: eq(newSP); break;
00111 case Op::NEQ: neq(newSP); break;
00112 case Op::LE: le(newSP); break;
00113 case Op::LEQ: leq(newSP); break;
00114 case Op::GE: ge(newSP); break;
00115 case Op::GEQ: geq(newSP); break;
00116
00117 case Op::BIT_NOT: bin_complement(newSP); break;
00118 case Op::BIT_AND: bin_and(newSP); break;
00119 case Op::BIT_OR: bin_or(newSP); break;
00120 case Op::BIT_XOR: bin_xor(newSP); break;
00121 case Op::BIT_SHL: shift_left(newSP); break;
00122 case Op::BIT_SHR: shift_right(newSP); break;
00123
00124 case Op::JUMP: jump(newSP, codeArg[0]); break;
00125 case Op::JUMPZ: jumpz(newSP,codeArg[0]); break;
00126 case Op::JUMPI: jumpi(newSP, codeArg[0]); break;
00127 case Op::JUMPZS: jumpzs(newSP, codeArg[0]); break;
00128 case Op::JUMPNZ: jumpnzs(newSP,codeArg[0]); break;
00129
00130 case Op::LOADC: push(newSP,(Word)codeArg[0]); break;
00131 case Op::POP: pop(newSP); break;
00132 case Op::LOAD: load(newSP); break;
00133 case Op::LOADA: loada(newSP, codeArg[0]); break;
00134 case Op::STORE: store(newSP); break;
00135 case Op::STOREA: storea(newSP, codeArg[0]); break;
00136 case Op::LOADRC: loadrc(newSP, codeArg[0]); break;
00137 case Op::LOADR: loadr(newSP, codeArg[0]); break;
00138 case Op::STORER: storer(newSP,codeArg[0]); break;
00139
00140 case Op::DUP: dup(newSP); break;
00141 case Op::MOVE: move(newSP, codeArg[0]); break;
00142
00143 case Op::NEW: alloc_memory(newSP); break;
00144 case Op::FREE: free_memory(newSP); break;
00145
00146 case Op::MARK: mark(newSP); break;
00147 case Op::CALL: call(newSP, codeArg[0]); break;
00148 case Op::ENTER: enter(newSP, codeArg[0]); break;
00149 case Op::ALLOC: alloc_stack(newSP); break;
00150 case Op::RETURN: return_value(newSP); break;
00151 case Op::HALT:
00152 halt_machine(newSP,pControl);
00153 return;
00154 break;
00155
00156 case Op::WRITEI: write_int(newSP,pControl); break;
00157 case Op::READI: read_int(newSP,pControl); break;
00158 case Op::WRITEC: write_char(newSP,pControl,(Word)codeArg[0]); break;
00159
00160 default: throw Failure("Error in completing instruction -- one operation isnt implemented(Sorry)!");
00161 }
00162
00163 PC = newPC;
00164 tillBreak--;
00165 if (tillBreak == 0) tillBreak = pControl->onBreak();
00166
00167 }
00168 }
00169 catch(Exception& error)
00170 {
00171 pControl->onException(&error);
00172 }
00173
00174 freeStore.deInit();
00175 heap.deInit();
00176 code.deInit();
00177 return;
00178 }
00179
00180 protected:
00209 inline void readOperation(Op::Code& opCode,Int codeArg[],Int& newPC,Int& newSP) throw (Error)
00210 {
00211
00212
00213 if(!code.verifyAddress(PC)) throw Error(Error::WRONG_CODE_ADDRESS);
00214
00215
00216 opCode = code[PC].convertToCode();
00217
00218
00219 int codeArgN;
00220 int stackArgN;
00221 int SPDelta;
00222 if (!op.getDescription(opCode, codeArgN, stackArgN, SPDelta))
00223 throw Error(Error::WRONG_OP_CODE);
00224
00225
00226 newPC = PC + (Int)codeArgN + (Int)1;
00227
00228
00229 assert(codeArgN <= CMA_MAX_OP_CODE_ARG_COUNT);
00230 if (codeArgN != 0)
00231 {
00232 if (!code.verifyInterval(PC, PC + (Int)codeArgN))
00233 throw Error(Error::WRONG_OP_ARGUMENT_ADDRESS);
00234
00235 for(int i = 1; i <= codeArgN; i++)
00236 codeArg[i-1] = (Int)code[PC + (Int)i];
00237 }
00238
00239
00240 if (SPDelta != 0)
00241 {
00242 newSP = heap.getSP() + (Int)SPDelta;
00243
00244
00245 if (PC!=(Int)0 || Op::ENTER!=opCode)
00246 {
00247 if (SPDelta < 0 && !heap.verifySP(newSP)) throw Error(Error::STACK_UNDERFLOW);
00248 if (SPDelta > 0 && !heap.verifySP(newSP)) throw Error(Error::STACK_OVERFLOW);
00249 }
00250 }
00251
00252 if(opCode==Op::MOVE)
00253 {
00254 newSP = heap.getSP() + (Int)codeArg[0]-(Int)1;
00255 if(!heap.verifySP(newSP)) throw Error(Error::STACK_OVERFLOW);
00256 }
00257 if(opCode==Op::ALLOC)
00258 {
00259 newSP = heap.getSP() + (Int)codeArg[0];
00260 if(!heap.verifySP(newSP)) throw Error(Error::STACK_OVERFLOW);
00261 }
00262 if(opCode==Op::RETURN)
00263 {
00264 newSP = FP-(Int)3;
00265 if(!heap.verifySP(newSP)) throw Error(Error::STACK_UNDERFLOW);
00266 }
00267
00268
00269 }
00270
00271 };
00272 }
00273
00274 #endif
00275