何时/何地在编译过程中进行类型检查

时间:2018-05-26 20:52:14

标签: ruby haskell compiler-construction jit typechecking

在编译过程中(在高级别)通常会发生类型检查(教科书与实践中)时,在高级别想知道。我对编译过程的理解大致是:

  1. 将源代码解析为AST
  2. 将AST转换为中间表示IR
  3. 优化IR(即SSA表格,注册分配等)
  4. 简化IR
  5. 生成最终输出代码
  6. 想知道是否在(1)和(2),(2)和(3)之间,或(4)之间发生了类型检查,或者是否在整个过程中发生了类似的情况,或其他情况。我有兴趣知道面向对象,功能和逻辑编程的答案(按照优先级顺序),但如果我必须选择一个OO,如Ruby之类的动态类型语言,或静态类型函数像Haskell这样的语言。

1 个答案:

答案 0 :(得分:7)

静态类型检查通常在AST上执行,因此它发生在1和2之间或作为2的一部分(意味着只要IR处理器处理AST节点,IR发生器就会调用类型检查器中的函数 - 当然IR发生器和类型检查器应该仍然存在于不同的模块/文件中。

理论上,您可以对IR执行类型检查,但这通常会导致以下至少一个问题:

  1. IR没有足够的信息来捕获您想要的所有错误。
  2. IR不包含足够的信息以在所有情况下产生最佳错误消息。作为一个例子,考虑IR表示使用相同指令的数组访问和指针算术。现在,您希望为具有浮点索引的数组访问生成错误。如果消息是“浮点值不允许作为指针算术的操作数”,那么当代码不包含任何指针算术时会令人困惑。要求用户知道数组访问被表示为指针算术以理解错误消息,不会非常用户友好。
  3. 为了进行类型检查,您需要向IR添加大量额外信息,使IR变得更加复杂和笨拙,但您从中获得的就是以与您相同的方式处理IR的能力AST会没有获得任何好处。
  4. 通常使用IR而不是AST意味着您不必处理尽可能多的情况(完全是因为IR使用相同的指令表示不同的事物)。这是主要的好处。但是如果你再跳过额外的箍只是为了能够以不同的方式处理这些情况,你可能也会首先使用AST。

    因此通常首选对AST¹进行类型检查。 GHC(主要的Haskell编译器)执行AST的类型检查。

    ¹或至少与AST非常接近的东西 - 例如,可能是AST和最终IR之间的表示,它在某些方面简化了事情(例如删除扁平嵌套表达式),而不会丢失相关的信息输入检查。

    动态类型检查在运行时发生。执行这些动态类型检查的代码是解释器的一部分(如果有解释器)或由代码生成器插入。

    Ruby在解释器中执行类型检查。