diff --git a/src/main/java/org/jcnc/snow/compiler/ir/utils/ComparisonUtils.java b/src/main/java/org/jcnc/snow/compiler/ir/utils/ComparisonUtils.java index 7d2141a..2cf8828 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/utils/ComparisonUtils.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/utils/ComparisonUtils.java @@ -10,36 +10,46 @@ import org.jcnc.snow.compiler.parser.ast.base.NodeContext; import java.util.Map; /** - * 比较运算辅助工具: - * 根据左右操作数类型(目前通过字面量后缀 L/l 判定)选择 - * 正确的 IR 比较指令,保证 int/long 均能正常运行。 + * 工具类,用于比较运算相关的类型推断和指令选择。 + *

+ * 该类主要用于根据左右操作数的静态类型,自动选择正确的 IR 层比较操作码。 + * 支持自动类型提升,保证 int、long、float、double 等类型的比较均能得到正确的 IR 指令。 + *

+ * + * 类型判定支持: + * */ public final class ComparisonUtils { - private ComparisonUtils() { - } + private ComparisonUtils() {} /** - * 判断给定操作符是否为比较运算符 + * 判断给定字符串是否为受支持的比较运算符(==, !=, <, >, <=, >=)。 + * 仅检查 int 类型指令表,因所有类型的比较符号集合相同。 + * + * @param op 比较运算符字符串 + * @return 若为比较运算符返回 true,否则返回 false */ public static boolean isComparisonOperator(String op) { - // 两张表 key 完全一致,只需检查一张 + // 只需查 int 类型表即可 return IROpCodeMappings.CMP_I32.containsKey(op); } /** - * 类型宽度优先级: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 优先级数值(越大类型越宽) + * @return 类型优先级数值 */ private static int rank(char p) { return switch (p) { @@ -54,23 +64,28 @@ public final class ComparisonUtils { } /** - * 返回更“宽”的公共类型(即优先级高的类型)。 + * 返回两个类型中较“宽”的类型(即优先级较高的类型)。 + * 若优先级相等,返回第一个参数的类型。 * - * @param a 类型标记字符 1 - * @param b 类型标记字符 2 - * @return 宽度更高的类型标记字符 + * @param a 类型标记字符1 + * @param b 类型标记字符2 + * @return 宽度更高的类型字符 */ public static char promote(char a, char b) { return rank(a) >= rank(b) ? a : b; } /** - * 返回符合操作数位宽的比较 IROpCode。 + * 根据变量类型映射和操作数表达式,推断操作数类型, + * 并自动类型提升后,选择正确的比较操作码(IROpCode)。 + * 若未能推断类型或操作符不受支持,会抛出异常。 * - * @param variables 变量->类型的映射 + * @param variables 变量名到类型的映射(如 "a" -> "int") * @param op 比较符号(==, !=, <, >, <=, >=) - * @param left 左操作数 AST - * @param right 右操作数 AST + * @param left 左操作数表达式 + * @param right 右操作数表达式 + * @return 适用的比较 IROpCode + * @throws IllegalStateException 如果无法推断合适的类型 */ public static IROpCode cmpOp(Map variables, String op, ExpressionNode left, ExpressionNode right) { char typeLeft = analysisType(variables, left); @@ -84,14 +99,21 @@ public final class ComparisonUtils { case 'L' -> IROpCodeMappings.CMP_L64; case 'F' -> IROpCodeMappings.CMP_F32; case 'D' -> IROpCodeMappings.CMP_D64; - default -> throw new IllegalStateException("意外的值: " + type); + default -> throw new IllegalStateException("Unexpected value: " + type); }; return table.get(op); } - /* ------------ 内部工具 ------------ */ - + /** + * 内部工具方法:根据表达式节点和变量表推断类型标记字符。 + * 字面量支持 B/S/I/L/F/D(大小写均可),浮点数默认 double; + * 标识符类型按变量表映射,未知则默认 int。 + * + * @param variables 变量名到类型的映射 + * @param node 表达式节点 + * @return 类型标记字符(B/S/I/L/F/D),未知时返回 I + */ private static char analysisType(Map variables, ExpressionNode node) { if (node instanceof NumberLiteralNode(String value, NodeContext _)) { char suffix = Character.toUpperCase(value.charAt(value.length() - 1)); @@ -101,33 +123,21 @@ public final class ComparisonUtils { if (value.indexOf('.') != -1) { return 'D'; } - - return 'I'; // 默认为 'I' + return 'I'; // 默认 int } if (node instanceof IdentifierNode(String name, NodeContext _)) { final String type = variables.get(name); - switch (type) { - case "byte" -> { - return 'B'; - } - case "short" -> { - return 'S'; - } - case "int" -> { - return 'I'; - } - case "long" -> { - return 'L'; - } - case "float" -> { - return 'F'; - } - case "double" -> { - return 'D'; + if (type != null) { + switch (type) { + case "byte": return 'B'; + case "short": return 'S'; + case "int": return 'I'; + case "long": return 'L'; + case "float": return 'F'; + case "double": return 'D'; } } } - - return 'I'; // 默认为 'I' + return 'I'; // 默认 int } }