次の (短縮された) スレッド化されたコード インタープリター (有限状態マシン) が与えられます。オペレーション スタックとオペランド スタックがあります。実行時に、次の操作が操作スタックからポップされて実行されます。
次の 3 つの指示があります。
- オペランド スタックから 2 つのオペランドをポップする加算命令は、それらを加算し、結果をオペランド スタックにプッシュします。
- オペランド スタックから 1 つのオペランドをポップして出力する印刷命令
- 加算命令を (命令内から)手動で呼び出そうとし、計算結果を取得する必要があるspecialcall命令
ここでの問題は、specialcall メソッドでは計算の結果が必要ですが、命令ループで加算演算が呼び出された後、最初の specialcall の直後にさらに実行が継続することです。
1 つのアプローチは、a) 操作と b) 必要に応じてジャンプするアドレスを含む操作構造体を作成することです。次に、命令ループで、命令構造体がポップされてアドレスが設定されると、実際の命令の実行直後にこのアドレスへのジャンプが行われます。
この問題を解決する他の方法はありますか?
#include <stdint.h>
#include <iostream>
#include <deque>
const uint32_t operation_addition = 1;
const uint32_t operation_print = 2;
const uint32_t operation_specialcall = 3;
std::deque<uint32_t> operations;
std::deque<uint32_t> stack;
void specialcall() {
std::cout << "specialcall" << std::endl;
// Manually create the call
stack.push_back(52);
stack.push_back(25);
operations.push_back(operation_addition);
// "place to jump back"
// Need result of calculation here!
...
}
void addition() {
std::cout << "addition" << std::endl;
uint32_t operandA = stack.back();
stack.pop_back();
uint32_t operandB = stack.back();
stack.pop_back();
uint32_t result = operandA + operandB;
stack.push_back(result);
}
void print() {
std::cout << "print" << std::endl;
uint32_t result = stack.back();
stack.pop_back();
std::cout << result << std::endl;
}
void start() {
while (!operations.empty()) {
uint32_t op = operations.back();
operations.pop_back();
switch (op) {
case operation_specialcall:
specialcall();
break;
case operation_print:
print();
break;
case operation_addition:
addition();
break;
}
}
}
int main() {
stack.push_front(25);
stack.push_front(53);
operations.push_front(operation_addition);
operations.push_front(operation_print);
operations.push_front(operation_specialcall);
start();
std::cout << "execution finished" << std::endl;
}