自制脚本语言[5.2] if-else_if-else语句
目录
警告
本文最后更新于 2023-07-30,文中内容可能已过时。
本篇来尝试描述一下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的最里面的节点开始的, 所以这个其实还是挺简单就可以实现的。
上述描述中,笔者省略了部分类似的地方。