/* * SPDX-FileCopyrightText: Dora "cat" * SPDX-License-Identifier: MPL-2.0 * * This Source Code Form is subject to the terms of the Mozilla Public License, * v. 2.0. If a copy of the MPL was not distributed with this file, You can * obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef GUARD_VARIADICMACHINE_MACHINE_H #define GUARD_VARIADICMACHINE_MACHINE_H #include #include #include #include #include #include namespace VariadicMachine { using Command = int; enum : int { // Single Argument NoCommand, MoveLeft, MoveRight, Increment, Decrement, // Two Arguments IncrementBy, DecrementBy, SetTo, Print, // Type AsDigit, AsUnsignedDigit, AsCharacter, AsBinary, AsHex, }; template class VMachine { public: template constexpr void Do(Commands &&...commands) { (Execute(commands), ...); } private: Command State = NoCommand; std::array memory; int W = 0, X = 0, Y = 0, Z = 0; std::size_t currentPosition = 0; void Execute(int command) { switch (State) { case NoCommand: break; case IncrementBy: memory[currentPosition] += command; State = NoCommand; return; case DecrementBy: memory[currentPosition] -= command; State = NoCommand; return; case SetTo: memory[currentPosition] = command; State = NoCommand; return; case Print: handlePrint(command); State = NoCommand; return; default: std::terminate(); return; } // State: NoCommand switch (command) { case MoveLeft: // Underflow wrap if (--currentPosition > maxCells) { currentPosition = maxCells; } return; case MoveRight: // Overflow wrap if (++currentPosition > maxCells) { currentPosition = 0; } return; case Increment: ++memory[currentPosition]; return; case Decrement: --memory[currentPosition]; return; // Double Argument Commands case Print: case IncrementBy: case DecrementBy: State = static_cast(command); return; default: std::cout << "Here\n"; std::terminate(); 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