diff --git a/src/main/java/org/jcnc/snow/compiler/ir/utils/ExpressionUtils.java b/src/main/java/org/jcnc/snow/compiler/ir/utils/ExpressionUtils.java index ba6f663..c12525d 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/utils/ExpressionUtils.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/utils/ExpressionUtils.java @@ -12,33 +12,46 @@ import org.jcnc.snow.compiler.parser.ast.base.NodeContext; import java.util.Map; /** - * 表达式分析与运算符辅助工具类。 - * - *
主要功能:
- *
+ * 主要功能:
+ * - 解析字面量常量,自动推断类型
+ * - 自动匹配并选择适合的算术/比较操作码
+ * - 表达式类型的合并与类型提升
+ * - 支持线程隔离的函数级默认类型后缀
*/
public final class ExpressionUtils {
private ExpressionUtils() {}
- /* ────────────────── 线程级默认类型后缀 ────────────────── */
+ // ───────────── 线程级默认类型后缀 ─────────────
- /** 默认类型后缀(如当前函数返回类型),线程隔离。 */
+ /**
+ * 当前线程的默认类型后缀(如当前函数返回类型等),用于类型推断兜底。
+ */
private static final ThreadLocal
+ * 支持的字面量后缀有 b/s/l/f/d(大小写均可)。
+ * 无后缀时,优先参考 IRContext 当前变量类型,否则根据字面量格式(含'.'或'e'等)判断为 double,否则为 int。
+ *
+ * @param ctx IRContext,允许参考变量声明类型
+ * @param value 数字字面量字符串
+ * @return 对应类型的 IRConstant 常量
*/
public static IRConstant buildNumberConstant(IRContext ctx, String value) {
char suffix = value.isEmpty() ? '\0'
@@ -56,7 +75,7 @@ public final class ExpressionUtils {
String digits = switch (suffix) {
case 'b','s','l','f','d' -> value.substring(0, value.length() - 1);
default -> {
- /* 如果字面量本身没有后缀,则回退到变量目标类型(如声明语句左值) */
+ // 无后缀,优先参考变量类型
if (ctx.getVarType() != null) {
String t = ctx.getVarType();
suffix = switch (t) {
@@ -73,7 +92,7 @@ public final class ExpressionUtils {
}
};
- /* 创建常量 */
+ // 生成常量对象
return switch (suffix) {
case 'b' -> new IRConstant(Byte.parseByte(digits));
case 's' -> new IRConstant(Short.parseShort(digits));
@@ -86,10 +105,13 @@ public final class ExpressionUtils {
};
}
- /* ────────────────────── 一元运算 ────────────────────── */
+ // ───────────── 一元运算指令匹配 ─────────────
/**
- * 推断一元取负(-)运算应使用的 {@link IROpCode}。
+ * 根据表达式节点的类型后缀,选择对应的取负(-)运算操作码。
+ *
+ * @param operand 操作数表达式
+ * @return 匹配类型的 IROpCode
*/
public static IROpCode negOp(ExpressionNode operand) {
char t = typeChar(operand);
@@ -99,34 +121,54 @@ public final class ExpressionUtils {
case 'l' -> IROpCode.NEG_L64;
case 'f' -> IROpCode.NEG_F32;
case 'd' -> IROpCode.NEG_D64;
- default -> IROpCode.NEG_I32; // '\0' 或 'i'
+ default -> IROpCode.NEG_I32; // 无法推断或为 int
};
}
- /* ────────────────── 比较运算(已适配 long) ────────────────── */
+ // ───────────── 比较运算相关 ─────────────
- /** 判断给定字符串是否是比较运算符(==, !=, <, >, <=, >=)。 */
+ /**
+ * 判断给定字符串是否为支持的比较运算符(==, !=, <, >, <=, >=)。
+ *
+ * @param op 操作符字符串
+ * @return 若为比较运算符返回 true,否则返回 false
+ */
public static boolean isComparisonOperator(String op) {
return ComparisonUtils.isComparisonOperator(op);
}
/**
- * 兼容旧调用:仅凭操作符返回 int32 比较指令。
+ * 兼容旧逻辑:仅凭操作符直接返回 int32 比较指令。
+ *
+ * @param op 比较操作符
+ * @return int32 类型的比较操作码
*/
public static IROpCode cmpOp(String op) {
- return IROpCodeMappings.CMP_I32.get(op); // 旧逻辑:一律 i32
+ return IROpCodeMappings.CMP_I32.get(op);
}
/**
- * 推荐调用:根据左右表达式类型自动选择 int / long 比较指令。
+ * 推荐调用:根据左右表达式类型自动选择 int/long/float/double 等合适的比较操作码。
+ *
+ * @param variables 变量名到类型的映射
+ * @param op 比较符号
+ * @param left 左操作数表达式
+ * @param right 右操作数表达式
+ * @return 匹配类型的比较操作码
*/
public static IROpCode cmpOp(Map
+ * 类型推断优先使用左右表达式的类型后缀,推断失败时回退为线程级默认类型后缀,再失败则默认为 int32。
+ *
+ * @param op 算术操作符
+ * @param left 左表达式
+ * @param right 右表达式
+ * @return 匹配类型的 IROpCode
*/
public static IROpCode resolveOpCode(String op,
ExpressionNode left,
ExpressionNode right) {
-
- /* 1. 尝试根据字面量推断 */
+ // 1. 优先根据表达式类型推断
char suffix = resolveSuffix(left, right);
-
- /* 2. 若失败则使用函数级默认类型 */
+ // 2. 推断失败则使用线程默认类型
if (suffix == '\0') suffix = DEFAULT_SUFFIX.get();
-
- /* 3. 仍失败则默认为 int32 */
+ // 3. 仍失败则默认为 int32
Map