diff --git a/src/main/java/org/jcnc/snow/compiler/backend/generator/CmpJumpGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/generator/CmpJumpGenerator.java
index 0f10d64..96cfaa7 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/generator/CmpJumpGenerator.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/generator/CmpJumpGenerator.java
@@ -10,18 +10,26 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.Map;
/**
- * 条件比较跳转指令生成器
+ * 条件比较跳转指令生成器
*
- * 该类实现了 {@link InstructionGenerator} 接口,用于将 IR 中的条件比较跳转指令
- * 转换为虚拟机可执行的指令序列。主要流程是先将比较操作数加载到虚拟机栈中,生成比较操作码,
- * 并发出跳转到目标标签的指令。
+ * 该类实现了 {@link InstructionGenerator} 接口,
+ * 负责将 IR 中的 {@link IRCompareJumpInstruction}(条件比较并跳转指令)
+ * 转换为目标虚拟机(VM)可执行的指令序列。
+ *
+ *
+ * 主要功能
+ *
+ * - 根据 IR 比较指令左右操作数的类型,自动进行类型提升与转换
+ * - 生成相应的 VM 加载、类型转换、比较与跳转指令
+ * - 保证指令的类型前缀与操作数类型一致,提升兼容性与正确性
+ *
*/
public class CmpJumpGenerator implements InstructionGenerator {
/**
- * 返回该生成器所支持的指令类型。
+ * 返回本生成器支持的 IR 指令类型。
*
- * @return {@link IRCompareJumpInstruction} 的类对象
+ * @return IRCompareJumpInstruction 的类对象
*/
@Override
public Class supportedClass() {
@@ -29,7 +37,19 @@ public class CmpJumpGenerator implements InstructionGenerator类型宽度优先级:D > F > L > I > S > B
+ *
+ * - D(double):6
+ * - F(float):5
+ * - L(long):4
+ * - I(int):3
+ * - S(short):2
+ * - B(byte):1
+ * - 未识别类型:0
+ *
+ *
+ * @param p 类型标记字符
+ * @return 优先级数值(越大类型越宽)
*/
private static int rank(char p) {
return switch (p) {
@@ -39,27 +59,40 @@ public class CmpJumpGenerator implements InstructionGenerator 3;
case 'S' -> 2;
case 'B' -> 1;
- default -> 0;
+ default -> 0;
};
}
/**
- * 返回优先级更高的类型字符
+ * 返回更“宽”的公共类型(即优先级高的类型)。
+ *
+ * @param a 类型标记字符 1
+ * @param b 类型标记字符 2
+ * @return 宽度更高的类型标记字符
*/
private static char promote(char a, char b) {
return rank(a) >= rank(b) ? a : b;
}
/**
- * 单字符转字符串
+ * 单字符类型标记转字符串。
+ *
+ * @param p 类型标记字符
+ * @return 类型字符串
*/
private static String str(char p) {
return String.valueOf(p);
}
/**
- * 获取从类型 {@code from} 到 {@code to} 的转换指令名。
- * 相同类型或无显式转换需求返回 {@code null}。
+ * 获取 {@code from → to} 的类型转换指令名(如不需转换则返回 {@code null})。
+ *
+ * 仅覆盖目前常见的整数与浮点类型提升与转换,后续有新类型可补充。
+ *
+ *
+ * @param from 源类型标记字符
+ * @param to 目标类型标记字符
+ * @return 转换指令名,如“L2I”;无转换返回 {@code null}
*/
private static String convert(char from, char to) {
if (from == to) return null;
@@ -78,46 +111,64 @@ public class CmpJumpGenerator implements InstructionGenerator "D2F";
case "SI" -> "S2I";
case "BI" -> "B2I";
- default -> null;
+ default -> null;
};
}
/**
- * 生成条件比较跳转相关的虚拟机指令。
+ * 生成 IR 条件比较跳转指令的 VM 指令序列。
+ *
+ * - 确定左右操作数的槽位及静态类型
+ * - 加载并按需类型提升转换
+ * - 根据公共类型调整比较指令前缀
+ * - 发出最终比较和跳转指令
+ *
*
- * @param ins 需要生成的条件比较跳转中间指令(IR)
- * @param out 虚拟机程序构建器,用于输出生成的指令
- * @param slotMap 虚拟寄存器到实际槽(slot)编号的映射表
- * @param currentFn 当前处理的函数名(可用于调试或作用域标识)
+ * @param ins IR 条件比较跳转指令
+ * @param out VMProgramBuilder:用于发出 VM 指令
+ * @param slotMap 虚拟寄存器到 VM 槽位的映射表
+ * @param currentFn 当前处理的函数名(调试用,当前未使用)
*/
@Override
- public void generate(IRCompareJumpInstruction ins,
- VMProgramBuilder out,
- Map slotMap,
- String currentFn) {
- // 获取左操作数所在的寄存器槽编号
- int leftSlot = slotMap.get(ins.left());
- // 获取右操作数所在的寄存器槽编号
- int rightSlot = slotMap.get(ins.right());
+ public void generate(IRCompareJumpInstruction ins,
+ VMProgramBuilder out,
+ Map slotMap,
+ String currentFn) {
- char lType = out.getSlotType(leftSlot); // 未登记默认 'I'
- char rType = out.getSlotType(rightSlot);
+ // 1. 获取左右操作数的槽位与静态类型
+ int leftSlot = slotMap.get(ins.left());
+ int rightSlot = slotMap.get(ins.right());
+ char lType = out.getSlotType(leftSlot); // 若未登记则默认 'I'
+ char rType = out.getSlotType(rightSlot);
+ char tType = promote(lType, rType); // 公共类型提升
- char tType = promote(lType, rType); // 类型提升结果
-
- // 加载左操作数到虚拟机栈
+ // 2. 加载左右操作数并按需类型转换
+ // 左操作数
out.emit(OpHelper.opcode(str(lType) + "_LOAD") + " " + leftSlot);
String cvt = convert(lType, tType);
- if (cvt != null) out.emit(OpHelper.opcode(cvt));
+ if (cvt != null) {
+ out.emit(OpHelper.opcode(cvt));
+ }
- // 加载右操作数到虚拟机栈
+ // 右操作数
out.emit(OpHelper.opcode(str(rType) + "_LOAD") + " " + rightSlot);
cvt = convert(rType, tType);
- if (cvt != null) out.emit(OpHelper.opcode(cvt));
+ if (cvt != null) {
+ out.emit(OpHelper.opcode(cvt));
+ }
- // 获取与当前比较操作对应的虚拟机操作码
+ // 3. 选择正确的比较指令前缀
String cmpOp = IROpCodeMapper.toVMOp(ins.op());
- // 生成分支跳转指令,如果比较成立则跳转到目标标签
+ /*
+ * 修正指令前缀(如 int 类型要用 IC_*, long 类型要用 LC_*)
+ */
+ if (tType == 'I' && cmpOp.startsWith("LC_")) {
+ cmpOp = "IC_" + cmpOp.substring(3);
+ } else if (tType == 'L' && cmpOp.startsWith("IC_")) {
+ cmpOp = "LC_" + cmpOp.substring(3);
+ }
+
+ // 4. 发出比较与跳转指令
out.emitBranch(OpHelper.opcode(cmpOp), ins.label());
}
}