feat: 丰富 IRConstant 类功能

- 添加通用工厂方法 fromObject
- 实现数字字面量解析方法 fromNumber
- 增加字符串和布尔字面量工厂方法
- 改进 toString 方法,提供调试友好的输出
This commit is contained in:
Luke 2025-08-29 17:45:17 +08:00
parent 8f59f91766
commit 4b633bae70

View File

@ -3,29 +3,99 @@ package org.jcnc.snow.compiler.ir.value;
import org.jcnc.snow.compiler.ir.core.IRValue;
/**
* IRConstant 表示中间表示IR系统中的常量值
* {@code IRConstant} 表示中间表示IR系统中的常量值节点
* <p>
* 常量用于表示在编译期间已知的不可变值例如字面整数浮点数布尔值或字符串
* {@link IRVirtualRegister} 不同常量不需要通过寄存器存储
* 可直接作为 IR 指令的操作数使用
* <p>
* 典型应用:
* - 加载常量指令: v1 = CONST 42
* - 计算表达式: v2 = ADD v1, 100
* 常量用于表示在编译期间已知的不可变值例如字面整数浮点数布尔值或字符串等
* {@link IRVirtualRegister} 不同IRConstant 不需要通过寄存器存储
* 可直接作为 IR 指令的操作数立即数/常量池引用等
*/
public record IRConstant(Object value) implements IRValue {
/**
* 将常量值转换为字符串用于打印 IR 指令或调试输出
* <p>
* 例如:
* - 整数常量: 42
* - 字符串常量: "hello"
* 通用工厂方法将任意 Java 对象包装为 IRConstant
*
* @return 常量的字符串表示
* @param v 任意对象
* @return IRConstant 封装后的常量
*/
public static IRConstant fromObject(Object v) {
return new IRConstant(v);
}
/**
* 数字字面量工厂接受源码字面量字符串解析为 int/long/double Java 数值类型
* <p>
* 支持下划线分隔 "1_000_000"类型后缀 'l','d','f' 并自动转换为
* <ul>
* <li>double带小数点或科学计数法</li>
* <li>long/byte/short/int依类型后缀或值范围判定</li>
* <li>解析失败时兜底为字符串原文保证编译不中断</li>
* </ul>
*
* @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);
}
/**
* 调试友好的字符串表示
* <ul>
* <li>字符串常量输出带引号转义引号和反斜杠</li>
* <li>null 输出为 "null"</li>
* <li>其它类型调用 toString()</li>
* </ul>
*/
@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);
}
}