diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/FunctionBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/FunctionBuilder.java
index 56ffd3f..2fb428f 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/builder/FunctionBuilder.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/FunctionBuilder.java
@@ -1,5 +1,6 @@
package org.jcnc.snow.compiler.ir.builder;
+import org.jcnc.snow.compiler.ir.common.GlobalConstTable;
import org.jcnc.snow.compiler.ir.common.GlobalFunctionTable;
import org.jcnc.snow.compiler.ir.core.IRFunction;
import org.jcnc.snow.compiler.ir.utils.ExpressionUtils;
@@ -13,6 +14,13 @@ import org.jcnc.snow.compiler.parser.ast.base.StatementNode;
*
* 负责将语法树中的 FunctionNode 节点转化为可执行的 IRFunction,
* 包含参数声明、返回类型推断、函数体语句转换等步骤。
+ *
+ *
+ * - 支持自动导入全局/跨模块常量,使跨模块常量引用(如 ModuleA.a)在 IR 阶段可用。
+ * - 将函数形参声明为虚拟寄存器,并注册到作用域,便于后续指令生成。
+ * - 根据返回类型设置表达式默认字面量类型,保证 IR 层类型一致性。
+ * - 遍历并转换函数体语句为 IR 指令。
+ *
*/
public class FunctionBuilder {
@@ -21,11 +29,15 @@ public class FunctionBuilder {
*
* 构建过程包括:
*
- * - 初始化 IRFunction 实例和上下文
- * - 根据函数返回类型,设置默认类型后缀,便于表达式推断
- * - 声明参数到作用域,并为每个参数分配虚拟寄存器
- * - 遍历并转换函数体内的每条语句为 IR 指令
- * - 函数构建完成后,清理默认类型后缀,防止影响其他函数
+ * - 在全局函数表注册函数签名,便于后续模块/语义分析阶段查询。
+ * - 初始化 IRFunction 实例和 IRContext 上下文对象(包含作用域与寄存器信息)。
+ * - 自动导入全局常量(包括跨模块 const 变量)到当前作用域,
+ * 使成员访问如 ModuleA.a 可直接折叠为常量。
+ * - 根据函数返回类型,设置表达式推断的默认字面量类型后缀
+ * (如 double→d, float→f),避免类型不一致。
+ * - 遍历声明形参,每个参数分配虚拟寄存器,并注册到作用域。
+ * - 依次转换函数体中的每条语句为 IR 指令。
+ * - 函数体转换完成后,清理默认类型后缀,防止影响后续函数构建。
*
*
* @param functionNode 表示函数定义的语法树节点
@@ -33,44 +45,56 @@ public class FunctionBuilder {
*/
public IRFunction build(FunctionNode functionNode) {
- // 在全局函数表中注册函数信息
+ // 1. 在全局函数表注册函数名与返回类型
+ // 方便其他阶段/模块调用、类型检查。
GlobalFunctionTable.register(functionNode.name(), functionNode.returnType());
-
- // 0) 基本初始化: 创建 IRFunction 实例与对应上下文
+ // 2. 初始化 IRFunction 实例与上下文对象
+ // IRFunction: 表示该函数的中间代码容器
+ // IRContext: 负责作用域、寄存器分配等编译上下文管理
IRFunction irFunction = new IRFunction(functionNode.name());
IRContext irContext = new IRContext(irFunction);
- // 1) 把函数返回类型注入为默认类型后缀(供表达式类型推断)
+ // 3. 自动导入所有全局/跨模块常量到当前作用域
+ // 支持如 ModuleA.a 这样的常量访问/折叠(参见 ExpressionBuilder)
+ GlobalConstTable.all().forEach((k, v) ->
+ irContext.getScope().importExternalConst(k, v));
+
+ // 4. 根据函数返回类型设置默认类型后缀
+ // 例如返回类型为 double 时, 字面量表达式自动用 d 后缀。
char _returnSuffix = switch (functionNode.returnType().toLowerCase()) {
case "double" -> 'd';
case "float" -> 'f';
case "long" -> 'l';
case "short" -> 's';
case "byte" -> 'b';
- default -> '\0';
+ default -> '\0'; // 其它类型不设默认后缀
};
ExpressionUtils.setDefaultSuffix(_returnSuffix);
try {
- // 2) 声明形参: 为每个参数分配虚拟寄存器并声明到作用域
+ // 5. 遍历函数参数列表
+ // - 为每个参数分配一个新的虚拟寄存器
+ // - 注册参数名、类型、寄存器到当前作用域
+ // - 添加参数寄存器到 IRFunction(用于后续调用与指令生成)
for (ParameterNode p : functionNode.parameters()) {
- IRVirtualRegister reg = irFunction.newRegister(); // 新寄存器
- irContext.getScope().declare(p.name(), p.type(), reg); // 变量名→寄存器绑定
- irFunction.addParameter(reg); // 添加到函数参数列表
+ IRVirtualRegister reg = irFunction.newRegister();
+ irContext.getScope().declare(p.name(), p.type(), reg);
+ irFunction.addParameter(reg);
}
- // 3) 生成函数体 IR: 遍历每条语句,逐一转化
+ // 6. 遍历函数体语句节点,转换为 IR 指令
+ // StatementBuilder 负责将每条语句递归转换为 IR
StatementBuilder stmtBuilder = new StatementBuilder(irContext);
for (StatementNode stmt : functionNode.body()) {
stmtBuilder.build(stmt);
}
} finally {
- // 4) 清除默认后缀,避免影响后续函数的推断
+ // 7. 清理默认类型后缀,防止影响后续其他函数的类型推断
ExpressionUtils.clearDefaultSuffix();
}
- // 返回构建好的 IRFunction
+ // 8. 返回构建完成的 IRFunction
return irFunction;
}
}