From 1f7458be286b7f02a29361721adff7473075aff7 Mon Sep 17 00:00:00 2001
From: Luke
+ * 主要工作内容包括:
+ *
+ * 该类为不可变工具类,仅包含静态行为,不持有状态。
+ *
+ * 主流程为:
+ *
*
+ *
+ * declare const 常量登记到全局常量表,支持跨模块常量折叠。StructName.__init__、StructName.method;同时在其参数列表首位插入隐式 this: StructName。
+ *
+ *
+ *
+ *
降级规则:
+ *+ * 支持跨模块常量折叠,便于 IR 生成时做常量传播与优化。 + *
* * @param roots AST 顶层节点列表 */ @@ -74,7 +206,7 @@ public final class IRProgramBuilder { String moduleName = mod.name(); if (mod.globals() == null) continue; for (DeclarationNode decl : mod.globals()) { - // 只处理 compile-time 的 const 常量,并要求有初始值 + // 只处理带初始值的 const 常量(编译期常量),忽略 run-time/无初始值 if (!decl.isConst() || decl.getInitializer().isEmpty()) continue; ExpressionNode init = decl.getInitializer().get(); Object value = evalLiteral(init); @@ -88,24 +220,28 @@ public final class IRProgramBuilder { /** * 字面量提取与类型折叠工具。 + ** 用于将表达式节点还原为 Java 原生类型(int、long、double、String等),仅支持直接字面量。 + * 不支持复杂表达式、非常量等情况,无法静态折叠则返回 null。 * - * @param expr 要计算的表达式节点 - * @return 提取到的原生常量值,不支持的情况返回 null + * @param expr 要计算的表达式节点(要求是字面量) + * @return 提取到的原生常量值;若不支持则返回 null */ private Object evalLiteral(ExpressionNode expr) { return switch (expr) { case NumberLiteralNode num -> { + // 数字字面量:支持下划线、类型后缀(如 123_456L) String raw = num.value(); String s = raw.replace("_", ""); char last = Character.toLowerCase(s.charAt(s.length() - 1)); + // 处理类型后缀:如 123l/123d/123f 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")) { - // 浮点数处理 yield Double.parseDouble(core); } long lv = Long.parseLong(core); @@ -119,9 +255,9 @@ public final class IRProgramBuilder { 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; // 布尔常量转为 1/0 + default -> null; // 其他情况不支持常量折叠 }; } @@ -129,21 +265,23 @@ public final class IRProgramBuilder { /** * 构建带有模块全局声明“注入”的函数,并将函数名加上模块前缀,保证模块内函数名唯一。 - * 如果模块有全局声明,则这些声明会被插入到函数体前部(**会过滤掉与参数同名的全局声明**)。 + *
+ * 如果模块有全局声明,则这些声明会被插入到函数体前部(会过滤掉与参数同名的全局声明,防止变量遮蔽)。 + *
* * @param moduleNode 所属模块节点 * @param functionNode 待构建的函数节点 * @return 包含全局声明的 IRFunction */ private IRFunction buildFunctionWithGlobals(ModuleNode moduleNode, FunctionNode functionNode) { - // 拼接模块名和函数名,生成全限定名 + // 1. 拼接模块名和函数名,生成全限定名 String qualifiedName = moduleNode.name() + "." + functionNode.name(); + // 2. 若无全局声明,直接重命名构建 if (moduleNode.globals() == null || moduleNode.globals().isEmpty()) { - // 无全局声明,直接重命名构建 return buildFunction(renameFunction(functionNode, qualifiedName)); } - // ------- 过滤与参数重名的全局声明 ------- + // 3. 过滤掉与参数重名的全局声明(优先参数作用域,避免变量遮蔽) Set本方法仅作中转,直接委托给 FunctionBuilder。
*/ private IRFunction buildFunction(FunctionNode functionNode) { return new FunctionBuilder().build(functionNode);