From e66a5a30782341fa6e49f22c90a80ae310f1822a Mon Sep 17 00:00:00 2001 From: zhangxun <1958638841@qq.com> Date: Thu, 10 Jul 2025 17:31:44 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E5=A4=8D=E7=9A=84?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=8F=90=E5=8D=87=E9=80=BB=E8=BE=91=E6=8F=90?= =?UTF-8?q?=E5=8F=96=E5=88=B0=20TypePromoteUtils=20=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/generator/BinaryOpGenerator.java | 72 ++---------- .../backend/generator/CmpJumpGenerator.java | 90 +-------------- .../backend/utils/TypePromoteUtils.java | 105 ++++++++++++++++++ 3 files changed, 122 insertions(+), 145 deletions(-) create mode 100644 src/main/java/org/jcnc/snow/compiler/backend/utils/TypePromoteUtils.java diff --git a/src/main/java/org/jcnc/snow/compiler/backend/generator/BinaryOpGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/generator/BinaryOpGenerator.java index 0d0a983..83c1747 100644 --- a/src/main/java/org/jcnc/snow/compiler/backend/generator/BinaryOpGenerator.java +++ b/src/main/java/org/jcnc/snow/compiler/backend/generator/BinaryOpGenerator.java @@ -4,6 +4,7 @@ import org.jcnc.snow.compiler.backend.builder.VMProgramBuilder; import org.jcnc.snow.compiler.backend.core.InstructionGenerator; import org.jcnc.snow.compiler.backend.utils.IROpCodeMapper; import org.jcnc.snow.compiler.backend.utils.OpHelper; +import org.jcnc.snow.compiler.backend.utils.TypePromoteUtils; import org.jcnc.snow.compiler.ir.core.IRValue; import org.jcnc.snow.compiler.ir.instruction.BinaryOperationInstruction; import org.jcnc.snow.compiler.ir.value.IRConstant; @@ -41,38 +42,12 @@ public class BinaryOpGenerator implements InstructionGenerator 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); - } - /** * 判断常量值是否等于 0。 * 仅支持 Java 原生数值类型。 + * + * @param v 常量值 + * @return 等于 0 返回 true,否则 false */ private static boolean isZero(Object v) { if (v == null) return false; @@ -87,31 +62,6 @@ public class BinaryOpGenerator implements InstructionGenerator "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; - }; - } - /* -------------------- 接口实现 -------------------- */ @Override @@ -161,16 +111,16 @@ public class BinaryOpGenerator 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) { - case 'D' -> 6; - case 'F' -> 5; - case 'L' -> 4; - case 'I' -> 3; - case 'S' -> 2; - case 'B' -> 1; - 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 → to} 的类型转换指令名(如不需转换则返回 {@code null})。 - *

- * 仅覆盖目前常见的整数与浮点类型提升与转换,后续有新类型可补充。 - *

- * - * @param from 源类型标记字符 - * @param to 目标类型标记字符 - * @return 转换指令名,如“L2I”;无转换返回 {@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; - }; - } - /** * 生成 IR 条件比较跳转指令的 VM 指令序列。 *
    @@ -140,19 +62,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) { + case 'D' -> 6; + case 'F' -> 5; + case 'L' -> 4; + case 'I' -> 3; + case 'S' -> 2; + case 'B' -> 1; + default -> 0; + }; + } + + /** + * 返回更“宽”的公共类型(即优先级高的类型)。 + * + * @param a 类型标记字符 1 + * @param b 类型标记字符 2 + * @return 宽度更高的类型标记字符 + */ + public static char promote(char a, char b) { + return rank(a) >= rank(b) ? a : b; + } + + /** + * 单字符类型标记转字符串。 + * + * @param p 类型标记字符 + * @return 类型字符串 + */ + public static String str(char p) { + return String.valueOf(p); + } + + /** + * 获取 {@code from → to} 的类型转换指令名(如不需转换则返回 {@code null})。 + * + * @param from 源类型标记字符 + * @param to 目标类型标记字符 + * @return 转换指令名,如“L2I”;无转换返回 {@code null} + */ + public static String convert(char from, char to) { + if (from == to) return null; + return switch ("" + from + to) { + case "BS" -> "B2S"; + case "BI" -> "B2I"; + case "BL" -> "B2L"; + case "BF" -> "B2F"; + case "BD" -> "B2D"; + + case "SB" -> "S2B"; + case "SI" -> "S2I"; + case "SL" -> "S2L"; + case "SF" -> "S2F"; + case "SD" -> "S2D"; + + case "IB" -> "I2B"; + case "IS" -> "I2S"; + case "IL" -> "I2L"; + case "IF" -> "I2F"; + case "ID" -> "I2D"; + + case "LB" -> "L2B"; + case "LS" -> "L2S"; + case "LI" -> "L2I"; + case "LF" -> "L2F"; + case "LD" -> "L2D"; + + case "FB" -> "F2B"; + case "FS" -> "F2S"; + case "FI" -> "F2I"; + case "FL" -> "F2L"; + case "FD" -> "F2D"; + + case "DB" -> "D2B"; + case "DS" -> "D2S"; + case "DI" -> "D2I"; + case "DL" -> "D2L"; + case "DF" -> "D2F"; + default -> null; + }; + } +}