24 DataLayoutOption, Newton3Option>;
152 std::vector<size_t>
execute(
const Program &program,
const std::vector<MemoryCell> &initialStack) {
154 _removedPatterns.clear();
155 _stack = initialStack;
157 _stackPointer = initialStack.size() - 1;
161 executeInstruction(program.
instructions.at(_programCounter++));
164 return _removedPatterns;
168 void executeInstruction(Instruction instruction) {
169 switch (instruction.cmd) {
171 _stack.at(++_stackPointer) = instruction.payload;
174 _stack.at(++_stackPointer) = _stack.at(std::get<size_t>(instruction.payload));
177 _stack.at(std::get<size_t>(instruction.payload)) = _stack.at(_stackPointer--);
180 _stackPointer += std::get<size_t>(instruction.payload);
183 bool res = compare<std::less>();
185 _stack.at(_stackPointer) = res;
189 bool res = compare<std::greater>();
191 _stack.at(_stackPointer) = res;
195 bool res = compare<std::equal_to>();
197 _stack.at(_stackPointer) = res;
201 bool shouldJump = not std::get<bool>(_stack.at(_stackPointer--));
203 _programCounter = std::get<size_t>(instruction.payload);
208 _removedPatterns.push_back(std::get<size_t>(instruction.payload));
211 if (std::get<bool>(_stack.at(_stackPointer))) {
212 _removedPatterns.push_back(std::get<size_t>(instruction.payload));
219 bool res = std::get<bool>(_stack.at(_stackPointer)) and std::get<bool>(_stack.at(_stackPointer - 1));
220 _stack.at(--_stackPointer) = res;
224 bool res = std::get<bool>(_stack.at(_stackPointer)) or std::get<bool>(_stack.at(_stackPointer - 1));
225 _stack.at(--_stackPointer) = res;
233 computeBinary(_stack.at(_stackPointer - 1), _stack.at(_stackPointer), [](
auto l,
auto r) { return l * r; });
234 _stack.at(--_stackPointer) = res;
238 auto res = computeBinary(_stack.at(_stackPointer - 1), _stack.at(_stackPointer), [](
auto l,
auto r) {
241 return r == 0 ? std::numeric_limits<decltype(l / r)>::max() : l / r;
243 _stack.at(--_stackPointer) = res;
248 computeBinary(_stack.at(_stackPointer - 1), _stack.at(_stackPointer), [](
auto l,
auto r) { return l + r; });
249 _stack.at(--_stackPointer) = res;
254 computeBinary(_stack.at(_stackPointer - 1), _stack.at(_stackPointer), [](
auto l,
auto r) { return l - r; });
255 _stack.at(--_stackPointer) = res;
259 _stack.at(_stackPointer) = not std::get<bool>(_stack.at(_stackPointer));
265 static constexpr auto isNumericVal() {
266 using type = std::remove_cv_t<std::remove_reference_t<T>>;
267 return std::is_same_v<type, double> or std::is_same_v<type, size_t>;
270 template <
template <
class>
typename Compare>
271 [[nodiscard]]
bool compare() {
272 bool res = std::visit(
273 [](
auto &&left,
auto &&right) {
274 if constexpr (std::is_same_v<
decltype(left),
decltype(right)>) {
275 return Compare{}(left, right);
276 }
else if constexpr (isNumericVal<decltype(left)>() and isNumericVal<decltype(right)>()) {
277 return Compare{}(left, right);
279 throw std::runtime_error(
"RuleVM: cannot compare");
283 _stack.at(_stackPointer - 1), _stack.at(_stackPointer));
287 template <
class Functor>
290 [&op](
auto &&l,
auto &&r) {
291 if constexpr (isNumericVal<decltype(l)>() and isNumericVal<decltype(r)>()) {
294 throw std::runtime_error(
"RuleVM: cannot compute binary operator with these operators");
305 size_t _programCounter;
309 size_t _stackPointer;
318 std::vector<MemoryCell> _stack;
322 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:18
std::vector< size_t > execute(const Program &program, const std::vector< MemoryCell > &initialStack)
Executes a program on a given initial stack.
Definition: RuleVM.h:152
CMD
An enum with all commands that this VM supports.
Definition: RuleVM.h:29
@ JUMPZERO
Payload is program address.
Definition: RuleVM.h:61
@ NOT
Unary operator.
Definition: RuleVM.h:105
@ OUTPUTC
Outputs payload.
Definition: RuleVM.h:65
@ AND
Binary operator.
Definition: RuleVM.h:77
@ ADD
Binary operator.
Definition: RuleVM.h:97
@ OR
Binary operator.
Definition: RuleVM.h:81
@ HALT
Halts program execution.
Definition: RuleVM.h:73
@ LOADA
Payload is absolute stack address.
Definition: RuleVM.h:37
@ LESS
Binary comparison.
Definition: RuleVM.h:49
@ EQUAL
Binary comparison.
Definition: RuleVM.h:57
@ POP
Pops one value from the stack.
Definition: RuleVM.h:85
@ MUL
Binary operator.
Definition: RuleVM.h:89
@ CONDOUTPUTC
Executes OUTPUTC if top of the stack is True.
Definition: RuleVM.h:69
@ SUB
Binary operator.
Definition: RuleVM.h:101
@ LOADC
Load a constant on top of the stack (payload).
Definition: RuleVM.h:33
@ RESERVE
Payload is number of stack cells to reserve.
Definition: RuleVM.h:45
@ DIV
Binary operator.
Definition: RuleVM.h:93
@ STOREA
Payload is absolute stack address.
Definition: RuleVM.h:41
@ GREATER
Binary comparison.
Definition: RuleVM.h:53
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:24
This is the main namespace of AutoPas.
Definition: AutoPasDecl.h:32
An instruction to execute in the VM.
Definition: RuleVM.h:113
CMD cmd
The command to execute.
Definition: RuleVM.h:117
Instruction(CMD cmd, MemoryCell payload=MemoryCell{0ul})
Constructs an Instruction.
Definition: RuleVM.h:128
MemoryCell payload
The payload the instruction can have.
Definition: RuleVM.h:121
A program that can be executed by this VM.
Definition: RuleVM.h:135
size_t neededStackSize
The maximum stack size needed to execute the instructions.
Definition: RuleVM.h:143
std::vector< Instruction > instructions
The instructions the program consists of.
Definition: RuleVM.h:139