From 439304c86a33d8ef25a369ee32b12f210cb4a31f Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 26 Aug 2025 14:32:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=BC=BA=E5=85=A8=E5=B1=80?= =?UTF-8?q?=E5=B8=B8=E9=87=8F=E5=A4=84=E7=90=86=E4=B8=8E=E5=AD=97=E9=9D=A2?= =?UTF-8?q?=E9=87=8F=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 支持整数、浮点数、字符串和布尔字面量的解析 - 添加类型后缀支持(b/s/l/f/d),并进行相应的类型转换 - 优化数字字面量的解析逻辑,支持科学计数法和下划线分隔符 - 改进字面量提取工具的文档注释,明确支持的类型和转换规则 --- .../compiler/ir/builder/IRProgramBuilder.java | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/IRProgramBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/IRProgramBuilder.java index 290cbb4..8d0a340 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/builder/IRProgramBuilder.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/IRProgramBuilder.java @@ -58,6 +58,7 @@ public final class IRProgramBuilder { } // ===================== 全局常量收集 ===================== + /** * 扫描所有模块节点,将其中声明的 const 全局变量(compile-time 常量) * 以 "模块名.常量名" 形式注册到全局常量表。 @@ -84,26 +85,54 @@ public final class IRProgramBuilder { } /** - * 字面量提取工具。仅支持整数/浮点、字符串、布尔字面量,其它返回 null。 + * 字面量提取与类型折叠工具。 + *

+ * 用于从表达式节点中解析出直接可用于全局常量表注册的 Java 值, + * 支持以下字面量类型: + *

+ * 不支持的表达式或解析失败将返回 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=1,false=0 + default -> null; // 其它类型不支持 }; }