23 DataLayoutOption, Newton3Option>;
151 std::vector<size_t>
execute(
const Program &program,
const std::vector<MemoryCell> &initialStack) {
153 _removedPatterns.clear();
154 _stack = initialStack;
156 _stackPointer = initialStack.size() - 1;
160 executeInstruction(program.
instructions.at(_programCounter++));
163 return _removedPatterns;
167 void executeInstruction(Instruction instruction) {
168 switch (instruction.cmd) {
170 _stack.at(++_stackPointer) = instruction.payload;
173 _stack.at(++_stackPointer) = _stack.at(std::get<size_t>(instruction.payload));
176 _stack.at(std::get<size_t>(instruction.payload)) = _stack.at(_stackPointer--);
179 _stackPointer += std::get<size_t>(instruction.payload);
182 bool res = compare<std::less>();
184 _stack.at(_stackPointer) = res;
188 bool res = compare<std::greater>();
190 _stack.at(_stackPointer) = res;
194 bool res = compare<std::equal_to>();
196 _stack.at(_stackPointer) = res;
200 bool shouldJump = not std::get<bool>(_stack.at(_stackPointer--));
202 _programCounter = std::get<size_t>(instruction.payload);
207 _removedPatterns.push_back(std::get<size_t>(instruction.payload));
210 if (std::get<bool>(_stack.at(_stackPointer))) {
211 _removedPatterns.push_back(std::get<size_t>(instruction.payload));
218 bool res = std::get<bool>(_stack.at(_stackPointer)) and std::get<bool>(_stack.at(_stackPointer - 1));
219 _stack.at(--_stackPointer) = res;
223 bool res = std::get<bool>(_stack.at(_stackPointer)) or std::get<bool>(_stack.at(_stackPointer - 1));
224 _stack.at(--_stackPointer) = res;
232 computeBinary(_stack.at(_stackPointer - 1), _stack.at(_stackPointer), [](
auto l,
auto r) { return l * r; });
233 _stack.at(--_stackPointer) = res;
237 auto res = computeBinary(_stack.at(_stackPointer - 1), _stack.at(_stackPointer), [](
auto l,
auto r) {
240 return r == 0 ? std::numeric_limits<decltype(l / r)>::max() : l / r;
242 _stack.at(--_stackPointer) = res;
247 computeBinary(_stack.at(_stackPointer - 1), _stack.at(_stackPointer), [](
auto l,
auto r) { return l + r; });
248 _stack.at(--_stackPointer) = res;
253 computeBinary(_stack.at(_stackPointer - 1), _stack.at(_stackPointer), [](
auto l,
auto r) { return l - r; });
254 _stack.at(--_stackPointer) = res;
258 _stack.at(_stackPointer) = not std::get<bool>(_stack.at(_stackPointer));
264 static constexpr auto isNumericVal() {
265 using type = std::remove_cv_t<std::remove_reference_t<T>>;
266 return std::is_same_v<type, double> or std::is_same_v<type, size_t>;
269 template <
template <
class>
typename Compare>
270 [[nodiscard]]
bool compare() {
271 bool res = std::visit(
272 [](
auto &&left,
auto &&right) {
273 if constexpr (std::is_same_v<
decltype(left),
decltype(right)>) {
274 return Compare{}(left, right);
275 }
else if constexpr (isNumericVal<decltype(left)>() and isNumericVal<decltype(right)>()) {
276 return Compare{}(left, right);
278 throw std::runtime_error(
"RuleVM: cannot compare");
282 _stack.at(_stackPointer - 1), _stack.at(_stackPointer));
286 template <
class Functor>
289 [&op](
auto &&l,
auto &&r) {
290 if constexpr (isNumericVal<decltype(l)>() and isNumericVal<decltype(r)>()) {
293 throw std::runtime_error(
"RuleVM: cannot compute binary operator with these operators");
304 size_t _programCounter;
308 size_t _stackPointer;
317 std::vector<MemoryCell> _stack;
321 std::vector<size_t> _removedPatterns;
Class representing the load estimator choices.
Definition: LoadEstimatorOption.h:18
A VM that is capable of executing a program with simple instructions on a stack of MemoryCells.
Definition: RuleVM.h:17
std::vector< size_t > execute(const Program &program, const std::vector< MemoryCell > &initialStack)
Executes a program on a given initial stack.
Definition: RuleVM.h:151
CMD
An enum with all commands that this VM supports.
Definition: RuleVM.h:28
@ JUMPZERO
Payload is program address.
Definition: RuleVM.h:60
@ NOT
Unary operator.
Definition: RuleVM.h:104
@ OUTPUTC
Outputs payload.
Definition: RuleVM.h:64
@ AND
Binary operator.
Definition: RuleVM.h:76
@ ADD
Binary operator.
Definition: RuleVM.h:96
@ OR
Binary operator.
Definition: RuleVM.h:80
@ HALT
Halts program execution.
Definition: RuleVM.h:72
@ LOADA
Payload is absolute stack address.
Definition: RuleVM.h:36
@ LESS
Binary comparison.
Definition: RuleVM.h:48
@ EQUAL
Binary comparison.
Definition: RuleVM.h:56
@ POP
Pops one value from the stack.
Definition: RuleVM.h:84
@ MUL
Binary operator.
Definition: RuleVM.h:88
@ CONDOUTPUTC
Executes OUTPUTC if top of the stack is True.
Definition: RuleVM.h:68
@ SUB
Binary operator.
Definition: RuleVM.h:100
@ LOADC
Load a constant on top of the stack (payload).
Definition: RuleVM.h:32
@ RESERVE
Payload is number of stack cells to reserve.
Definition: RuleVM.h:44
@ DIV
Binary operator.
Definition: RuleVM.h:92
@ STOREA
Payload is absolute stack address.
Definition: RuleVM.h:40
@ GREATER
Binary comparison.
Definition: RuleVM.h:52
std::variant< bool, double, size_t, ContainerOption, TraversalOption, LoadEstimatorOption, DataLayoutOption, Newton3Option > MemoryCell
The type of a memory cell in the stack the VM operates on.
Definition: RuleVM.h:23
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:32
An instruction to execute in the VM.
Definition: RuleVM.h:112
CMD cmd
The command to execute.
Definition: RuleVM.h:116
Instruction(CMD cmd, MemoryCell payload=MemoryCell{0ul})
Constructs an Instruction.
Definition: RuleVM.h:127
MemoryCell payload
The payload the instruction can have.
Definition: RuleVM.h:120
A program that can be executed by this VM.
Definition: RuleVM.h:134
size_t neededStackSize
The maximum stack size needed to execute the instructions.
Definition: RuleVM.h:142
std::vector< Instruction > instructions
The instructions the program consists of.
Definition: RuleVM.h:138