编译实践Lv2.初试目标代码生成
目的 实现一个能处理 main 函数和 return 语句的编译器, 同时输出编译后的 RISC-V 汇编。 编译器会将如下的 SysY 程序: int main() { // 摊牌了, 我是注释 return 0; } 编译为对应的 RISC-V 汇编: .text .globl main main: li a0, 0 ret 或: .text .globl main main: li t0, 0 mv a0, t0 ret 实现 Lv2.1. 处理 Koopa IR 这一节的任务是建立内存形式的 Koopa IR。 libkoopa 中的接口并没有我定义的AST数据类型,所以可以先把 Program Dump 到 string 中,再用koopa_parse_from_string解析这个 string,得到内存形式的 Koopa IR。 Lv2.2. 目标代码生成 这一节的任务是生成 RISC-V 汇编。 可以写一个头文件和cpp文件(ASMGenerator.h,ASMGenerator.cpp)专门用来生成汇编。在ASMGenerator.h中声明需要用到的函数, class ASMGenerator { public: ASMGenerator(std::ostream &os) : os(os) {} void Generate(const koopa_raw_program_t &program); private: // DFS 遍历族 void Visit(const koopa_raw_program_t &program); void Visit(const koopa_raw_slice_t &slice); void Visit(const koopa_raw_function_t &func); void Visit(const koopa_raw_basic_block_t &bb); void Visit(const koopa_raw_value_t &value); // 辅助 void EmitPrologue(); void EmitEpilogue(); // 共享状态 std::ostream &os; int frame_size = 0; // 对齐后的栈帧大小 std::string cur_func; // 当前函数名(已去 @) }; 在ASMGenerator.cpp分别实现这些函数, ...