mycpu/cinstruction.h

00001 
00008 #ifndef CINSTRUCTION_H
00009 #define CINSTRUCTION_H 1
00010 
00011 #include <iostream>
00012 #include <list>
00013 #include <sstream>
00014 #include <boost/lexical_cast.hpp>
00015 #include <assert.h>
00016 #include <stdexcept>
00017 
00023 class CInstructionError
00024  : public std::invalid_argument
00025 {
00026   public:
00037     CInstructionError(const std::string& what)
00038       : std::invalid_argument(what)
00039     {}
00040 };
00041 
00042 #include "ccpu.h"
00043 
00044 /* forward declare CCPU */
00045 template <class T>
00046 class CCPU;
00047 
00053 template <class T>
00054 class CInstruction
00055 {
00056   public:
00067     CInstruction(std::string name)
00068       : m_name(name)
00069     {}
00070 
00081     virtual ~CInstruction()
00082     {}
00083 
00094     virtual bool operator==(std::string& name)
00095     {
00096       return name == m_name;
00097     }
00098 
00109     virtual CInstruction& operator()(CCPU<T> *cpu)
00110     {
00111       execute(cpu);
00112       return *this;
00113     }
00114 
00125     virtual const std::string& getName()
00126     {
00127       return m_name;
00128     }
00129 
00140     virtual std::ostream& dump(std::ostream& stream)
00141     {
00142       stream << m_name;
00143       return stream;
00144     }
00145 
00157     friend std::ostream& operator<<(std::ostream& stream, CInstruction& instr)
00158     {
00159       return instr.dump(stream);
00160     }
00161 
00172     virtual const unsigned parseRegister(const std::string& str);
00173 
00186     virtual void checkRegister(CCPU<T> *cpu, const unsigned regidx);
00187 
00198     virtual CInstruction *factory() = 0;
00199 
00211     virtual void compile(std::list<std::string>& params) = 0;
00212 
00223     virtual void execute(CCPU<T> *cpu) = 0;
00224 
00225   protected:
00226     /* members */
00228     std::string m_name;
00229 };
00230 
00231 /*----------------------------------------------------------------------------*/
00232 
00233 template<class T>
00234 const unsigned CInstruction<T>::parseRegister(const std::string& str)
00235 {
00236   unsigned reg;
00237   if (str.length() < 2 || str[0] != 'r')
00238     throw CInstructionError("Invalid syntax of register");
00239 
00240   try
00241   {
00242     reg = boost::lexical_cast<unsigned>(str.substr(1));
00243   }
00244   catch(boost::bad_lexical_cast& ex)
00245   {
00246     throw CInstructionError("Invalid syntax of register");
00247   }
00248 
00249   return reg;
00250 }
00251 
00252 /*----------------------------------------------------------------------------*/
00253 
00254 template<class T>
00255 inline void CInstruction<T>::checkRegister(CCPU<T> *cpu, const unsigned regidx)
00256 {
00257   assert(cpu != NULL);
00258   if (regidx >= cpu->getRegisterCount())
00259   {
00260     std::stringstream sstr;
00261     sstr << "Register R" << regidx << " doesn't exist (out of bound)";
00262     throw CInstructionError(sstr.str());
00263   }
00264 }
00265 
00266 #endif
00267 
00268 /* vim: set et sw=2 ts=2: */

Generated on Sat May 30 16:32:35 2009 for mycpu by  doxygen 1.5.3