# Lab2：生成中间表示（IR）

## 1. 本实验定位
  
Lab2 的目标是在该示例基础上扩展语义覆盖范围，逐步把更多 SysY 语法正确翻译为 IR。

## 2. Lab2 要求

需要同学完成：

1. 熟悉 IR 相关数据结构与构建接口。
2. 理解当前语法树 -> IR 的最小实现流程。
3. 在现有框架上扩展 IR 生成能力，使其覆盖课程要求的Sysy语法。


## 3. 当前代码框架（与 Lab2 直接相关）

1. IR 定义与打印
   - `src/ir/IR.h`
   - `src/ir/IRBuilder.cpp`
   - `src/ir/IRPrinter.cpp`

2. 语法树 -> IR 生成器
   - `src/irgen/IRGen.h`
   - `src/irgen/IRGenDriver.cpp`
   - `src/irgen/IRGenFunc.cpp`
   - `src/irgen/IRGenDecl.cpp`
   - `src/irgen/IRGenStmt.cpp`
   - `src/irgen/IRGenExp.cpp`

3. 入口流程
   - `src/main.cpp`

## 4. Lab2 需要补充的内容

1. 必须修改的文件
   - `src/irgen/IRGenDecl.cpp`
   - `src/irgen/IRGenStmt.cpp`
   - `src/irgen/IRGenExp.cpp`
   - `src/ir/IR.h`（当现有 IR 指令/类型不够用时）
   - `src/ir/IRBuilder.cpp`（当需要新增构建接口时）
   - `src/ir/IRPrinter.cpp`（新增 IR 指令后补齐打印）
   - `src/irgen/IRGen.h`（当需要扩展状态或辅助接口时）

2. 视实现需要可能修改
   - `src/main.cpp`（当需要调整输出阶段行为）

## 5. 当前最小示例实现说明

当前语法树 -> IR 仅覆盖最小子集：

1. 常量整数、变量引用、二元加法表达式。
2. 局部变量声明（当前采用 LLVM 前端常见的 `alloca/load/store` 内存模型）。
3. `return` 语句。
4. 单函数 `main` 的最小流程。


说明：当前阶段变量统一采用内存模型：先 `alloca` 分配栈槽，再通过 `store/load` 读写。即使变量由常量初始化（如 `int a = 1;`），也会先 `store` 到栈槽，而不是直接把变量替换成 SSA 值。后续实验中，同学可按需求再重构。

此外，当前 IR 还维护了最基本的 use-def 关系：每个 `Value` 会记录哪些 `Instruction` 使用了它。  
这对后续做数据流分析、死代码删除、常量传播等优化会很有帮助；但目前相关实现，接口仍不完整，后续实验中还需要同学继续补充和完善。

## 6. 构建与运行

```bash
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j "$(nproc)"
```

## 7. Lab2 验证方式

项目编译后按提供测试输入回归：

```bash
./build/bin/compiler --emit-ir test/test_case/simple_add.sy
```

如需打印语法树：

```bash
./build/bin/compiler --emit-parse-tree test/test_case/simple_add.sy
```

推荐使用统一脚本验证 “IR -> LLVM 后端 -> 可执行程序” 整体链路，用于验证 IR 的正确性：


```bash
./scripts/verify_ir.sh test/test_case/simple_add.sy test/test_result/ir --run
```
