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