feat: 增强全局常量处理与字面量解析

- 支持整数、浮点数、字符串和布尔字面量的解析
- 添加类型后缀支持(b/s/l/f/d),并进行相应的类型转换
- 优化数字字面量的解析逻辑,支持科学计数法和下划线分隔符
- 改进字面量提取工具的文档注释,明确支持的类型和转换规则
This commit is contained in:
Luke 2025-08-26 14:32:13 +08:00
parent 6e31185519
commit 439304c86a

View File

@ -58,6 +58,7 @@ public final class IRProgramBuilder {
}
// ===================== 全局常量收集 =====================
/**
* 扫描所有模块节点将其中声明的 const 全局变量compile-time 常量
* "模块名.常量名" 形式注册到全局常量表
@ -84,26 +85,54 @@ public final class IRProgramBuilder {
}
/**
* 字面量提取工具仅支持整数/浮点字符串布尔字面量其它返回 null
* 字面量提取与类型折叠工具
* <p>
* 用于从表达式节点中解析出直接可用于全局常量表注册的 Java
* 支持以下字面量类型
* <ul>
* <li>整数与浮点可带下划线分隔符支持类型后缀 b/s/l/f/d自动转换为对应 Java 基本类型</li>
* <li>字符串字面量直接返回内容</li>
* <li>布尔字面量true 返回 1false 返回 0用于数值语境</li>
* </ul>
* 不支持的表达式或解析失败将返回 null
*
* @param expr 常量初始化表达式
* @return 字面量值 123, 3.14, "abc", 1/0否则 null
* @param expr 字面量表达式节点通常为 NumberLiteralNode/StringLiteralNode/BoolLiteralNode
* @return 提取出的 Java 可为 Integer/Byte/Short/Long/Double/String/Integer(布尔) null
*/
private Object evalLiteral(ExpressionNode expr) {
return switch (expr) {
case NumberLiteralNode num -> {
String s = num.value();
String raw = num.value();
// 1. 去掉下划线分隔符便于解析 1_000_000
String s = raw.replace("_", "");
// 2. 提取类型后缀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 (s.contains(".") || s.contains("e") || s.contains("E"))
yield Double.parseDouble(s);
yield Integer.parseInt(s);
// 3. 若为浮点字面量或科学计数法直接转 double
if (core.contains(".") || core.contains("e") || core.contains("E")) {
double dv = Double.parseDouble(core);
yield dv;
}
// 4. 整数字面量先转 long再根据后缀决定精度
long lv = Long.parseLong(core);
yield switch (last) {
case 'b' -> (byte) lv; // 末尾 b byte
case 's' -> (short) lv; // 末尾 s short
case 'l' -> lv; // 末尾 l long
default -> (int) lv; // 无后缀 int
};
} catch (NumberFormatException ignore) {
// 解析失败返回 null
yield null;
}
}
case StringLiteralNode str -> str.value();
case BoolLiteralNode b -> b.getValue() ? 1 : 0;
default -> null;
case StringLiteralNode str -> str.value(); // 字符串字面量返回内容
case BoolLiteralNode b -> b.getValue() ? 1 : 0; // 布尔字面量true=1false=0
default -> null; // 其它类型不支持
};
}