为C的子集实现基于堆栈的虚拟机

时间:2010-07-21 01:43:27

标签: c++ interpreter vm-implementation

大家好,我目前正在实施一种简单的编程语言来学习,但我需要一些建议。目前我正在设计我的口译员,但我遇到了一个问题。

我的语言是C的一个子集,我在堆栈解释器实现方面遇到了问题。在下面的语言中将编译:

somefunc ()
{
    1 + 2;
}

main ()
{
    somefunc ();
}

现在这没关系,但是当计算出“1 + 2”时,结果被压入堆栈然后函数返回但是堆栈上仍然有一个数字,并且不应该存在。我怎样才能解决这个问题呢?

我想过在函数调用之前保存堆栈的“状态”并在函数调用之后恢复“状态”。例如,保存堆栈上的元素数量,然后执行函数代码,返回,然后从堆栈弹出,直到我们拥有与之前相同数量的元素(如果函数返回了某些内容,则可能为+1)。

有什么想法吗?感谢您的任何提示!

3 个答案:

答案 0 :(得分:8)

好问题!我的一个爱好是编写玩具语言的编译器,所以感谢您的优秀编程品味。

表达式语句是语句中的代码只是表达式的语句。这意味着<expression> ;形式的任何内容,其中包括分配和函数调用等内容,但不包括if s,whilereturn s。任何表达式语句都会在最后的堆栈上留下一个剩余的值,你应该丢弃它。

1 + 2是一个表达式语句,但这些语句也是如此:

  • x = 5;
    赋值表达式在堆栈上保留值5,因为赋值的结果是左操作数的值。 语句完成后,弹出未使用的值5。

  • printf("hello world!\n");
    printf()返回输出的字符数。您将在堆栈上保留此值,因此在语句完成时将其弹出。

实际上,除非表达式的类型为void,否则每个表达式语句都会在堆栈上留下一个值。在这种情况下,您可以使用特殊情况void语句,之后不会弹出任何内容,或者将假装的“void”值推送到堆栈上,这样您就可以随时弹出一个值。

答案 1 :(得分:2)

您需要一个更智能的解析器。当您看到一个未使用其值的表达式时,您需要发出一个POP。

答案 2 :(得分:0)

这是学习优化的重要机会。你有一个数字但整数数学的函数,int数学结果甚至没有以任何方式,形状或形式使用。

让编译器优化函数将减少生成的字节码并执行任何操作!