本篇来尝试描述一下if-else_if-else 语句如何进行实现。

基本内容

语法树部分

先上图。

if-else_if-else 的语法树
if-else_if-else 的语法树

这里给的只是一个示例的语法树图示, 读者可以根据自己的需求进行修改。

笔者的想法是, 使用一个if_else节点作为根节点, 它的所有子节点是N个if节点和一个else节点。

由图可知,根节点下面有2个if节点, 和一个else 节点。 每个节点的内容和上篇类似,这里就不再赘述了。

对比上篇文章的内容, 笔者省略了condition等中间块。

直接在 AST上进行运算

笔者今天突然发现,上篇提到的跳转问题其实是可以解决的,目前大概有下面两个想法。

  • 给每个节点设置一个出口节点, 即当前节点成功执行/失败之后, 跳到出口节点执行。
    • 此方法似乎会有点浪费内存
  • 在线程状态上 添加一个或多个出口节点, 用于跳转。
  • 似乎上述方法都没有使用字节码简单。

言归正传, 如果要在上面的语法树上直接运算的话, 笔者建议的方式是这样的。

if_else节点按顺序依次执行每个子节点, 如果碰到执行成功的或者全部子节点执行结束, 就直接从if_else节点中返回出去。

因为else 节点是放在最后面的, 所以不需要额外处理它。

使用字节码进行运算

这部分其实很简单, 笔者只大致说一下思路。

下面说的指令都是笔者自定义的字节码指令。

  • 定义一个出口标签end_of_if_else
  • a == 0的逻辑判断语句之后生成一条 条件跳转语句cjmp, 跳转到else if语句的开始部分。
  • print("a == 0"); 函数语句的调用之后附加一条无条件跳转语句jmp, 跳转到end_of_if_else
  • a > 0 的逻辑判断语句之后生成一条 条件跳转语句cjmp,跳转到else语句开始的地方。
  • 我们在生成字节码的时候应该是从AST的最里面的节点开始的, 所以这个其实还是挺简单就可以实现的。

上述描述中,笔者省略了部分类似的地方。