feat: 扩展签名注册器支持结构体类型

- 增加结构体类型签名的登记逻辑,包括构造函数和方法签名
- 优化模块级函数签名的注册流程,提高代码可读性
- 完善导入模块的合法性校验,确保模块存在性
This commit is contained in:
Luke 2025-08-29 18:21:25 +08:00
parent 586ede1cf0
commit 584e226051

View File

@ -1,12 +1,10 @@
package org.jcnc.snow.compiler.semantic.core;
import org.jcnc.snow.compiler.parser.ast.FunctionNode;
import org.jcnc.snow.compiler.parser.ast.ImportNode;
import org.jcnc.snow.compiler.parser.ast.ModuleNode;
import org.jcnc.snow.compiler.parser.ast.ParameterNode;
import org.jcnc.snow.compiler.parser.ast.*;
import org.jcnc.snow.compiler.semantic.error.SemanticError;
import org.jcnc.snow.compiler.semantic.type.BuiltinType;
import org.jcnc.snow.compiler.semantic.type.FunctionType;
import org.jcnc.snow.compiler.semantic.type.StructType;
import org.jcnc.snow.compiler.semantic.type.Type;
import java.util.ArrayList;
@ -14,71 +12,96 @@ import java.util.List;
import java.util.Optional;
/**
* {@code SignatureRegistrar} 负责函数签名登记与导入语义检查
* {@code SignatureRegistrar}
* <p>
* 在语义分析初期阶段它遍历每个模块完成以下任务:
* 语义分析准备阶段负责函数签名登记与 import 模块存在性校验
* <ul>
* <li>验证所有 {@link ImportNode} 导入的模块是否存在于全局模块表 {@link Context#modules()} </li>
* <li>将每个 {@link FunctionNode} 的函数签名参数类型和返回类型注册到对应 {@link ModuleInfo} </li>
* <li>在参数或返回类型无法识别时记录 {@link SemanticError}并进行容错降级</li>
* <li>验证每个模块声明的 import 模块在全局模块表 {@link Context#modules()} 是否存在</li>
* <li>将每个函数结构体方法构造函数的类型签名登记到 {@link ModuleInfo}便于后续类型推断</li>
* <li>若参数或返回类型无法解析则报错并降级为 int void保证语义分析流程健壮</li>
* </ul>
* 本组件作为语义分析的准备阶段为后续函数体检查提供函数类型上下文
*
* @param ctx 全局语义分析上下文提供模块类型错误管理等功能
* 作为语义分析前置流程为后续函数体和表达式分析提供类型环境
* </p>
*/
public record SignatureRegistrar(Context ctx) {
/**
* 构造函数签名注册器
* 遍历所有模块注册函数/方法签名校验 import 合法性填充 {@link ModuleInfo} 元信息
*
* @param ctx 当前语义分析上下文
* @param modules 需要分析的所有模块列表AST 顶层节点
*/
public SignatureRegistrar {
}
/**
* 遍历模块并注册函数签名同时校验导入模块的合法性
*
* @param mods 所有模块的语法树节点集合
*/
public void register(Iterable<ModuleNode> mods) {
for (ModuleNode mod : mods) {
public void register(Iterable<ModuleNode> modules) {
for (ModuleNode mod : modules) {
ctx.setCurrentModule(mod.name()); // 切换上下文到当前模块
ModuleInfo mi = ctx.modules().get(mod.name());
// ---------- 1. 模块导入检查 ----------
// ========== 1) 校验 imports ==========
for (ImportNode imp : mod.imports()) {
if (!ctx.modules().containsKey(imp.moduleName())) {
ctx.errors().add(new SemanticError(
imp,
"未知模块: " + imp.moduleName()
));
// 导入的模块在全局表中不存在报错
ctx.errors().add(new SemanticError(imp, "未知模块: " + imp.moduleName()));
} else {
// 添加到本模块导入集合
mi.getImports().add(imp.moduleName());
}
}
// ---------- 2. 函数签名注册 ----------
for (FunctionNode fn : mod.functions()) {
List<Type> params = new ArrayList<>();
// ========== 2) 结构体签名登记 ==========
for (StructNode stn : mod.structs()) {
// 构造结构体类型对象唯一标识为 (模块名, 结构体名)
StructType st = new StructType(mod.name(), stn.name());
mi.getStructs().put(stn.name(), st);
// 参数类型解析
for (ParameterNode p : fn.parameters()) {
Type t = Optional.ofNullable(ctx.parseType(p.type()))
.orElseGet(() -> {
ctx.errors().add(new SemanticError(
p,
"未知类型: " + p.type()
));
return BuiltinType.INT; // 容错降级
});
params.add(t);
// --- 2.1 构造函数 init ---
if (stn.init() != null) {
List<Type> ptypes = new ArrayList<>();
for (ParameterNode p : stn.init().parameters()) {
// 解析参数类型不存在则报错降级为 int
Type t = ctx.parseType(p.type());
if (t == null) {
ctx.errors().add(new SemanticError(p, "未知类型: " + p.type()));
t = BuiltinType.INT;
}
ptypes.add(t);
}
// 构造函数返回类型固定为 void
st.setConstructor(new FunctionType(ptypes, BuiltinType.VOID));
}
// 返回类型解析默认降级为 void
// --- 2.2 结构体方法签名 ---
for (FunctionNode fn : stn.methods()) {
List<Type> ptypes = new ArrayList<>();
for (ParameterNode p : fn.parameters()) {
// 解析参数类型不存在则报错降级为 int
Type t = ctx.parseType(p.type());
if (t == null) {
ctx.errors().add(new SemanticError(p, "未知类型: " + p.type()));
t = BuiltinType.INT;
}
ptypes.add(t);
}
// 返回类型未指定时降级为 void
Type ret = Optional.ofNullable(ctx.parseType(fn.returnType()))
.orElse(BuiltinType.VOID);
st.getMethods().put(fn.name(), new FunctionType(ptypes, ret));
}
}
// ========== 3) 模块级函数签名登记 ==========
for (FunctionNode fn : mod.functions()) {
List<Type> params = new ArrayList<>();
for (ParameterNode p : fn.parameters()) {
// 解析参数类型不存在则报错降级为 int
Type t = ctx.parseType(p.type());
if (t == null) {
ctx.errors().add(new SemanticError(p, "未知类型: " + p.type()));
t = BuiltinType.INT;
}
params.add(t);
}
// 返回类型未指定时降级为 void
Type ret = Optional.ofNullable(ctx.parseType(fn.returnType()))
.orElse(BuiltinType.VOID);
// 注册函数签名
mi.getFunctions().put(fn.name(), new FunctionType(params, ret));
}
}