Main Page   Class Hierarchy   Compound List   File List   Compound Members  

interpreter.h

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                         // Registers
00054                         Int PC;
00055                         Int FP;
00056                         /******************************Implementation*of*C-machine*operations*****************************/
00057                         private:
00058                                 #include "operations.h" 
00059                         /******************************************Public*methods*****************************************/
00060                         public:
00061                         
00062                         Interpreter() : freeStore(heap){}
00063 
00064                         void execute(Control<Word>* pControl)
00065                         {
00066                                 try
00067                                 {
00068                                         // Internal variables
00069                                         Op::Code opCode;
00070                                         Int codeArg[CMA_MAX_OP_CODE_ARG_COUNT];
00071 
00072                                         Int newPC;
00073                                         Int newSP;
00074 
00075                                         // Initializing registers
00076                                         PC = (Int)0;
00077                                         FP = (Int)0;
00078 
00079                                         // Initializing subconstructions
00080                                         heap.init();
00081                                         freeStore.init();
00082                                         code.init();
00083 
00084                                         // Start of execution
00085                                         int tillBreak = pControl->onBreak();
00086                                 
00087                                         while (tillBreak != 0 )
00088                                         {
00089                                                 //Both SP is correct, PC may be invalid
00090                                                 readOperation(opCode, codeArg, newPC, newSP);
00091                                                 //Now newSP is correct, newPC may be incorrect.
00092                                                 //NewSP is calculated for every operation!!
00093                                                 
00094                                                 switch (opCode)
00095                                                 {
00096                                                         //Aritmetical operations
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                                                         //Logical operations
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                                                         //Comparison operators
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                                                         //Bitwise operators
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                                                         //Various jumps
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                                                         //Store and load
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                                                         //Duplication
00140                                                         case Op::DUP:     dup(newSP);  break;
00141                                                         case Op::MOVE:    move(newSP, codeArg[0]); break;
00142                                                         //Memory management
00143                                                         case Op::NEW:     alloc_memory(newSP); break;
00144                                                         case Op::FREE:    free_memory(newSP);  break;
00145                                                         //Organisatory commands
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; //Nothing to do further
00154                                                             break;
00155                                                         //I/O commands
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                                                         //This is THE END
00160                                                         default: throw Failure("Error in completing instruction -- one operation isnt implemented(Sorry)!");
00161                                                 }
00162                                         //Prepararing to fetch new instruction
00163                                         PC = newPC;
00164                                         tillBreak--;
00165                                         if (tillBreak == 0) tillBreak = pControl->onBreak();
00166                                         //End of while
00167                                 }
00168                         }
00169                         catch(Exception& error)
00170                         {
00171                                 pControl->onException(&error);
00172                         }
00173                         //Closing up
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                     //THIS LOOKS UGLY AND IS UGLY!
00212                     //Check that PC is correct
00213                         if(!code.verifyAddress(PC)) throw Error(Error::WRONG_CODE_ADDRESS);                                     
00214 
00215                         // Load operation code
00216                         opCode = code[PC].convertToCode();
00217                         
00218                         // Load information about the operation code
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                         // Compute new PC
00226                         newPC = PC + (Int)codeArgN + (Int)1;
00227 
00228                         // Load code arguments
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                         // Compute new SP
00240                         if (SPDelta != 0)
00241                         {
00242                                 newSP = heap.getSP() + (Int)SPDelta;
00243                                 //Big hack for ENTER
00244                 //If program is translated then first ENTER  then SP is invalid
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                         // Compute newSP for operations: MOVE,ALLOC,RETURN,
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                         //Shoud be correct now?
00268 
00269                 }
00270 
00271         };
00272 }
00273 
00274 #endif
00275 

Generated on Tue Oct 12 03:30:44 1999 by doxygen1.2.18