feat: 条件表达式支持类型提升

This commit is contained in:
zhangxun 2025-06-16 23:06:57 +08:00 committed by Luke
parent 7bd795b796
commit e78cb09c0f

View File

@ -28,6 +28,60 @@ public class CmpJumpGenerator implements InstructionGenerator<IRCompareJumpInstr
return IRCompareJumpInstruction.class;
}
/**
* 类型优先级D &gt; F &gt; L &gt; I &gt; S &gt; B
*/
private static int rank(char p) {
return switch (p) {
case 'D' -> 6;
case 'F' -> 5;
case 'L' -> 4;
case 'I' -> 3;
case 'S' -> 2;
case 'B' -> 1;
default -> 0;
};
}
/**
* 返回优先级更高的类型字符
*/
private static char promote(char a, char b) {
return rank(a) >= rank(b) ? a : b;
}
/**
* 单字符转字符串
*/
private static String str(char p) {
return String.valueOf(p);
}
/**
* 获取从类型 {@code from} {@code to} 的转换指令名
* 相同类型或无显式转换需求返回 {@code null}
*/
private static String convert(char from, char to) {
if (from == to) return null;
return switch ("" + from + to) {
case "IL" -> "I2L";
case "ID" -> "I2D";
case "IF" -> "I2F";
case "LI" -> "L2I";
case "LD" -> "L2D";
case "LF" -> "L2F";
case "FI" -> "F2I";
case "FL" -> "F2L";
case "FD" -> "F2D";
case "DI" -> "D2I";
case "DL" -> "D2L";
case "DF" -> "D2F";
case "SI" -> "S2I";
case "BI" -> "B2I";
default -> null;
};
}
/**
* 生成条件比较跳转相关的虚拟机指令
*
@ -45,10 +99,22 @@ public class CmpJumpGenerator implements InstructionGenerator<IRCompareJumpInstr
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); // 类型提升结果
// 加载左操作数到虚拟机栈
out.emit(OpHelper.opcode("L_LOAD") + " " + leftSlot);
out.emit(OpHelper.opcode(str(lType) + "_LOAD") + " " + leftSlot);
String cvt = convert(lType, tType);
if (cvt != null) out.emit(OpHelper.opcode(cvt));
// 加载右操作数到虚拟机栈
out.emit(OpHelper.opcode("L_LOAD") + " " + rightSlot);
out.emit(OpHelper.opcode(str(rType) + "_LOAD") + " " + rightSlot);
cvt = convert(rType, tType);
if (cvt != null) out.emit(OpHelper.opcode(cvt));
// 获取与当前比较操作对应的虚拟机操作码
String cmpOp = IROpCodeMapper.toVMOp(ins.op());
// 生成分支跳转指令如果比较成立则跳转到目标标签