c – 线程代码解释器中的手动操作调用(打破正常流程)

给出了以下(缩短的)线程代码解释器(有限状态机).它有一个操作堆栈和一个操作数堆栈.执行时,从操作堆栈弹出下一个操作并执行.

有三个说明:

>从操作数堆栈中弹出两个操作数的加法指令将它们相加并将结果推送到操作数堆栈上
>打印指令,从操作数堆栈中弹出一个操作数并将其打印出来
> specialcall指令,尝试手动调用加法指令(来自指令内)并需要获取计算结果

现在的问题是,在specialcall方法中,需要计算的结果,但是在指令循环中调用加法运算之后,进一步执行将在初始特殊调用之后继续执行.

一种方法是创建一个操作结构,其中包含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;
}

最佳答案 你已经有了结果,它位于堆栈顶部.代码执行后.所以只需检索它:

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();

    uint32_t result = stack.back();
    stack.pop_back();
    std::cout << result << std::endl;
}

如果你需要在operation_specialcall()函数中使用结果,那么你需要深入思考该函数将如何使用结果.任意地,你可以打印它:

void specialcall() {
    stack.push_back(52);
    stack.push_back(25);
    operations.push_back(operation_addition);
    operations.push_back(operation_print);
}

两种方法都完成了同样的事情.这里的关键是区分编译时和运行时.避免让他们混淆,这需要你的口译员的重大改进.您必须实现等效的eval()函数.这需要能够管理多个指令流,您没有适当的管道.换句话说,您不能再将操作和堆栈变量作为全局变量.

点赞