Rust 开发编译器速成(二):计算编译器
书接上文。本章节会接触一些真正硬核的东西,包括从 Ast 生成 IR,以及制作一个迷你版的 LLVM,并且能够输出 LLVM IR 代码。
目标 我们会实现一个 AOT 编译器,它能够编译类似如下的语句:
11;-mem*3-1;print(mem);print(mem+7); 输出:
1-4 23 可以使用命令行
1calc -e "1;-mem*3-1;print(mem);print(mem+7);" | lli - 来运行。
环境准备 我们会沿用上一章节的代码,所以请确保你已经完成了上一章节的代码。
然后我们虽然不需要依赖 LLVM 就能生成 LLVM IR,但为了能够运行 LLVM IR,我们还是需要安装 LLVM。以 MacOS 为例:
1brew install llvm 确保 lli 命令能够运行即可。
另外我们多了一个依赖:
1id-arena = "2.2.1" 它的作用是提供竞技场分配,这样我们可以避免使用令人头秃的 Rc<RefCell<T>> 以及对应的 Weak。下面用了你就知道了。
生成 IR 前的准备 LLVM 中的 Value 首先需要介绍一下 Value。
Value 是所有 IR 实体的基类。每个 Value 都是一个命名的值,可以是整数、浮点数、指针、函数等等。Value 可以作为操作数用于构建表达式或指令,并用于定义全局变量、局部变量和函数的参数和返回值。
Value 有许多子类,如 Instruction、Argument、Constant 等等,它们各自有不同的功能。但是,不同的 Value 实例都有一些共同的特点,例如它们都有一个唯一的名称(以及命名前缀),可以拥有一个类型,还可以被分配给任何指令作为操作数。
Read more...