diff --git a/src/main/java/org/jcnc/snow/compiler/backend/IROpCodeMapper.java b/src/main/java/org/jcnc/snow/compiler/backend/IROpCodeMapper.java
index c6cb9e4..c1a21b8 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/IROpCodeMapper.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/IROpCodeMapper.java
@@ -6,65 +6,65 @@ import java.util.EnumMap;
import java.util.Map;
/**
- * IROpCodeMapper —— IR 操作码(IROpCode)到 VM 虚拟机操作码(字符串形式)的映射器。
+ * 提供 IR 操作码({@link IROpCode})到虚拟机指令名({@code String})的一一映射工具类。
*
- * 本类用于编译器后端阶段,将中间表示中的操作类型(如 ADD_I32)转换为
- * 虚拟机指令集中的具体指令(如 "I_ADD"),用于代码生成输出。
+ * 本类在编译器后端负责将中间表示中的操作码转换为对应的 VM 指令,用于最终的代码生成。
+ * 不负责操作数或参数传递的逻辑,仅做纯映射处理。
*
*
- * 注意:该类只做一一映射,不处理操作数或参数传递逻辑。
- * 若未来有更多数据类型或扩展语义,可在此处集中管理。
+ * 如需扩展更多操作码或新增指令语义,可在此集中管理映射关系。
*
*/
public final class IROpCodeMapper {
- /** 存储映射关系的枚举映射表(使用 EnumMap 提高性能) */
+ /**
+ * IR 操作码到 VM 指令名的映射表,基于 {@code EnumMap} 实现以提升性能。
+ */
private static final Map opcodeMap = new EnumMap<>(IROpCode.class);
- // 初始化静态映射表
static {
- // ───── 算术运算 ─────
- opcodeMap.put(IROpCode.ADD_I32, "I_ADD");
- opcodeMap.put(IROpCode.SUB_I32, "I_SUB");
- opcodeMap.put(IROpCode.MUL_I32, "I_MUL");
- opcodeMap.put(IROpCode.DIV_I32, "I_DIV");
- opcodeMap.put(IROpCode.NEG_I32, "I_NEG");
+ opcodeMap.put(IROpCode.ADD_I32, "I_ADD");
+ opcodeMap.put(IROpCode.SUB_I32, "I_SUB");
+ opcodeMap.put(IROpCode.MUL_I32, "I_MUL");
+ opcodeMap.put(IROpCode.DIV_I32, "I_DIV");
+ opcodeMap.put(IROpCode.NEG_I32, "I_NEG");
- // ───── 逻辑比较运算 ─────
- opcodeMap.put(IROpCode.CMP_EQ, "IC_EQ");
- opcodeMap.put(IROpCode.CMP_NE, "IC_NE");
- opcodeMap.put(IROpCode.CMP_LT, "IC_L");
- opcodeMap.put(IROpCode.CMP_GT, "IC_G");
- opcodeMap.put(IROpCode.CMP_LE, "IC_LE");
- opcodeMap.put(IROpCode.CMP_GE, "IC_GE");
+ opcodeMap.put(IROpCode.CMP_EQ, "IC_EQ");
+ opcodeMap.put(IROpCode.CMP_NE, "IC_NE");
+ opcodeMap.put(IROpCode.CMP_LT, "IC_L");
+ opcodeMap.put(IROpCode.CMP_GT, "IC_G");
+ opcodeMap.put(IROpCode.CMP_LE, "IC_LE");
+ opcodeMap.put(IROpCode.CMP_GE, "IC_GE");
- // ───── 数据操作 ─────
- opcodeMap.put(IROpCode.LOAD, "I_LOAD");
- opcodeMap.put(IROpCode.STORE, "I_STORE");
- opcodeMap.put(IROpCode.CONST, "I_PUSH");
+ opcodeMap.put(IROpCode.LOAD, "I_LOAD");
+ opcodeMap.put(IROpCode.STORE, "I_STORE");
+ opcodeMap.put(IROpCode.CONST, "I_PUSH");
- // ───── 控制流 ─────
- opcodeMap.put(IROpCode.JUMP, "JMP");
+ opcodeMap.put(IROpCode.JUMP, "JMP");
opcodeMap.put(IROpCode.JUMP_IF_ZERO, "JZ");
- opcodeMap.put(IROpCode.LABEL, "LABEL");
+ opcodeMap.put(IROpCode.LABEL, "LABEL");
- // ───── 函数调用 ─────
- opcodeMap.put(IROpCode.CALL, "CALL");
- opcodeMap.put(IROpCode.RET, "RET");
+ opcodeMap.put(IROpCode.CALL, "CALL");
+ opcodeMap.put(IROpCode.RET, "RET");
}
/**
- * 将给定的 IR 操作码转换为对应的 VM 指令名(字符串)。
+ * 将给定的 IR 操作码转换为对应的 VM 指令名。
*
- * @param irOp IROpCode 中的操作码
- * @return 对应的 VM opcode 字符串
- * @throws IllegalArgumentException 若操作码未被映射
+ * @param irOp 需转换的 IR 操作码
+ * @return 与 IR 操作码对应的 VM 指令名称
+ * @throws IllegalArgumentException 若 {@code irOp} 未在映射表中定义
*/
public static String toVMOp(IROpCode irOp) {
- String code = opcodeMap.get(irOp);
- if (code == null) {
+ String vmCode = opcodeMap.get(irOp);
+ if (vmCode == null) {
throw new IllegalArgumentException("未映射的 IR 操作码: " + irOp);
}
- return code;
+ return vmCode;
+ }
+
+ // 私有构造函数,防止实例化
+ private IROpCodeMapper() {
+ // 不允许实例化
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/RegisterAllocator.java b/src/main/java/org/jcnc/snow/compiler/backend/RegisterAllocator.java
index 738dea3..d02c0eb 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/RegisterAllocator.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/RegisterAllocator.java
@@ -1,52 +1,55 @@
package org.jcnc.snow.compiler.backend;
-import org.jcnc.snow.compiler.ir.core.*;
+import org.jcnc.snow.compiler.ir.core.IRFunction;
+import org.jcnc.snow.compiler.ir.core.IRInstruction;
+import org.jcnc.snow.compiler.ir.core.IRValue;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.HashMap;
import java.util.Map;
/**
- * A very simple linear-scan register allocator.
- *
- * Strategy:
+ * 线性扫描寄存器分配器。
+ *
+ * 分配策略:
*
- * - Assign formal parameters to slots
- * 0 .. n-1 (in declaration order).
- * - Scan the instruction list; every unseen virtual register
- * gets the next free slot number.
+ * - 将函数的形式参数按照声明顺序分配到槽编号 0 到 n-1。
+ * - 随后扫描函数体中的指令列表,每遇到尚未分配槽号的虚拟寄存器,
+ * 即为其分配下一个可用的槽编号。
*
- * No liveness analysis, no spilling – demo-grade only.
*/
public final class RegisterAllocator {
- private final Map map = new HashMap<>();
+ /**
+ * 存储虚拟寄存器到物理槽的映射表。
+ * 键为虚拟寄存器,值为分配的槽编号。
+ */
+ private final Map map = new HashMap<>();
/**
- * Computes a register→slot mapping for the given function.
+ * 为指定的 IR 函数计算寄存器到槽的映射关系。
+ *
+ * 先为函数的形式参数分配槽号,再为函数体中出现的其他虚拟寄存器依次分配。
+ *
*
- * @param fn IRFunction to allocate
- * @return mapping table (immutable)
+ * @param fn 需要进行寄存器分配的中间表示函数
+ * @return 一个不可变的映射表,表示每个虚拟寄存器对应的槽编号
*/
- public Map allocate(IRFunction fn) {
-
+ public Map allocate(IRFunction fn) {
int next = 0;
- /* ---------- 1) parameters first ---------- */
+ // 1. 为形式参数分配槽编号
for (IRVirtualRegister param : fn.parameters()) {
map.put(param, next++);
}
- /* ---------- 2) then all remaining VRegs ---------- */
+ // 2. 扫描函数体,分配其他虚拟寄存器的槽编号
for (IRInstruction inst : fn.body()) {
-
if (inst.dest() != null && !map.containsKey(inst.dest())) {
map.put(inst.dest(), next++);
}
-
- for (IRValue v : inst.operands()) {
- if (v instanceof IRVirtualRegister vr &&
- !map.containsKey(vr)) {
+ for (IRValue operand : inst.operands()) {
+ if (operand instanceof IRVirtualRegister vr && !map.containsKey(vr)) {
map.put(vr, next++);
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java
index 0fb8c7f..d03ba84 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java
@@ -1,50 +1,95 @@
package org.jcnc.snow.compiler.backend;
-import org.jcnc.snow.compiler.ir.core.*;
-import org.jcnc.snow.compiler.ir.instruction.*;
-import org.jcnc.snow.compiler.ir.value.*;
+import org.jcnc.snow.compiler.ir.core.IRFunction;
+import org.jcnc.snow.compiler.ir.core.IRInstruction;
+import org.jcnc.snow.compiler.ir.core.IRValue;
+import org.jcnc.snow.compiler.ir.instruction.BinaryOperationInstruction;
+import org.jcnc.snow.compiler.ir.instruction.CallInstruction;
+import org.jcnc.snow.compiler.ir.instruction.LoadConstInstruction;
+import org.jcnc.snow.compiler.ir.instruction.ReturnInstruction;
+import org.jcnc.snow.compiler.ir.instruction.UnaryOperationInstruction;
+import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
+import org.jcnc.snow.compiler.ir.value.IRConstant;
import org.jcnc.snow.vm.engine.VMOpCode;
import java.lang.reflect.Field;
import java.util.Map;
/**
- * Generates VM code for a single IRFunction.
+ * 为单个 {@link IRFunction} 生成对应的虚拟机指令序列。
+ *
+ * 本类依据中间表示函数的指令列表,调用 {@link VMProgramBuilder} 输出相应的 VM 操作码,
+ * 包括常量加载、算术运算、函数调用和返回等指令生成逻辑。
+ *
*/
public final class VMCodeGenerator {
- private final Map slotMap;
+ /**
+ * 虚拟寄存器到槽编号的映射表,用于确定加载和存储的目标槽。
+ */
+ private final Map slotMap;
+
+ /**
+ * VM 指令输出器,用于构建最终的指令流。
+ */
private final VMProgramBuilder out;
+
+ /**
+ * 当前正在生成代码的函数名称,用于在返回指令处区分主函数与其他函数。
+ */
private String currentFn;
- public VMCodeGenerator(Map slotMap,
+ /**
+ * 构造 VMCodeGenerator 实例。
+ *
+ * @param slotMap 虚拟寄存器与槽编号的映射表
+ * @param out 用于输出 VM 指令的构建器
+ */
+ public VMCodeGenerator(Map slotMap,
VMProgramBuilder out) {
this.slotMap = slotMap;
- this.out = out;
+ this.out = out;
}
+ /**
+ * 为指定的 IR 函数生成完整的 VM 指令流。
+ *
+ * @param fn 目标 IRFunction 实例
+ * @throws IllegalStateException 若遇到不支持的 IR 指令类型
+ */
public void generate(IRFunction fn) {
currentFn = fn.name();
out.beginFunction(currentFn);
- for (IRInstruction inst : fn.body()) switch (inst) {
- case LoadConstInstruction c -> genLoadConst(c);
- case BinaryOperationInstruction b -> genBinOp(b);
- case UnaryOperationInstruction u -> genUnary(u);
- case CallInstruction c -> genCall(c);
- case ReturnInstruction r -> genRet(r);
- default -> throw new IllegalStateException("Unsupported IR: "+inst);
+ for (IRInstruction inst : fn.body()) {
+ switch (inst) {
+ case LoadConstInstruction c -> genLoadConst(c);
+ case BinaryOperationInstruction b -> genBinOp(b);
+ case UnaryOperationInstruction u -> genUnary(u);
+ case CallInstruction c -> genCall(c);
+ case ReturnInstruction r -> genRet(r);
+ default -> throw new IllegalStateException("Unsupported IR: " + inst);
+ }
}
}
- /* ---------- helpers ---------- */
-
+ /**
+ * 生成常量加载指令序列:将常量推入栈并存入目标寄存器槽。
+ *
+ * @param c 常量加载指令
+ */
private void genLoadConst(LoadConstInstruction c) {
- IRConstant k = (IRConstant) c.operands().getFirst();
- emit(op("I_PUSH"), k.value().toString());
+ IRConstant constant = (IRConstant) c.operands().getFirst();
+ emit(op("I_PUSH"), constant.value().toString());
emit(op("I_STORE"), slot(c.dest()));
}
+ /**
+ * 生成二元算术或比较运算指令序列:
+ * 依次加载两个操作数,执行运算,并存回目标寄存器槽。
+ *
+ * @param b 二元操作指令
+ */
private void genBinOp(BinaryOperationInstruction b) {
emit(op("I_LOAD"), slot((IRVirtualRegister) b.operands().get(0)));
emit(op("I_LOAD"), slot((IRVirtualRegister) b.operands().get(1)));
@@ -52,15 +97,24 @@ public final class VMCodeGenerator {
emit(op("I_STORE"), slot(b.dest()));
}
+ /**
+ * 生成一元运算指令序列:加载操作数,执行运算,并存回目标寄存器槽。
+ *
+ * @param u 一元操作指令
+ */
private void genUnary(UnaryOperationInstruction u) {
emit(op("I_LOAD"), slot((IRVirtualRegister) u.operands().getFirst()));
emit(op(IROpCodeMapper.toVMOp(u.op())));
emit(op("I_STORE"), slot(u.dest()));
}
- /** Generates CALL addr nArgs */
+ /**
+ * 生成函数调用指令序列:
+ * 按参数顺序加载每个参数,执行调用,并将返回值存入目标寄存器槽。
+ *
+ * @param c 调用指令
+ */
private void genCall(CallInstruction c) {
- /* push arguments in IR order (already left-to-right) */
for (IRValue arg : c.getArguments()) {
emit(op("I_LOAD"), slot((IRVirtualRegister) arg));
}
@@ -69,28 +123,56 @@ public final class VMCodeGenerator {
emit(op("I_STORE"), slot(c.getDest()));
}
+ /**
+ * 生成返回指令序列:可选地加载返回值,然后根据是否为主函数选择 HALT 或 RET。
+ *
+ * @param r 返回指令
+ */
private void genRet(ReturnInstruction r) {
- if (r.value() != null)
+ if (r.value() != null) {
emit(op("I_LOAD"), slot(r.value()));
- emit("main".equals(currentFn) ? op("HALT") : op("RET"));
+ }
+ String opcode = "main".equals(currentFn) ? op("HALT") : op("RET");
+ out.emit(opcode);
}
+ /**
+ * 构造并输出一条 VM 指令。
+ *
+ * @param opcode 操作码字符串
+ * @param args 可选的操作数字符串列表
+ */
private void emit(String opcode, String... args) {
StringBuilder sb = new StringBuilder(opcode);
- for (String a : args) sb.append(' ').append(a);
+ for (String a : args) {
+ sb.append(' ').append(a);
+ }
out.emit(sb.toString());
}
+ /**
+ * 将虚拟寄存器映射为对应的槽编号字符串。
+ *
+ * @param r 虚拟寄存器
+ * @return 目标槽编号的字符串形式
+ */
private String slot(IRVirtualRegister r) {
return slotMap.get(r).toString();
}
+ /**
+ * 根据 VMOpCode 常量名反射获取对应的操作码字符串。
+ *
+ * @param name VMOpCode 常量字段名
+ * @return 对应的操作码字符串
+ * @throws RuntimeException 若未找到指定操作码字段
+ */
private String op(String name) {
try {
- Field f = VMOpCode.class.getField(name);
- return f.get(null).toString();
+ Field field = VMOpCode.class.getField(name);
+ return field.get(null).toString();
} catch (Exception e) {
- throw new RuntimeException("Unknown opcode: "+name, e);
+ throw new RuntimeException("Unknown opcode: " + name, e);
}
}
}