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
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
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