/* * 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 { enum Command : int16_t { // Single Argument NoCommand, MoveLeft, MoveRight, Increment, Decrement, PrintAsCharacter, // Two Arguments IncrementBy, DecrementBy }; template class VMachine { public: template constexpr void Do(Commands &&...commands) { (Execute(commands), ...); } 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; void Execute(int16_t command) { switch (State) { case Command::IncrementBy: memory[currentPosition] += command; State = Command::NoCommand; return; case Command::DecrementBy: memory[currentPosition] -= command; State = Command::NoCommand; return; default: std::terminate(); break; case Command::NoCommand: break; } // State: NoCommand switch (command) { case Command::MoveLeft: --currentPosition; return; case Command::MoveRight: ++currentPosition; return; case Command::Increment: ++memory[currentPosition]; return; case Command::Decrement: --memory[currentPosition]; return; case Command::PrintAsCharacter: std::wcout << static_cast(memory[currentPosition]); return; // Double Argument Commands case Command::IncrementBy: case Command::DecrementBy: State = static_cast(command); return; default: std::cout << "Here\n"; std::terminate(); return; } } }; } // namespace VariadicMachine #endif