From 4b633bae7076afbc9184e8fcb4589c82fce44d8f Mon Sep 17 00:00:00 2001 From: Luke Date: Fri, 29 Aug 2025 17:45:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=B0=E5=AF=8C=20IRConstant=20?= =?UTF-8?q?=E7=B1=BB=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加通用工厂方法 fromObject - 实现数字字面量解析方法 fromNumber - 增加字符串和布尔字面量工厂方法 - 改进 toString 方法,提供调试友好的输出 --- .../snow/compiler/ir/value/IRConstant.java | 100 +++++++++++++++--- 1 file changed, 85 insertions(+), 15 deletions(-) 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); } }