存储弱类型变量的方法
Methods of storing weakly typed variables
在我的编译器开发阶段,我 运行 遇到了一个相当复杂的问题:如何用我的语言存储弱类型变量。
由于我允许在不明确指定变量类型的情况下声明变量,并允许函数 return 任一类型(例如函数可以 return 标量或数组),我现在面临困难以何种形式存储这些变量。
以下是我考虑过的可能性,但它们都有 显着 开销:
- 将所有变量视为双精度列表 (
List<double>
),并让第一个元素指定它是标量还是数组(例如 0
或 1
)。
- 将所有变量视为
object
个实例。
- 将所有变量视为
TVar
(自定义class),可以是double
或List<double>
。
谨记:
- 我打算拥有的唯一两种类型的变量是双精度和双精度数组,因为所有其他变量都可以从此类派生(例如,char 是双精度的情况,字符串是字符数组,e.t.c.)
- 我正在使用
ILAsm
,这是一种高级汇编语言(基本上是 .NET 中间语言)
这显然在很大程度上取决于您的语言。如果你不在编译时修复变量类型,那么你需要用类型信息包装所有的值。 (这有时被称为 "boxing" 变量,尽管它不是 "boxing" 的唯一含义。)
另一方面,您也许可以在编译时推断出变量类型。例如,awk
(尽管它完全没有声明语法,但有时会通过某种虚拟机的编译器实现)允许标量和数组变量,但很有可能找出每个 awk 变量:
除了作为函数参数传递外,数组变量不能没有下标使用,因为awk
不允许数组赋值。因此,任何带下标的变量都必须是数组,而任何不带下标的变量,除了函数调用外,都必须是标量。
函数也没有原型,但所有有用的参数都必须在函数体中使用或传递给另一个函数。因此可以为每个函数创建一个原型,将每个变量标识为 scalar/array/unknown.
对函数调用的最小定点重复扫描将提供有关每个有用变量的精确信息。如果变量既用作标量又用作数组,则可能会引发错误。如果根本不使用变量(除了可能传递给不使用相应参数的函数),则可以简单地删除该变量,或者可以将其编译为(未使用的)标量。
这还不足以完全键入 awk
变量,因为存在三种标量类型,因此在大多数情况下仍然需要装箱。在某些情况下,也可能推断出标量类型,尽管由于自动强制转换会更加棘手。但是,您的语言只有一种标量类型,因此类似于上述的策略可能可行。
在我的编译器开发阶段,我 运行 遇到了一个相当复杂的问题:如何用我的语言存储弱类型变量。
由于我允许在不明确指定变量类型的情况下声明变量,并允许函数 return 任一类型(例如函数可以 return 标量或数组),我现在面临困难以何种形式存储这些变量。
以下是我考虑过的可能性,但它们都有 显着 开销:
- 将所有变量视为双精度列表 (
List<double>
),并让第一个元素指定它是标量还是数组(例如0
或1
)。 - 将所有变量视为
object
个实例。 - 将所有变量视为
TVar
(自定义class),可以是double
或List<double>
。
谨记:
- 我打算拥有的唯一两种类型的变量是双精度和双精度数组,因为所有其他变量都可以从此类派生(例如,char 是双精度的情况,字符串是字符数组,e.t.c.)
- 我正在使用
ILAsm
,这是一种高级汇编语言(基本上是 .NET 中间语言)
这显然在很大程度上取决于您的语言。如果你不在编译时修复变量类型,那么你需要用类型信息包装所有的值。 (这有时被称为 "boxing" 变量,尽管它不是 "boxing" 的唯一含义。)
另一方面,您也许可以在编译时推断出变量类型。例如,awk
(尽管它完全没有声明语法,但有时会通过某种虚拟机的编译器实现)允许标量和数组变量,但很有可能找出每个 awk 变量:
除了作为函数参数传递外,数组变量不能没有下标使用,因为
awk
不允许数组赋值。因此,任何带下标的变量都必须是数组,而任何不带下标的变量,除了函数调用外,都必须是标量。函数也没有原型,但所有有用的参数都必须在函数体中使用或传递给另一个函数。因此可以为每个函数创建一个原型,将每个变量标识为 scalar/array/unknown.
对函数调用的最小定点重复扫描将提供有关每个有用变量的精确信息。如果变量既用作标量又用作数组,则可能会引发错误。如果根本不使用变量(除了可能传递给不使用相应参数的函数),则可以简单地删除该变量,或者可以将其编译为(未使用的)标量。
这还不足以完全键入 awk
变量,因为存在三种标量类型,因此在大多数情况下仍然需要装箱。在某些情况下,也可能推断出标量类型,尽管由于自动强制转换会更加棘手。但是,您的语言只有一种标量类型,因此类似于上述的策略可能可行。