0

在我的编译器的开发阶段,我遇到了一个非常复杂的问题:如何在我的语言中存储弱类型变量。

由于我允许在不明确指定其类型的情况下声明变量,并允许函数返回任一类型(例如函数可以返回标量 OR 数组),我现在面临着以何种形式存储这些变量的困难。

以下是我考虑过的可能性,但它们都有很大的开销:

  • 将所有变量视为双精度列表 ( List<double>) 并让第一个元素指定它是标量还是数组(01例如)。
  • 将所有变量视为object实例。
  • 将所有变量视为TVar(自定义类),可以是 adoubleList<double>.

要牢记:

  • 我打算拥有的唯一两种类型的变量是双精度和双精度数组,因为所有其他变量都可以从中派生(例如 char 是双精度的情况,字符串是字符数组等)
  • 我正在使用ILAsm它是更高级别的汇编风格(基本上是.NET中间语言)
4

1 回答 1

1

这显然很大程度上取决于您的语言。如果您在编译时不修复变量类型,那么您需要使用类型信息包装所有值。(这有时被称为“装箱”变量,尽管它不是“装箱”的唯一含义。)

另一方面,您可能能够在编译时推断出变量类型。例如,awk(尽管它完全没有声明语法,但有时通过编译器对某种虚拟机实现)允许标量和数组变量,但很可能找出每个 awk 变量的类型:

  1. 除了作为函数参数传递之外,数组变量不能在没有下标的情况下使用,因为awk它不允许数组赋值。因此,任何带有下标的变量都必须是一个数组,而任何不带下标的变量,除了在函数调用中,都必须是一个标量。

  2. 函数也没有原型,但所有有用的参数必须要么在函数体中使用,要么传递给另一个函数。因此可以为每个函数创建一个原型,将每个变量标识为标量/数组/未知。

  3. 然后,对函数调用的最小定点重复扫描将提供有关每个有用变量的精确信息。如果变量同时用作标量和数组,则可能会引发错误。如果根本不使用变量(除了可能传递给不使用相应参数的函数),那么可以简单地消除该变量,或者可以将其编译为(未使用的)标量。

这不足以完全键入awk变量,因为存在三种标量类型,所以在大多数情况下仍然需要装箱。在某些情况下,也可能推导出标量类型,尽管由于自动强制转换会比较棘手。但是,您的语言只有一个标量类型,因此类似于上述的策略可能是可行的。

于 2016-07-11T00:06:33.050 回答