从 AST 为条件表达式生成分支指令

Generating branch instructions from an AST for a conditional expression

我正在尝试为领域特定语言编写编译器,目标是基于堆栈机器的 VM,而不是 JVM。

我已经为我的语言生成了一个解析器,并且可以很容易地生成一个我可以轻松行走的 AST。我也没有问题将我的语言的许多语句转换为该 VM 的适当指令,但在遇到复杂条件时处理适当分支指令的生成时遇到障碍,尤其是当它们与(可能嵌套的)'and'-like 或 'or' 类似的操作相结合,这些操作应酌情使用短路分支。

我不是要任何人为我写这篇文章。我知道我还没有开始足够详细地描述我的问题。我要的是指向有用的 material 的指针,它可以让我克服我面临的这个障碍。正如我所说,我已经过了将我的语言中大约 90% 的语句转换为适用指令的阶段,但让我感到困惑的是条件的处理和生成适当的流程控制指令。到目前为止,我能够找到的关于从 AST 生成代码的大部分信息似乎只处理与简单的命令式语句相对应的代码生成,但是条件和流控制的处理似乎更加稀缺.

除了 'and' 的 short-circuiting/lazy-evaluation 机制和 'or' 之类的构造,我不关心处理任何其他优化。

每个条件控制流都可以建模为流程图(或流程图),其中条件的两个分支具有不同的目标。鉴于布尔运算符短路,它们是控制流元素而不是简单的表达式,它们需要这样建模。

考虑这一点的一种方法是将布尔运算符改写为三元条件运算符的实例。因此,例如,A and B 变为 A ? B : falseA or B 变为 A ? true : B [注 1]。请注意,每个控制流程图恰好有两个输出点。

要组合布尔表达式,只需代入图中即可。例如,这里是 A AND (B OR C)

您只需交换两个流出的含义即可实现 NOT

如果布尔表达式的最终使用是某种条件,例如 if 语句或条件循环,您可以按原样使用控制流。如果布尔表达式要保存到变量中或用作值,则需要在两个流出处填充代码以创建相关常量,通常是 truefalse 布尔常量,或(在类 C 语言中)1 或 0。


备注:

  1. 另一种写法是A and B ⇒ A ? B : AA or B ⇒ A ? A : B,但这对于控制流视图来说用处不大,而且还模糊了一个事实,即意图只对每个表达式求值一次。这种形式(修改为重用 A 的初始计算)通常用于具有多个“假”值的语言(如 Python)。