feat: 更新 FunctionBuilder构建流程与文档

- 在全局函数表中注册函数名与返回类型
- 初始化 IRFunction 实例与 IRContext 上下文对象
- 自动导入全局常量(包括跨模块 const 变量)到当前作用域
- 根据函数返回类型设置表达式推断的默认字面量类型后缀
- 遍历声明形参,每个参数分配虚拟寄存器,并注册到作用域
- 依次转换函数体中的每条语句为 IR指令
- 函数体转换完成后,清理默认类型后缀
This commit is contained in:
Luke 2025-08-26 11:32:48 +08:00
parent fcdc3a49f8
commit 1a0c3a38cb

View File

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