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 指令。
+ *
+ *
+ * 类型判定支持:
+ *
+ * - 字面量后缀:支持 B/S/I/L/F/D(大小写均可)
+ * - 浮点数支持:如无后缀但有小数点,视为 double
+ * - 变量类型:根据传入变量表推断类型,未识别则默认 int
+ *
*/
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
- *
+ * 返回类型宽度优先级(越大代表类型越宽)。类型对应的优先级:
+ * - 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
}
}