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 <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
Register& getOrDefault(std::map<RegIndex, Register>& mapping, const RegIndex& lookup);
|
using RegMap = std::map<RegIndex, Register>;
|
||||||
|
|
||||||
int main() {
|
Register& getOrDefault(std::map<RegIndex, Register>& mapping, const RegIndex& lookup);
|
||||||
const constexpr size_t registerIndexPadding = 6;
|
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;
|
bool executing = true;
|
||||||
|
|
||||||
std::cout << "Please enter the program" << std::endl;
|
std::cout << "Please enter the program" << std::endl;
|
||||||
|
|
||||||
RegIndex pc = 0;
|
RegIndex pc = 0;
|
||||||
Register reg;
|
Register programReg;
|
||||||
std::map<RegIndex, Register> registers{};
|
std::map<RegIndex, Register> registers{}, program{};
|
||||||
|
|
||||||
std::cin >> reg;
|
if (!(std::cin >> programReg)) {
|
||||||
auto registerStates = toList(reg);
|
std::cerr << "Failed to read program from input" << std::endl;
|
||||||
|
return -1;
|
||||||
std::cout << "\nRegister states at startup:\n";
|
}
|
||||||
RegIndex i = 0;
|
|
||||||
|
auto& programMap = seperateInstructions ? program : registers;
|
||||||
for (; i < registerStates.size(); i++) {
|
auto& registerMap = seperateInstructions ? registers : program;
|
||||||
const auto registerState = registerStates[i];
|
uint32_t instructionCount, registerCount;
|
||||||
|
|
||||||
registers.insert(std::make_pair(i, registerState));
|
std::tie(programMap, instructionCount) = mapFromRegister(programReg);
|
||||||
std::cout << std::setw(registerIndexPadding) << i << ": " << registerState << " => ";
|
|
||||||
printInstruction(std::cout, registerState) << std::endl;
|
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;
|
std::cout << "Beginning Execution..." << std::endl;
|
||||||
|
|
||||||
registers.insert(std::make_pair(pc, reg));
|
registers.insert(std::make_pair(pc, programReg));
|
||||||
|
|
||||||
while (executing) {
|
while (executing) {
|
||||||
std::cout << "L" << pc << "\t";
|
std::cout << instructionLabel << pc << "\t";
|
||||||
Register instruction = getOrDefault(registers, pc);
|
Register instruction = getOrDefault(programMap, pc);
|
||||||
printInstruction(std::cout, instruction) << std::endl;
|
printInstruction(std::cout, instruction) << std::endl;
|
||||||
|
|
||||||
if (instruction == 0) { /* HALT instruction. */
|
if (instruction == 0) { /* HALT instruction. */
|
||||||
@@ -47,19 +87,19 @@ int main() {
|
|||||||
auto splitInstruction = toPair<false>(instruction);
|
auto splitInstruction = toPair<false>(instruction);
|
||||||
|
|
||||||
if (splitInstruction.first % 2 == 0) { /* R+ 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();
|
RegIndex destinationLabel = splitInstruction.second.get_ui();
|
||||||
|
|
||||||
getOrDefault(registers, sourceRegisterIndex)++;
|
getOrDefault(registerMap, sourceRegisterIndex)++;
|
||||||
pc = destinationLabel;
|
pc = destinationLabel;
|
||||||
} else {
|
} else {
|
||||||
RegIndex sourceRegisterIndex = splitInstruction.first.get_ui();
|
RegIndex sourceRegisterIndex = splitInstruction.first.get_ui() / 2;
|
||||||
|
|
||||||
auto branches = toPair<true>(splitInstruction.second);
|
auto branches = toPair<true>(splitInstruction.second);
|
||||||
RegIndex trueLabel = branches.first.get_ui();
|
RegIndex trueLabel = branches.first.get_ui();
|
||||||
RegIndex falseLabel = branches.second.get_ui();
|
RegIndex falseLabel = branches.second.get_ui();
|
||||||
|
|
||||||
auto& sourceRegister = getOrDefault(registers, sourceRegisterIndex);
|
auto& sourceRegister = getOrDefault(registerMap, sourceRegisterIndex);
|
||||||
|
|
||||||
if (sourceRegister > 0) {
|
if (sourceRegister > 0) {
|
||||||
sourceRegister--;
|
sourceRegister--;
|
||||||
@@ -74,3 +114,18 @@ Register& getOrDefault(std::map<RegIndex, Register>& mapping, const RegIndex& lo
|
|||||||
auto valueIter = mapping.try_emplace(lookup, Register{ 0 });
|
auto valueIter = mapping.try_emplace(lookup, Register{ 0 });
|
||||||
return valueIter.first->second;
|
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++;
|
x++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skip the first 1 bit. */
|
||||||
unsplit >>= 1;
|
unsplit >>= 1;
|
||||||
|
|
||||||
return std::make_pair(x, unsplit);
|
return std::make_pair(x, unsplit);
|
||||||
@@ -26,6 +27,7 @@ std::pair<Register, Register> toPair<true>(Register unsplit) {
|
|||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skip the first 0 bit. */
|
||||||
unsplit >>= 1;
|
unsplit >>= 1;
|
||||||
|
|
||||||
return std::make_pair(x, unsplit);
|
return std::make_pair(x, unsplit);
|
||||||
|
|||||||
Reference in New Issue
Block a user