解释器:沿着 AST 直接算结果
本节阅读量:解释器做的事很直接:
|
|
它不会生成汇编,也不会生成别的文件。
例如:
|
|
解释器最后直接得到:
|
|
先用人脑算一次
看这个表达式:
|
|
我们手算时会这样想:
|
|
换成更机械的步骤:
|
|
这就是解释器的核心。
先处理两种表达式
第一章的语言还很小,解释器先学会处理两种表达式。
整数表达式:
|
|
比如:
|
|
加法表达式:
|
|
比如:
|
|
如果左右两边本身还是加法,就继续用同样的规则。
这就是递归:解决一个大表达式时,先解决它的子表达式。
对应到 C++ 代码
代码在 code/01_numbers/src/interp/interpreter.cpp。
AST 节点有一个 kind 字段:
|
|
解释器先看 kind,再用 switch 选择求值规则。
这里的顺序很重要:
|
|
先看整数:
|
|
可以读成:
|
|
expr 的类型是通用的 Expr&。确认 kind 是 integer 之后,这一行:
|
|
可以先理解成:
|
|
再看加法:
|
|
可以读成:
|
|
这里也一样,先通过 kind 确认它是加法,再把通用的 Expr 当成具体的 AddExpr 来用。
add_expr.lhs 和 add_expr.rhs 是 unique_ptr<Expr>,也就是“拥有子表达式的指针”。前面的 * 表示取出它指向的那个表达式节点:
|
|
所以:
|
|
就是“递归求左子表达式的值”。
完整函数:
|
|
switch 在这里的作用是判断:
|
|
第一章只有两种可能:
|
|
后面章节会加更多节点。
跑一下解释器
运行:
|
|
输出:
|
|
再运行:
|
|
输出:
|
|
本节目录