Fixed execution. Added ability to split instrctions and registers.
This commit is contained in:
105
src/main.cpp
105
src/main.cpp
@@ -3,40 +3,80 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
Register& getOrDefault(std::map<RegIndex, Register>& mapping, const RegIndex& lookup);
|
||||
using RegMap = std::map<RegIndex, Register>;
|
||||
|
||||
int main() {
|
||||
const constexpr size_t registerIndexPadding = 6;
|
||||
Register& getOrDefault(std::map<RegIndex, Register>& mapping, const RegIndex& lookup);
|
||||
std::pair<RegMap, uint32_t> 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<RegIndex, Register> registers{};
|
||||
Register programReg;
|
||||
std::map<RegIndex, Register> 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<false>(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<true>(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<RegIndex, Register>& mapping, const RegIndex& lo
|
||||
auto valueIter = mapping.try_emplace(lookup, Register{ 0 });
|
||||
return valueIter.first->second;
|
||||
}
|
||||
|
||||
std::pair<RegMap, uint32_t> 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);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ std::pair<Register, Register> toPair<false>(Register unsplit) {
|
||||
x++;
|
||||
}
|
||||
|
||||
/* Skip the first 1 bit. */
|
||||
unsplit >>= 1;
|
||||
|
||||
return std::make_pair(x, unsplit);
|
||||
@@ -26,6 +27,7 @@ std::pair<Register, Register> toPair<true>(Register unsplit) {
|
||||
x++;
|
||||
}
|
||||
|
||||
/* Skip the first 0 bit. */
|
||||
unsplit >>= 1;
|
||||
|
||||
return std::make_pair(x, unsplit);
|
||||
|
||||
Reference in New Issue
Block a user