本章总结

本节阅读量:

第一章只支持很小的语言:

1
2
3
整数
负整数
(+ expr expr)

但这已经走通了一门语言实现最重要的两条路:

1
2
源码 -> token -> AST -> 解释器 -> 结果
源码 -> token -> AST -> IR -> 汇编 -> 可执行程序

前半条路回答:

1
这个程序是什么意思?

解释器沿着 AST 递归求值。遇到整数就返回整数,遇到加法就先求左右两边,再把结果相加。

后半条路回答:

1
这个意思怎样变成机器能执行的步骤?

编译器先把 AST 降成 IR,让嵌套表达式变成一行一行的计算步骤。再给每个临时变量分配栈槽,把 IR 翻译成 x86-64 AT&T 汇编。最后用 cc 把汇编变成可执行程序。

这一章里有几个分界线很重要:

1
2
3
4
5
6
lexer   只切 token,不理解程序含义
parser  把 token 组装成 AST
AST     保存程序结构
interp  按 AST 直接算结果
IR      保存更接近汇编的计算步骤
compile 把 IR 写成汇编文本

后面章节会继续扩展语言,但不会推翻这条主线。第二章加入变量和 let 后,新的问题会变成:

1
2
解释器怎么知道变量的值?
编译器怎么把源码里的变量名变成栈槽?

也就是从“只计算数字和加法”,走向“处理名字和作用域”。


1.8 compile:把 IR 翻译成汇编

上一节

1.10 练习

下一节


本节目录