diff --git a/machine.hpp b/machine.hpp index 54fd372..90a8f93 100644 --- a/machine.hpp +++ b/machine.hpp @@ -11,25 +11,34 @@ #define GUARD_VARIADICMACHINE_MACHINE_H #include +#include #include #include -#include #include #include namespace VariadicMachine { -enum Command : int16_t { +using Command = int; +enum : int { // Single Argument NoCommand, MoveLeft, MoveRight, Increment, Decrement, - PrintAsCharacter, // Two Arguments IncrementBy, - DecrementBy + DecrementBy, + SetTo, + Print, + + // Type + AsDigit, + AsUnsignedDigit, + AsCharacter, + AsBinary, + AsHex, }; template class VMachine { @@ -39,54 +48,65 @@ public: } private: - Command State = Command::NoCommand; - std::array memory; - std::int16_t W = 0, X = 0, Y = 0, Z = 0; - std::size_t maxCellLimit = maxCells, currentPosition = 0; + Command State = NoCommand; + std::array memory; + int W = 0, X = 0, Y = 0, Z = 0; + std::size_t currentPosition = 0; - void Execute(int16_t command) { + void Execute(int command) { switch (State) { - case Command::IncrementBy: + case NoCommand: + break; + + case IncrementBy: memory[currentPosition] += command; - State = Command::NoCommand; + State = NoCommand; return; - case Command::DecrementBy: + case DecrementBy: memory[currentPosition] -= command; - State = Command::NoCommand; + State = NoCommand; + return; + case SetTo: + memory[currentPosition] = command; + State = NoCommand; + return; + case Print: + handlePrint(command); + State = NoCommand; return; default: std::terminate(); - break; - - case Command::NoCommand: - break; + return; } // State: NoCommand switch (command) { - case Command::MoveLeft: - --currentPosition; + case MoveLeft: + // Underflow wrap + if (--currentPosition > maxCells) { + currentPosition = maxCells; + } return; - case Command::MoveRight: - ++currentPosition; + case MoveRight: + // Overflow wrap + if (++currentPosition > maxCells) { + currentPosition = 0; + } return; - case Command::Increment: + case Increment: ++memory[currentPosition]; return; - case Command::Decrement: + case Decrement: --memory[currentPosition]; return; - case Command::PrintAsCharacter: - std::wcout << static_cast(memory[currentPosition]); - return; - // Double Argument Commands - case Command::IncrementBy: - case Command::DecrementBy: + case Print: + case IncrementBy: + case DecrementBy: State = static_cast(command); return; @@ -96,6 +116,34 @@ private: return; } } + + void handlePrint(int Type) { + switch (Type) { + case AsDigit: + std::cout << memory[currentPosition]; + return; + + case AsUnsignedDigit: + std::cout << static_cast(memory[currentPosition]); + return; + + case AsCharacter: + std::wcout << static_cast(memory[currentPosition]); + return; + + case AsBinary: + std::cout << std::bitset(memory[currentPosition]); + return; + + case AsHex: + std::cout << std::hex << memory[currentPosition] << std::dec; + return; + + default: + std::terminate(); + return; + } + } }; } // namespace VariadicMachine #endif