按值传递语义很容易在解释器中实现(例如,您的普通命令式语言)。对于每个范围,我们维护一个将标识符映射到其值的环境。处理函数调用涉及创建一个新环境并使用参数的副本填充它。
如果我们允许通过引用传递的参数,这将不起作用。这种情况通常如何处理?
答案 0 :(得分:1)
首先,您的解释器必须检查参数是否可以通过引用传递 - 参数在赋值语句的左侧是合法的。例如,如果f
有一个传递引用参数,f(x)
就可以了(因为x := y
有意义)但f(1+1)
不是(1+1 := y
没有意义)。典型的限定参数是变量和类似于变量的构造,如数组索引(如果a
是一个数组,5
是合法索引,f(a[5])
是可以的,因为a[5] = y
使得义)。
如果参数通过了该检查,则解释器可以在处理函数调用时确定它所引用的精确内存位置。构造新环境时,将对该内存位置的引用作为pass-by-reference参数的值。这个参考具体看起来取决于你的解释器的设计,特别是你如何表示变量:如果你的实现语言支持它,你可以简单地使用指针,但如果你的设计需要它可能会更复杂(重要的是它)是引用必须使您能够检索和修改所引用的内存位置中包含的值。
当你的翻译解释一个函数的主体时,它可能必须特别处理传递参数,因为环境不包含适当的值,只是一个引用。您的口译员必须认识到这一点,并查看参考指向的内容。例如,如果x
是局部变量且y
是传递引用参数,则计算x+1
和y+1
可能(取决于解释器的详细信息)工作方式不同:在前者中,您只需查找x
的值,然后再添加一个;在后者中,您必须查找y
恰好在环境中绑定的引用,并查看引用远端的变量中存储的值,然后向其中添加一个值。同样,x = 1
和y = 1
可能会有不同的工作方式:前者只是修改x
的值,而后者必须首先查看引用指向的位置并修改任何变量或它在那里找到类似变量的东西(比如一个数组元素)。
您可以通过将环境中的所有变量绑定到引用而不是值来简化此操作;然后查找变量的值与查找pass-by-reference参数的值的过程相同。然而,这会产生其他问题,这取决于你的翻译设计和语言的细节是否值得麻烦。