diff --git a/src/main.cpp b/src/main.cpp index b877657..176f933 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,40 +3,80 @@ #include #include -Register& getOrDefault(std::map& mapping, const RegIndex& lookup); +using RegMap = std::map; -int main() { - const constexpr size_t registerIndexPadding = 6; +Register& getOrDefault(std::map& mapping, const RegIndex& lookup); +std::pair mapFromRegister(Register listRegister); + +int main(int argc, char* argv[]) { + const constexpr size_t registerIndexPadding = 6, registerContentPadding = registerIndexPadding; + bool seperateInstructions = false; + + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "--seperate-instructions")) + seperateInstructions = true; + } + + const char instructionLabel = (seperateInstructions ? 'L' : 'R'); bool executing = true; std::cout << "Please enter the program" << std::endl; RegIndex pc = 0; - Register reg; - std::map registers{}; + Register programReg; + std::map registers{}, program{}; - std::cin >> reg; - auto registerStates = toList(reg); - - std::cout << "\nRegister states at startup:\n"; - RegIndex i = 0; - - for (; i < registerStates.size(); i++) { - const auto registerState = registerStates[i]; - - registers.insert(std::make_pair(i, registerState)); - std::cout << std::setw(registerIndexPadding) << i << ": " << registerState << " => "; - printInstruction(std::cout, registerState) << std::endl; + if (!(std::cin >> programReg)) { + std::cerr << "Failed to read program from input" << std::endl; + return -1; + } + + auto& programMap = seperateInstructions ? program : registers; + auto& registerMap = seperateInstructions ? registers : program; + uint32_t instructionCount, registerCount; + + std::tie(programMap, instructionCount) = mapFromRegister(programReg); + + if (seperateInstructions) { + std::cout << "Please enter the registers" << std::endl; + + if (!(std::cin >> programReg)) { + std::cerr << " Failed to read register states from input" << std::endl; + return -2; + } + + std::tie(registerMap, registerCount) = mapFromRegister(programReg); + } + + std::cout << "\nProgram state at startup:\n"; + + if (seperateInstructions) + std::cout << "Program:\n"; + + for (auto&& instruction : programMap) { + std::cout << instructionLabel << std::setw(registerIndexPadding) << instruction.first << ": " << std::setw(registerContentPadding) << instruction.second << " ==> "; + printInstruction(std::cout, instruction.second) << "\n"; + } + + std::cout << instructionLabel << std::setw(registerIndexPadding) << instructionCount << ": " << std::setw(registerContentPadding) << "0" << "... HALT\n\n"; + + if (seperateInstructions) { + std::cout << "Registers:\n"; + + for (auto&& instruction : registerMap) { + std::cout << "R" << std::setw(registerIndexPadding) << instruction.first << ": " << std::setw(registerContentPadding) << instruction.second << "\n"; + } + + std::cout << "R" << std::setw(registerIndexPadding) << registerCount << ": " << std::setw(registerContentPadding) << "0" << "...\n\n"; } - std::cout << std::setw(registerIndexPadding) << i << ": 0...\n\n"; std::cout << "Beginning Execution..." << std::endl; - registers.insert(std::make_pair(pc, reg)); + registers.insert(std::make_pair(pc, programReg)); while (executing) { - std::cout << "L" << pc << "\t"; - Register instruction = getOrDefault(registers, pc); + std::cout << instructionLabel << pc << "\t"; + Register instruction = getOrDefault(programMap, pc); printInstruction(std::cout, instruction) << std::endl; if (instruction == 0) { /* HALT instruction. */ @@ -47,19 +87,19 @@ int main() { auto splitInstruction = toPair(instruction); if (splitInstruction.first % 2 == 0) { /* R+ instruction */ - RegIndex sourceRegisterIndex = splitInstruction.first.get_ui(); + RegIndex sourceRegisterIndex = splitInstruction.first.get_ui() / 2; RegIndex destinationLabel = splitInstruction.second.get_ui(); - getOrDefault(registers, sourceRegisterIndex)++; + getOrDefault(registerMap, sourceRegisterIndex)++; pc = destinationLabel; } else { - RegIndex sourceRegisterIndex = splitInstruction.first.get_ui(); + RegIndex sourceRegisterIndex = splitInstruction.first.get_ui() / 2; auto branches = toPair(splitInstruction.second); RegIndex trueLabel = branches.first.get_ui(); RegIndex falseLabel = branches.second.get_ui(); - auto& sourceRegister = getOrDefault(registers, sourceRegisterIndex); + auto& sourceRegister = getOrDefault(registerMap, sourceRegisterIndex); if (sourceRegister > 0) { sourceRegister--; @@ -74,3 +114,18 @@ Register& getOrDefault(std::map& mapping, const RegIndex& lo auto valueIter = mapping.try_emplace(lookup, Register{ 0 }); return valueIter.first->second; } + +std::pair mapFromRegister(Register listRegister) { + RegMap map; + auto registerStates = toList(listRegister); + + RegIndex i = 0; + + for (; i < registerStates.size(); i++) { + const auto registerState = registerStates[i]; + + map.insert(std::make_pair(i, registerState)); + } + + return std::make_pair(map, i); +} diff --git a/src/register.cpp b/src/register.cpp index bdc8c7f..59e9200 100644 --- a/src/register.cpp +++ b/src/register.cpp @@ -11,6 +11,7 @@ std::pair toPair(Register unsplit) { x++; } + /* Skip the first 1 bit. */ unsplit >>= 1; return std::make_pair(x, unsplit); @@ -26,6 +27,7 @@ std::pair toPair(Register unsplit) { x++; } + /* Skip the first 0 bit. */ unsplit >>= 1; return std::make_pair(x, unsplit);