diff --git a/src/main/java/org/jcnc/snow/compiler/ir/value/IRConstant.java b/src/main/java/org/jcnc/snow/compiler/ir/value/IRConstant.java index 776d688..8515bb7 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/value/IRConstant.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/value/IRConstant.java @@ -3,29 +3,99 @@ package org.jcnc.snow.compiler.ir.value; import org.jcnc.snow.compiler.ir.core.IRValue; /** - * IRConstant —— 表示中间表示(IR)系统中的常量值。 + * {@code IRConstant} —— 表示中间表示(IR)系统中的常量值节点。 *

- * 常量用于表示在编译期间已知的不可变值,例如字面整数、浮点数、布尔值或字符串。 - * 与 {@link IRVirtualRegister} 不同,常量不需要通过寄存器存储, - * 可直接作为 IR 指令的操作数使用。 - *

- * 典型应用: - * - 加载常量指令: v1 = CONST 42 - * - 计算表达式: v2 = ADD v1, 100 + * 常量用于表示在编译期间已知的不可变值,例如字面整数、浮点数、布尔值或字符串等。 + * 与 {@link IRVirtualRegister} 不同,IRConstant 不需要通过寄存器存储, + * 可直接作为 IR 指令的操作数(立即数/常量池引用等)。 */ public record IRConstant(Object value) implements IRValue { /** - * 将常量值转换为字符串,用于打印 IR 指令或调试输出。 - *

- * 例如: - * - 整数常量: 42 - * - 字符串常量: "hello" + * 通用工厂方法:将任意 Java 对象包装为 IRConstant。 * - * @return 常量的字符串表示 + * @param v 任意对象 + * @return IRConstant 封装后的常量 + */ + public static IRConstant fromObject(Object v) { + return new IRConstant(v); + } + + /** + * 数字字面量工厂:接受源码字面量字符串,解析为 int/long/double 等 Java 数值类型。 + *

+ * 支持下划线分隔(如 "1_000_000")、类型后缀(如 'l','d','f' 等),并自动转换为 + *

+ * + * @param literal 字面量字符串(可能含类型后缀、下划线分隔) + * @return IRConstant 包装的数字常量 + */ + public static IRConstant fromNumber(String literal) { + if (literal == null) return new IRConstant(null); + String s = literal.replace("_", ""); // 去除下划线分隔符 + // 检查并处理类型后缀(b/s/l/f/d) + char last = Character.toLowerCase(s.charAt(s.length() - 1)); + String core = switch (last) { + case 'b', 's', 'l', 'f', 'd' -> s.substring(0, s.length() - 1); + default -> s; + }; + try { + // 浮点:含小数点或科学计数法 + if (core.contains(".") || core.contains("e") || core.contains("E")) { + return new IRConstant(Double.parseDouble(core)); + } + long lv = Long.parseLong(core); // 整型 + return switch (last) { + case 'b' -> new IRConstant((byte) lv); // 字节型 + case 's' -> new IRConstant((short) lv); // 短整型 + case 'l' -> new IRConstant(lv); // 长整型 + default -> new IRConstant((int) lv); // 默认 int + }; + } catch (NumberFormatException e) { + // 解析失败时,回退为原始字符串,避免编译中断 + return new IRConstant(core); + } + } + + /** + * 字符串字面量工厂。 + * + * @param s 字符串内容 + * @return IRConstant 封装的字符串常量 + */ + public static IRConstant fromString(String s) { + return new IRConstant(s); + } + + /** + * 布尔字面量工厂。 + * + * @param v 布尔值 + * @return IRConstant 封装的布尔常量 + */ + public static IRConstant fromBoolean(boolean v) { + return new IRConstant(v); + } + + /** + * 调试友好的字符串表示。 + * */ @Override public String toString() { - return value.toString(); + if (value == null) return "null"; + if (value instanceof String s) { + String escaped = s.replace("\\", "\\\\").replace("\"", "\\\""); + return "\"" + escaped + "\""; + } + return String.valueOf(value); } }