diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/ExpressionBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/ExpressionBuilder.java
new file mode 100644
index 0000000..1d8f1fd
--- /dev/null
+++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/ExpressionBuilder.java
@@ -0,0 +1,88 @@
+package org.jcnc.snow.compiler.ir.builder;
+
+import org.jcnc.snow.compiler.ir.core.IROp;
+import org.jcnc.snow.compiler.ir.value.VirtualRegister;
+import org.jcnc.snow.compiler.parser.ast.BinaryExpressionNode;
+import org.jcnc.snow.compiler.parser.ast.IdentifierNode;
+import org.jcnc.snow.compiler.parser.ast.NumberLiteralNode;
+import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
+
+import java.util.Map;
+
+/**
+ * ExpressionBuilder 负责将 AST 中的 ExpressionNode 构建为 IR 指令,并返回结果寄存器。
+ *
+ * 功能:
+ *
+ * - 处理数字字面量节点,生成加载常量指令;
+ * - 处理标识符节点,从作用域获取对应的虚拟寄存器;
+ * - 处理二元表达式节点,递归构建左右操作数并生成二元运算指令;
+ *
+ */
+public class ExpressionBuilder {
+ /**
+ * 操作符到 IR 操作码的映射表
+ */
+ private static final Map OP_MAP = Map.of(
+ "+", IROp.ADD_I32,
+ "-", IROp.SUB_I32,
+ "*", IROp.MUL_I32,
+ "/", IROp.DIV_I32
+ );
+
+ /**
+ * 当前 IR 构建上下文,包含 IRFunction 和 Scope
+ */
+ private final IRContext ctx;
+
+ /**
+ * 构造方法,注入 IRContext
+ *
+ * @param ctx 构建 IR 所需上下文,管理函数、作用域和指令添加
+ */
+ public ExpressionBuilder(IRContext ctx) {
+ this.ctx = ctx;
+ }
+
+ /**
+ * 将给定的表达式节点转换为 IR,并返回存放结果的虚拟寄存器。
+ *
+ * @param expr 要构建的表达式节点
+ * @return 存放表达式计算结果的虚拟寄存器
+ * @throws IllegalStateException 若遇到不支持的表达式节点或未定义变量
+ */
+ public VirtualRegister build(ExpressionNode expr) {
+ // 处理数字常量
+ if (expr instanceof NumberLiteralNode(String value)) {
+ int v = Integer.parseInt(value);
+ // 生成加载常量指令并返回结果寄存器
+ return InstrFactory.loadConst(ctx, v);
+ }
+ // 处理变量引用
+ if (expr instanceof IdentifierNode(String name)) {
+ // 从作用域查找已声明的寄存器
+ VirtualRegister vr = ctx.getScope().lookup(name);
+ if (vr == null) {
+ throw new IllegalStateException("未定义的变量: " + name);
+ }
+ return vr;
+ }
+ // 处理二元表达式
+ if (expr instanceof BinaryExpressionNode(ExpressionNode left, String operator, ExpressionNode right)) {
+ // 递归构建左、右子表达式
+ VirtualRegister l = build(left);
+ VirtualRegister r = build(right);
+ // 根据操作符获取 IR 操作码
+ IROp op = OP_MAP.get(operator);
+ if (op == null) {
+ throw new IllegalStateException("不支持的运算符: " + operator);
+ }
+ // 生成二元运算指令并返回结果寄存器
+ return InstrFactory.binOp(ctx, op, l, r);
+ }
+ // 其他表达式类型暂不支持
+ throw new IllegalStateException(
+ "不支持的表达式类型: " + expr.getClass().getSimpleName()
+ );
+ }
+}
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/FunctionBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/FunctionBuilder.java
index 25f6efe..7487aa4 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/builder/FunctionBuilder.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/FunctionBuilder.java
@@ -1,145 +1,46 @@
package org.jcnc.snow.compiler.ir.builder;
import org.jcnc.snow.compiler.ir.core.IRFunction;
-import org.jcnc.snow.compiler.ir.core.IROp;
-import org.jcnc.snow.compiler.ir.instr.BinOpInstruction;
-import org.jcnc.snow.compiler.ir.instr.LoadConstInstruction;
-import org.jcnc.snow.compiler.ir.instr.ReturnInstruction;
-import org.jcnc.snow.compiler.ir.value.Constant;
-import org.jcnc.snow.compiler.ir.value.VirtualRegister;
-import org.jcnc.snow.compiler.parser.ast.*;
-import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
+import org.jcnc.snow.compiler.parser.ast.FunctionNode;
+import org.jcnc.snow.compiler.parser.ast.ParameterNode;
import org.jcnc.snow.compiler.parser.ast.base.StatementNode;
-
/**
- * FunctionBuilder 负责将 AST 中的 FunctionNode 构建为 IRFunction。
+ * FunctionBuilder 负责将 AST 中的 FunctionNode 构建为可执行的 IRFunction。
*
* 构建流程:
*
- * - 创建 IRFunction 并绑定到作用域;
- * - 将函数参数声明为虚拟寄存器;
- * - 遍历函数体中的语句,生成对应的 IR 指令。
+ * - 创建 IRFunction 实例并初始化 IRContext;
+ * - 将函数签名中的参数声明为虚拟寄存器;
+ * - 遍历函数体中的每个语句节点,通过 StatementBuilder 生成对应 IR 指令;
+ * - 最终返回构建完成的 IRFunction 对象。
*
*/
-final class FunctionBuilder {
-
- /** 当前正在构建的 IRFunction 实例 */
- private IRFunction irFunction;
-
- /** 管理变量名到虚拟寄存器的映射 */
- private final Scope scope = new Scope();
+public class FunctionBuilder {
/**
- * 将给定的 FunctionNode 转换为 IRFunction。
+ * 构建函数的 IR 表示
*
- * @param functionNode 要转换的函数节点
- * @return 构建完成的 IRFunction
+ * @param fn 要构建的函数 AST 节点
+ * @return 构建完成的 IRFunction 对象
*/
- IRFunction build(FunctionNode functionNode) {
- irFunction = new IRFunction(functionNode.name());
- scope.attachFunction(irFunction);
- for (ParameterNode p : functionNode.parameters()) {
- scope.declare(p.name());
+ public IRFunction build(FunctionNode fn) {
+ // 创建 IRFunction 并包装到上下文
+ IRFunction irFunc = new IRFunction(fn.name());
+ IRContext ctx = new IRContext(irFunc);
+
+ // 声明函数参数
+ for (ParameterNode p : fn.parameters()) {
+ // 在当前作用域中声明参数名称对应的虚拟寄存器
+ ctx.getScope().declare(p.name());
}
- for (StatementNode s : functionNode.body()) {
- stmt(s);
+
+ // 使用 StatementBuilder 遍历并生成函数体所有语句的 IR
+ StatementBuilder sb = new StatementBuilder(ctx);
+ for (StatementNode s : fn.body()) {
+ sb.build(s);
}
- return irFunction;
+
+ // 返回构建好的 IRFunction
+ return irFunc;
}
-
- /**
- * 处理不同类型的语句节点,并生成相应的 IR 指令。
- *
- * @param s 要处理的语句节点
- */
- private void stmt(StatementNode s) {
- switch (s) {
- case ExpressionStatementNode(ExpressionNode expression) ->
- // 处理表达式语句,无需保存结果
- expr(expression);
- case AssignmentNode(String variable, ExpressionNode value) -> {
- // 处理赋值语句:计算右侧表达式并赋值
- VirtualRegister result = expr(value);
- if (scope.lookup(variable) == null) {
- scope.declare(variable, result);
- } else {
- scope.put(variable, result);
- }
- }
- case DeclarationNode d -> {
- // 处理声明语句,可能带初始化
- if (d.getInitializer().isPresent()) {
- scope.declare(d.getName(), expr(d.getInitializer().get()));
- } else {
- scope.declare(d.getName());
- }
- }
- case ReturnNode r -> {
- // 处理返回语句,区分是否带返回值
- if (r.getExpression().isPresent()) {
- irFunction.add(new ReturnInstruction(expr(r.getExpression().get())));
- } else {
- irFunction.add(new ReturnInstruction(null));
- }
- }
- case null, default -> throw new IllegalStateException("Unsupported statement: " + s);
- }
- }
-
- /**
- * 根据表达式类型生成对应的 IR 值,并返回结果寄存器。
- *
- * @param e 要处理的表达式节点
- * @return 存放表达式结果的虚拟寄存器
- */
- private VirtualRegister expr(ExpressionNode e) {
- if (e instanceof NumberLiteralNode num) {
- return number(num);
- } else if (e instanceof IdentifierNode(String name)) {
- // 处理变量引用,从作用域获取寄存器
- VirtualRegister vr = scope.lookup(name);
- if (vr == null) {
- throw new IllegalStateException("Undefined variable " + name);
- }
- return vr;
- } else if (e instanceof BinaryExpressionNode bin) {
- return bin(bin);
- }
- throw new IllegalStateException("Unsupported expression: " + e);
- }
-
- /**
- * 生成加载数值常量的指令。
- *
- * @param n 数字字面量节点
- * @return 存放常量的虚拟寄存器
- */
- private VirtualRegister number(NumberLiteralNode n) {
- VirtualRegister vr = irFunction.newRegister();
- irFunction.add(new LoadConstInstruction(vr, new Constant(Integer.parseInt(n.value()))));
- return vr;
- }
-
- /**
- * 生成二元运算指令,并返回结果寄存器。
- *
- * @param b 二元表达式节点
- * @return 存放运算结果的虚拟寄存器
- */
- private VirtualRegister bin(BinaryExpressionNode b) {
- VirtualRegister l = expr(b.left());
- VirtualRegister r = expr(b.right());
- VirtualRegister d = irFunction.newRegister();
-
- IROp op = switch (b.operator()) {
- case "+" -> IROp.ADD_I32;
- case "-" -> IROp.SUB_I32;
- case "*" -> IROp.MUL_I32;
- case "/" -> IROp.DIV_I32;
- default -> throw new IllegalStateException("Unknown operator " + b.operator());
- };
-
- irFunction.add(new BinOpInstruction(op, d, l, r));
- return d;
- }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/IRContext.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/IRContext.java
new file mode 100644
index 0000000..866de5f
--- /dev/null
+++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/IRContext.java
@@ -0,0 +1,78 @@
+package org.jcnc.snow.compiler.ir.builder;
+
+import org.jcnc.snow.compiler.ir.core.IRFunction;
+import org.jcnc.snow.compiler.ir.core.IRInstruction;
+import org.jcnc.snow.compiler.parser.ast.*;
+import org.jcnc.snow.compiler.ir.value.VirtualRegister;
+
+/**
+ * IRContext 封装了当前函数的 IRFunction 实例和作用域管理(Scope),
+ * 并提供分配寄存器和添加 IR 指令的便利方法。
+ *
+ * 主要功能:
+ *
+ * - 持有正在构建的 IRFunction 对象;
+ * - 管理变量名到虚拟寄存器的映射作用域;
+ * - 分配新的虚拟寄存器;
+ * - 将生成的 IRInstruction 自动添加到 IRFunction。
+ *
+ */
+public class IRContext {
+ /**
+ * 正在构建的 IRFunction 对象
+ */
+ private final IRFunction function;
+ /**
+ * 管理变量和寄存器映射的作用域
+ */
+ private final Scope scope;
+
+ /**
+ * 构造 IRContext,并绑定要构建的 IRFunction。
+ *
+ * @param function 要构建的 IRFunction 对象
+ */
+ public IRContext(IRFunction function) {
+ this.function = function;
+ this.scope = new Scope();
+ // 将 IRFunction 与作用域关联,以便指令生成时使用
+ this.scope.attachFunction(function);
+ }
+
+ /**
+ * 获取当前 IRFunction。
+ *
+ * @return 当前正在构建的 IRFunction 对象
+ */
+ public IRFunction getFunction() {
+ return function;
+ }
+
+ /**
+ * 获取当前作用域,用于变量声明和查找。
+ *
+ * @return 作用域对象 Scope
+ */
+ /* 包内可见:仅在 builder 包内部使用 Scope */
+ Scope getScope() {
+ return scope;
+ }
+
+ /**
+ * 分配一个新的虚拟寄存器。
+ *
+ * @return 新分配的 VirtualRegister 对象
+ */
+ public VirtualRegister newRegister() {
+ return function.newRegister();
+ }
+
+ /**
+ * 将给定的 IRInstruction 添加到 IRFunction 中。
+ *
+ * @param instr 要添加的 IR 指令
+ */
+ public void addInstruction(IRInstruction instr) {
+ function.add(instr);
+ }
+}
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/InstrFactory.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/InstrFactory.java
new file mode 100644
index 0000000..12479bc
--- /dev/null
+++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/InstrFactory.java
@@ -0,0 +1,72 @@
+package org.jcnc.snow.compiler.ir.builder;
+
+import org.jcnc.snow.compiler.ir.core.IROp;
+import org.jcnc.snow.compiler.ir.instr.BinOpInstruction;
+import org.jcnc.snow.compiler.ir.instr.LoadConstInstruction;
+import org.jcnc.snow.compiler.ir.instr.ReturnInstruction;
+import org.jcnc.snow.compiler.ir.value.Constant;
+import org.jcnc.snow.compiler.ir.value.VirtualRegister;
+
+/**
+ * InstrFactory 统一管理 IR 指令的创建,并自动将生成的指令添加到上下文中。
+ *
+ * 提供的功能包括:
+ *
+ * - 生成加载常量指令(LoadConstInstruction);
+ * - 生成二元运算指令(BinOpInstruction);
+ * - 生成返回指令(ReturnInstruction),支持有返回值和无返回值两种情况;
+ *
+ */
+public class InstrFactory {
+
+ /**
+ * 生成加载整数常量的指令,并返回对应的结果寄存器。
+ *
+ * @param ctx 当前 IR 构建上下文
+ * @param value 要加载的整数值
+ * @return 存放常量的虚拟寄存器
+ */
+ public static VirtualRegister loadConst(IRContext ctx, int value) {
+ VirtualRegister vr = ctx.newRegister();
+ LoadConstInstruction instr = new LoadConstInstruction(vr, new Constant(value));
+ ctx.addInstruction(instr);
+ return vr;
+ }
+
+ /**
+ * 生成二元运算指令,并返回运算结果寄存器。
+ *
+ * @param ctx 当前 IR 构建上下文
+ * @param op 要执行的 IR 运算符
+ * @param left 左操作数寄存器
+ * @param right 右操作数寄存器
+ * @return 存放运算结果的虚拟寄存器
+ */
+ public static VirtualRegister binOp(IRContext ctx, IROp op,
+ VirtualRegister left,
+ VirtualRegister right) {
+ VirtualRegister dest = ctx.newRegister();
+ BinOpInstruction instr = new BinOpInstruction(op, dest, left, right);
+ ctx.addInstruction(instr);
+ return dest;
+ }
+
+ /**
+ * 生成带返回值的返回指令。
+ *
+ * @param ctx 当前 IR 构建上下文
+ * @param value 需要返回的虚拟寄存器
+ */
+ public static void ret(IRContext ctx, VirtualRegister value) {
+ ctx.addInstruction(new ReturnInstruction(value));
+ }
+
+ /**
+ * 生成无返回值的返回指令。
+ *
+ * @param ctx 当前 IR 构建上下文
+ */
+ public static void retVoid(IRContext ctx) {
+ ctx.addInstruction(new ReturnInstruction(null));
+ }
+}
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java
new file mode 100644
index 0000000..b1fa215
--- /dev/null
+++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java
@@ -0,0 +1,57 @@
+package org.jcnc.snow.compiler.ir.builder;
+
+import org.jcnc.snow.compiler.ir.value.VirtualRegister;
+import org.jcnc.snow.compiler.parser.ast.AssignmentNode;
+import org.jcnc.snow.compiler.parser.ast.DeclarationNode;
+import org.jcnc.snow.compiler.parser.ast.ExpressionStatementNode;
+import org.jcnc.snow.compiler.parser.ast.ReturnNode;
+import org.jcnc.snow.compiler.parser.ast.base.StatementNode;
+
+/**
+ * 负责语句节点到 IR 的转换。
+ */
+public class StatementBuilder {
+ private final IRContext ctx;
+ private final ExpressionBuilder exprBuilder;
+
+ public StatementBuilder(IRContext ctx) {
+ this.ctx = ctx;
+ this.exprBuilder = new ExpressionBuilder(ctx);
+ }
+
+ /** 入口:根据不同语句类型分发 */
+ public void build(StatementNode stmt) {
+ if (stmt instanceof ExpressionStatementNode es) {
+ exprBuilder.build(es.expression());
+ return;
+ }
+ if (stmt instanceof AssignmentNode an) {
+ VirtualRegister vr = exprBuilder.build(an.value());
+ if (ctx.getScope().lookup(an.variable()) == null) {
+ ctx.getScope().declare(an.variable(), vr);
+ } else {
+ ctx.getScope().put(an.variable(), vr);
+ }
+ return;
+ }
+ if (stmt instanceof DeclarationNode dn) {
+ if (dn.getInitializer().isPresent()) {
+ VirtualRegister init = exprBuilder.build(dn.getInitializer().get());
+ ctx.getScope().declare(dn.getName(), init);
+ } else {
+ ctx.getScope().declare(dn.getName());
+ }
+ return;
+ }
+ if (stmt instanceof ReturnNode rn) {
+ if (rn.getExpression().isPresent()) {
+ VirtualRegister vr = exprBuilder.build(rn.getExpression().get());
+ InstrFactory.ret(ctx, vr);
+ } else {
+ InstrFactory.retVoid(ctx);
+ }
+ return;
+ }
+ throw new IllegalStateException("Unsupported statement: " + stmt.getClass().getSimpleName());
+ }
+}