Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <regex>
- #include <fstream>
- #include <math.h>
- // Error flag
- bool ERROR = false;
- class Memory
- {
- public:
- Memory();
- void set();
- void get();
- void print_program();
- void print_to_halt();
- // Registers
- int PC;
- std::string IR;
- int MAR;
- std::string MBR;
- int AC;
- int MQ;
- private:
- std::string m[1000];
- };
- Memory memory = Memory();
- bool execute(int code, int address)
- {
- // Codes:
- // 0 load register
- // 1 load memory to register
- // 2 load memory
- // 3 load |memory|
- // 4 load -memory
- // 5 load -|memory|
- // 6 stor
- // 7 add
- // 8 add ||
- // 9 sub
- // 10 sub ||
- // 11 mul
- // 12 div
- // 13 jump+
- // 14 jump
- switch(code)
- {
- case 0:
- memory.AC = memory.MQ;
- break;
- case 1:
- memory.MAR = address;
- memory.get();
- memory.MQ = std::stoi(memory.MBR);
- break;
- case 2:
- memory.MAR = address;
- memory.get();
- memory.AC = std::stoi(memory.MBR);
- break;
- case 3:
- memory.MAR = address;
- memory.get();
- memory.AC = abs(std::stoi(memory.MBR));
- break;
- case 4:
- memory.MAR = address;
- memory.get();
- memory.AC = -std::stoi(memory.MBR);
- break;
- case 5:
- memory.MAR = address;
- memory.get();
- memory.AC = -std::stoi(memory.MBR);
- break;
- case 6:
- memory.MAR = address;
- memory.MBR = std::to_string(memory.AC);
- memory.set();
- break;
- case 7:
- memory.MAR = address;
- memory.get();
- memory.AC = memory.AC + std::stoi(memory.MBR);
- break;
- case 8:
- memory.MAR = address;
- memory.get();
- memory.AC = memory.AC + abs(std::stoi(memory.MBR));
- break;
- case 9:
- memory.MAR = address;
- memory.get();
- memory.AC = memory.AC - std::stoi(memory.MBR);
- break;
- case 10:
- memory.MAR = address;
- memory.get();
- memory.AC = memory.AC - abs(std::stoi(memory.MBR));
- break;
- case 11:
- memory.MAR = address;
- memory.get();
- memory.AC = memory.MQ * std::stoi(memory.MBR);
- break;
- case 12:
- memory.MAR = address;
- memory.get();
- memory.MQ = memory.AC / std::stoi(memory.MBR);
- memory.AC = memory.AC % std::stoi(memory.MBR);
- break;
- case 13:
- if(memory.AC >= 0)
- {
- memory.PC = address - 1; // -1 to account for automatic increment
- }
- break;
- case 14:
- memory.PC = address - 1; // -1 to account for automatic increment
- break;
- default:
- return false; // invalid code, which should never happen
- break;
- }
- return true;
- }
- bool decode()
- {
- // begin, halt, nop, and comments do NOT call the execute method
- if(memory.IR == "halt")
- {
- return false;
- }
- else if(memory.IR == "nop" || memory.IR == "begin" || (char) memory.IR[0] == '.')
- {
- return true;
- }
- int code = -1;
- int address = -1;
- //std::string command;
- //std::regex pattern("((load)|(stor)|(add)|(sub)|(mul)|(div)|(jump\\+)|(jump))\\s+((MQ,)|(MQ))*\\s*(-)*\\s*(\\|)*\\s*(?:M\\(\\s*(\\s*[0-9]+\\s*)\\s*\\))*\\s*(\\|)*", std::regex_constants::icase);
- std::regex pattern("(((load)\\s+(((MQ,)\\s*M\\s*\\(\\s*([0-9]+)\\s*\\))|(MQ))?\\s*(-)?\\s*(\\|\\s*M\\s*\\(\\s*([0-9]+)\\s*\\)\\s*\\||M\\s*\\(\\s*([0-9]+)\\s*\\))?)|((stor)\\s+M\\s*\\(\\s*([0-9]+)\\s*\\))|((add)\\s+(\\|\\s*M\\s*\\(\\s*([0-9]+)\\s*\\)\\s*\\||M\\s*\\(\\s*([0-9]+)\\s*\\)))|((sub)\\s+(\\|\\s*M\\s*\\(\\s*([0-9]+)\\s*\\)\\s*\\||M\\s*\\(\\s*([0-9]+)\\s*\\)))|((mul)\\s+M\\s*\\(\\s*([0-9]+)\\s*\\))|((div)\\s+M\\s*\\(\\s*([0-9]+)\\s*\\))|((jump\\+)\\s+M\\s*\\(\\s*([0-9]+)\\s*\\))|((jump)\\s+M\\s*\\(\\s*([0-9]+)\\s*\\)))", std::regex_constants::icase);
- std::smatch sm;
- std::regex_match(memory.IR, sm, pattern);
- if(sm.size() > 0)
- {
- if(!std::string(sm[3]).empty())
- {
- // load
- // default
- code = 2;
- if(!std::string(sm[6]).empty())
- {
- // load sm[7] into MQ
- code = 1;
- address = std::stoi(sm[7]);
- }
- else if(!std::string(sm[8]).empty())
- {
- // load MQ into AC
- code = 0;
- address = -1;
- }
- else if(!std::string(sm[11]).empty())
- {
- // absolute value, 11 is the address
- code = 3;
- address = std::stoi(sm[11]);
- if(!std::string(sm[9]).empty())
- {
- // negative!
- code = 5;
- }
- }
- else if(!std::string(sm[9]).empty())
- {
- // negative!
- code = 4;
- if(address == -1)
- {
- // default address for loading memory into AC
- address = std::stoi(sm[12]);
- }
- }
- if(address == -1 && code == 2)
- {
- // default address for loading memory into AC
- address = std::stoi(sm[12]);
- }
- }
- else if(!std::string(sm[14]).empty())
- {
- // stor
- code = 6;
- address = std::stoi(sm[15]);
- }
- else if(!std::string(sm[17]).empty())
- {
- // add
- code = 7;
- address = std::stoi(sm[20]);
- if(!std::string(sm[19]).empty())
- {
- // add absolute value
- code = 8;
- address = std::stoi(sm[19]);
- }
- }
- else if(!std::string(sm[22]).empty())
- {
- // sub
- code = 9;
- address = std::stoi(sm[25]);
- if(!std::string(sm[24]).empty())
- {
- // sub absolute value
- code = 10;
- address = std::stoi(sm[24]);
- }
- }
- else if(!std::string(sm[27]).empty())
- {
- // mul
- code = 11;
- address = std::stoi(sm[28]);
- }
- else if(!std::string(sm[30]).empty())
- {
- // div
- code = 12;
- address = std::stoi(sm[31]);
- }
- else if(!std::string(sm[33]).empty())
- {
- // jump+
- code = 13;
- address = std::stoi(sm[34]);
- }
- else if(!std::string(sm[36]).empty())
- {
- // jump
- code = 14;
- address = std::stoi(sm[37]);
- }
- }
- else
- {
- ERROR = true;
- return false;
- }
- return execute(code, address);
- }
- Memory::Memory()
- {
- MBR = "nop";
- for (MAR = 0; MAR < 1000; MAR++)
- {
- this->set();
- }
- }
- void Memory::set()
- {
- m[MAR] = MBR;
- }
- void Memory::get()
- {
- MBR = m[MAR];
- }
- void Memory::print_program()
- {
- std::cout << "Program:" << std::endl;
- for(int i=0; i < 1000; i++)
- {
- if(m[i] == "nop")
- {
- continue;
- }
- std::cout << i << " " << m[i] << std::endl;
- }
- }
- void Memory::print_to_halt()
- {
- std::cout << "Memory:" << std::endl;
- for(int i=0; i < 1000; i++)
- {
- std::cout << i << " " << m[i] << std::endl;
- if(m[i] == "halt")
- {
- break;
- }
- }
- }
- int main()
- {
- // Initialize Registers
- memory.PC = 0;
- memory.MAR = 0;
- memory.AC = 0;
- memory.MQ = 0;
- // Set the line where "begin" should be to an invalid address
- int start_memory_address = -1;
- bool valid = false;
- int address;
- std::string content;
- std::string filename;
- std::cout << "Please enter a filename: ";
- std::cin >> filename;
- std::ifstream infile(filename);
- // Setup memory
- std::string line;
- std::regex line_pattern("([0-9]+)\\s+(.+)\\s*");
- std::smatch sm;
- if(infile)
- {
- while (std::getline(infile, line).good())
- {
- //std::cout << "Parsing" << std::endl;
- std::regex_match(line,sm,line_pattern);
- if(sm.size())
- {
- address = std::stoi(sm.str(1));
- content = sm.str(2);
- if(content == "begin")
- {
- start_memory_address = address;
- }
- if(content == "halt")
- {
- valid = true;
- }
- //std::cout << MAR << std::endl;
- memory.MAR = address;
- memory.MBR = content;
- memory.set();
- }
- }
- }
- else
- {
- std::cout << "Couldn't read file." << std::endl;
- }
- memory.print_program();
- std::cout << std::endl;
- if(!(start_memory_address == -1)) // don't run if halt was never set
- {
- memory.PC = start_memory_address;
- std::cout << "Program Execution:" << std::endl;
- while(valid)
- {
- // Fetch
- memory.MAR = memory.PC;
- memory.get();
- memory.IR = memory.MBR;
- std::cout << "PC = " << memory.PC << " IR = " << memory.IR << std::endl;
- // Decode
- valid = decode();
- if(ERROR)
- {
- std::cout << "An error occured at PC = " << memory.PC << std::endl;
- break;
- }
- memory.PC++;
- std::cout << "PC = " << memory.PC << " AC = " << memory.AC << " MQ = " << memory.MQ << std::endl << std::endl;
- }
- }
- std::cout << std::endl;
- memory.print_to_halt();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement