Guest User

Untitled

a guest
May 27th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.87 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <deque>
  4. #include <map>
  5. #include <string>
  6. #include <utility>
  7. #include <sstream>
  8. #include <stdlib.h>
  9. using namespace std;
  10.  
  11. enum OpCode{
  12.     AM_READ=0,
  13.     AM_WRITE,
  14.     AM_LOAD,
  15.     AM_STORE,
  16.     AM_LIT,
  17.     AM_ADD,
  18.     AM_MUL,
  19.     AM_SUB,
  20.     AM_DIV,
  21.     AM_MOD,
  22.     AM_LT,
  23.     AM_EQ,
  24.     AM_NE,
  25.     AM_GT,
  26.     AM_LE,
  27.     AM_GE,
  28.     AM_JMP,
  29.     AM_JMC
  30. };
  31. struct Befehl {
  32.     OpCode op;
  33.     int right;
  34. };
  35. class Programm;
  36. class CException{
  37. public:
  38.     CException() {}
  39.     ~CException() {}
  40.  
  41.     static void AbnormalProgramTermination(string cerr)
  42.     {
  43.         cout << "Fatal Error: " << cerr << endl;
  44.         cout << "Please enter any number to exit the program: ";
  45.         int foo;
  46.         cin >> foo;
  47.         exit(-1);
  48.     }
  49. };
  50. template<class T> class VirtualMachine{
  51. public:
  52.     VirtualMachine(Programm * vater) : m_befehlszaehler(1) {
  53.         m_vater = vater;
  54.     }
  55.     unsigned int Tick(Befehl * cmd)
  56.     {
  57.         switch(cmd->op)
  58.         {
  59.         case AM_READ:
  60.             if(!m_eingabeband.size())
  61.                 CException::AbnormalProgramTermination("READ trotz leerem Eingabeband");
  62.             m_hauptspeicher[cmd->right] = m_eingabeband[0];
  63.             m_eingabeband.pop_front();
  64.             ++m_befehlszaehler;
  65.             break;
  66.         case AM_WRITE:
  67.             if(m_hauptspeicher.find(cmd->right) == m_hauptspeicher.end())
  68.                 CException::AbnormalProgramTermination("WRITE zeigt auf ungueltigen Wert");
  69.             m_ausgabeband.push_back(m_hauptspeicher[cmd->right]);
  70.             ++m_befehlszaehler;
  71.             break;
  72.         case AM_LOAD:
  73.             if(m_hauptspeicher.find(cmd->right) == m_hauptspeicher.end())
  74.                 CException::AbnormalProgramTermination("LOAD zeigt auf ungueltigen Wert");
  75.             m_datenkeller.push_front(m_hauptspeicher[cmd->right]);
  76.             ++m_befehlszaehler;
  77.             break;
  78.         case AM_STORE:
  79.             if(!m_datenkeller.size())
  80.                 CException::AbnormalProgramTermination("STORE trotz leerem Datenkeller");
  81.             m_hauptspeicher[cmd->right] = m_datenkeller[0];
  82.             m_datenkeller.pop_front();
  83.             ++m_befehlszaehler;
  84.             break;
  85.         case AM_LIT:
  86.             m_datenkeller.push_front(cmd->right);
  87.             ++m_befehlszaehler;
  88.             break;
  89.         case AM_ADD: case AM_MUL: case AM_SUB: case AM_DIV: case AM_MOD: case AM_LT: case AM_EQ: case AM_NE: case AM_GT: case AM_LE: case AM_GE:
  90.             if(m_datenkeller.size() <= 1)
  91.                 CException::AbnormalProgramTermination("OP trotz kleinem Datenkeller");
  92.             if(cmd->op == AM_ADD)   m_datenkeller[1] = m_datenkeller[1] + m_datenkeller[0];
  93.             if(cmd->op == AM_MUL)   m_datenkeller[1] = m_datenkeller[1] * m_datenkeller[0];
  94.             if(cmd->op == AM_SUB)   m_datenkeller[1] = m_datenkeller[1] - m_datenkeller[0];
  95.             if(cmd->op == AM_DIV)   m_datenkeller[1] = m_datenkeller[1] / m_datenkeller[0];
  96.             if(cmd->op == AM_MOD)   m_datenkeller[1] = m_datenkeller[1] % m_datenkeller[0];
  97.             if(cmd->op == AM_LT)    m_datenkeller[1] = m_datenkeller[1] < m_datenkeller[0];
  98.             if(cmd->op == AM_EQ)    m_datenkeller[1] = m_datenkeller[1] == m_datenkeller[0];
  99.             if(cmd->op == AM_NE)    m_datenkeller[1] = m_datenkeller[1] != m_datenkeller[0];
  100.             if(cmd->op == AM_GT)    m_datenkeller[1] = m_datenkeller[1] > m_datenkeller[0];
  101.             if(cmd->op == AM_LE)    m_datenkeller[1] = m_datenkeller[1] <= m_datenkeller[0];
  102.             if(cmd->op == AM_GE)    m_datenkeller[1] = m_datenkeller[1] >= m_datenkeller[0];
  103.             m_datenkeller.pop_front();
  104.             ++m_befehlszaehler;
  105.             break;
  106.         case AM_JMP:
  107.             m_befehlszaehler = cmd->right;
  108.             break;
  109.         case AM_JMC:
  110.             if(!m_datenkeller.size())
  111.                 CException::AbnormalProgramTermination("JMC trotz leerem Datenkeller");
  112.             int flag = m_datenkeller[0]; m_datenkeller.pop_front();
  113.             if(flag != 0 && flag != 1)
  114.                 CException::AbnormalProgramTermination("JUMP FLAG OUT OF BOUNDS");
  115.             if(flag == 0)
  116.                 m_befehlszaehler = cmd->right;
  117.             else
  118.                 ++m_befehlszaehler;
  119.             break;
  120.         }
  121.         return m_befehlszaehler;
  122.     }
  123.     deque<T> & Ausgabeband() {return m_ausgabeband;}
  124.     deque<T> & Eingabeband() {return m_eingabeband;}
  125.     deque<T> & Datenkeller() {return m_datenkeller;}
  126.     map<unsigned int, T> & HauptSpeicher() {return m_hauptspeicher;}
  127.     unsigned int Pos() {return m_befehlszaehler;}
  128.    
  129.     string HauptSpeicherString()
  130.     {
  131.         stringstream ss;
  132.         ss << "[";
  133.         map<unsigned int, T>::iterator it, it2;
  134.         for ( it=m_hauptspeicher.begin() ; it != m_hauptspeicher.end(); it++ )
  135.         {
  136.             ss << (*it).first << "/" << (*it).second;
  137.             it2 = it;
  138.             if(++it2!=m_hauptspeicher.end())
  139.                 ss << ",";
  140.         }
  141.         ss << "]";
  142.         return ss.str();
  143.     }
  144.     string DequePrint(deque<T> & deq, char separator=':')
  145.     {
  146.         stringstream ss;
  147.         if(!deq.size()) return "e";
  148.         for(unsigned int i = 0; i < deq.size(); ++i)
  149.         {
  150.             ss << deq[i];
  151.             if(i != deq.size()-1)
  152.                 ss << separator;
  153.         }
  154.         return ss.str();
  155.     }
  156. private:
  157.     unsigned int m_befehlszaehler;
  158.     deque<T> m_datenkeller;
  159.     map<unsigned int, T> m_hauptspeicher;
  160.     deque<T> m_eingabeband;
  161.     deque<T> m_ausgabeband;
  162.     Programm * m_vater;
  163. };
  164. class Programm{
  165. public:
  166.     Programm() {m_machine = new VirtualMachine<int>(this);}
  167.     ~Programm() {delete m_machine;}
  168.  
  169.     void CmdReg(OpCode op, int rop)
  170.     {
  171.         Befehl nb;
  172.         nb.op = op;
  173.         nb.right = rop;
  174.         m_programm.push_back(nb);
  175.     }
  176.     void LegeAufEingabeband(int k)
  177.     {
  178.         m_machine->Eingabeband().push_front(k);
  179.     }
  180.     void LadeProgramm()
  181.     {
  182.         LegeAufEingabeband(123);
  183.         pair<OpCode,int> programm[] = {
  184.             pair<OpCode,int>(AM_READ,1),
  185.             pair<OpCode,int>(AM_LIT,0),
  186.             pair<OpCode,int>(AM_STORE,2),
  187.             pair<OpCode,int>(AM_LOAD,1),
  188.             pair<OpCode,int>(AM_LIT,0),
  189.             pair<OpCode,int>(AM_NE,0xCC),
  190.             pair<OpCode,int>(AM_JMC,25),
  191.             pair<OpCode,int>(AM_LOAD,1),
  192.             pair<OpCode,int>(AM_LIT,10),
  193.             pair<OpCode,int>(AM_MOD,0xCC),
  194.             pair<OpCode,int>(AM_STORE,3),
  195.             pair<OpCode,int>(AM_LOAD,3),
  196.             pair<OpCode,int>(AM_LIT,2),
  197.             pair<OpCode,int>(AM_MOD,0xCC),
  198.             pair<OpCode,int>(AM_JMC,20),
  199.             pair<OpCode,int>(AM_LOAD,3),
  200.             pair<OpCode,int>(AM_LOAD,2),
  201.             pair<OpCode,int>(AM_ADD,0xCC),
  202.             pair<OpCode,int>(AM_STORE,2),
  203.             pair<OpCode,int>(AM_LOAD,1),
  204.             pair<OpCode,int>(AM_LIT,10),
  205.             pair<OpCode,int>(AM_DIV,0xCC),
  206.             pair<OpCode,int>(AM_STORE,1),
  207.             pair<OpCode,int>(AM_JMP,4),
  208.             pair<OpCode,int>(AM_WRITE,2),
  209.         };
  210.         for(int i = 0; i < sizeof(programm)/sizeof(programm[0]); ++i)
  211.             CmdReg(programm[i].first,programm[i].second);
  212.     }
  213.  
  214.     void Debug()
  215.     {
  216.         cout << "( " << m_machine->Pos() << " , " << m_machine->DequePrint(m_machine->Datenkeller()) << " , "
  217.             << m_machine->HauptSpeicherString() << " , " << m_machine->DequePrint(m_machine->Eingabeband()) << " , "
  218.             << m_machine->DequePrint(m_machine->Ausgabeband()) << " )" << endl;
  219.     }
  220.     void FuehreProgrammAus()
  221.     {
  222.         int iPos = 1;
  223.         for(int i = 0; i < 200 && iPos < 1+m_programm.size(); ++i) //WHILE NOT EOF
  224.         {
  225.             Debug();
  226.             iPos = m_machine->Tick(&P(iPos));
  227.         }
  228.         Debug();
  229.     }
  230.  
  231.     Befehl P(unsigned int i) {
  232.         --i;
  233.         if(i < m_programm.size())return m_programm[i]; 
  234.         else{
  235.             cout << "Fataler Fehler: EOP " << i << endl;
  236.             return m_programm[0];
  237.     }
  238.     }
  239. private:
  240.     VirtualMachine<int> * m_machine;
  241.     vector<Befehl> m_programm;
  242. };
  243.  
  244. int main()
  245. {
  246.     Programm foo;
  247.     foo.LadeProgramm();
  248.     foo.FuehreProgrammAus();
  249.     system("pause");
  250. }
Add Comment
Please, Sign In to add comment