diff --git a/src/main/java/org/jcnc/snow/compiler/backend/generator/CallGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/generator/CallGenerator.java index 04dfaa1..2c35596 100644 --- a/src/main/java/org/jcnc/snow/compiler/backend/generator/CallGenerator.java +++ b/src/main/java/org/jcnc/snow/compiler/backend/generator/CallGenerator.java @@ -72,7 +72,8 @@ public class CallGenerator implements InstructionGenerator { String fn = ins.getFunctionName(); // 特殊处理 syscall 调用 - if ("syscall".equals(fn) || fn.endsWith(".syscall")) { + String tname = fn.substring(0, fn.lastIndexOf(':')); + if ("syscall".equals(tname) || tname.endsWith(".syscall")) { generateSyscall(ins, out, slotMap, fn); return; } diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/ExpressionBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/ExpressionBuilder.java index 47bb4a4..6e481eb 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/builder/ExpressionBuilder.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/ExpressionBuilder.java @@ -14,6 +14,9 @@ import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode; import java.util.ArrayList; import java.util.List; +import java.util.StringJoiner; + +import static org.jcnc.snow.compiler.ir.utils.ExpressionUtils.looksLikeFloat; /** * {@code ExpressionBuilder} 表达式 → IR 构建器。 @@ -377,17 +380,67 @@ public record ExpressionBuilder(IRContext ctx) { // 1. 递归生成所有参数的寄存器 List argv = call.arguments().stream().map(this::build).toList(); + // TODO: 注释 + StringJoiner sj = new StringJoiner("_"); + for (ExpressionNode param : call.arguments()) { + switch (param) { + case NumberLiteralNode n -> { + String value = n.value(); + char suffix = value.isEmpty() ? '\0' + : Character.toLowerCase(value.charAt(value.length() - 1)); + + switch (suffix) { + case 'b' -> sj.add("byte"); + case 's' -> sj.add("short"); + case 'l' -> sj.add("long"); + case 'f' -> sj.add("float"); + case 'd' -> sj.add("double"); + default -> { + if (looksLikeFloat(value)) { + sj.add("double"); + } else { + sj.add("int"); + } + } + } + ; + } + case BoolLiteralNode _ -> sj.add("bool"); + case StringLiteralNode _ -> sj.add("string"); + case IdentifierNode id -> { + String type = ctx.getScope().lookupType(id.name()); + sj.add(type); + } +// case CallExpressionNode ce -> { +// } + case null, default -> throw new IllegalArgumentException("(内部错误) 不支持的参数表达式: " + param); + } + } + // 2. 规范化被调用方法名(区分成员方法与普通函数) String callee = switch (call.callee()) { // 成员方法调用,如 obj.method() - case MemberExpressionNode m when m.object() instanceof IdentifierNode id -> id.name() + "." + m.member(); + case MemberExpressionNode m when m.object() instanceof IdentifierNode id -> { + String qualifiedName = id.name() + "." + m.member(); + if (sj.length() > 0) { + qualifiedName = qualifiedName + ":" + sj; + } + + yield qualifiedName; + } // 普通函数调用,或处理命名空间前缀(如当前方法名为 namespace.func) case IdentifierNode id -> { String current = ctx.getFunction().name(); int dot = current.lastIndexOf('.'); - if (dot > 0) - yield current.substring(0, dot) + "." + id.name(); // 同命名空间内调用 - yield id.name(); // 全局函数调用 + + String qualifiedName = dot > 0 + ? current.substring(0, dot) + "." + id.name() + : id.name(); + if (sj.length() > 0) { + qualifiedName = qualifiedName + ":" + sj; + } + + yield qualifiedName; // 全局函数调用 } // 其它类型不支持 default -> throw new IllegalStateException( diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/IRProgramBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/IRProgramBuilder.java index 28e89c2..9ecc2e5 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/builder/IRProgramBuilder.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/IRProgramBuilder.java @@ -4,12 +4,14 @@ import org.jcnc.snow.compiler.ir.core.IRFunction; import org.jcnc.snow.compiler.ir.core.IRProgram; import org.jcnc.snow.compiler.parser.ast.FunctionNode; import org.jcnc.snow.compiler.parser.ast.ModuleNode; +import org.jcnc.snow.compiler.parser.ast.ParameterNode; import org.jcnc.snow.compiler.parser.ast.base.Node; import org.jcnc.snow.compiler.parser.ast.base.NodeContext; import org.jcnc.snow.compiler.parser.ast.base.StatementNode; import java.util.ArrayList; import java.util.List; +import java.util.StringJoiner; /** * IRProgramBuilder 负责将 AST 根节点(如模块、函数、顶层语句)转换为可执行的 IRProgram 实例。 @@ -66,6 +68,15 @@ public final class IRProgramBuilder { private IRFunction buildFunctionWithGlobals(ModuleNode moduleNode, FunctionNode functionNode) { // 拼接模块名和函数名,生成全限定名 String qualifiedName = moduleNode.name() + "." + functionNode.name(); + + StringJoiner sj = new StringJoiner("_"); + for (ParameterNode param : functionNode.parameters()) { + sj.add(param.type()); + } + if (sj.length() > 0) { + qualifiedName = qualifiedName + ":" + sj; + } + // 若无全局声明,仅重命名后直接构建 if (moduleNode.globals() == null || moduleNode.globals().isEmpty()) { return buildFunction(renameFunction(functionNode, qualifiedName)); diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/CallExpressionAnalyzer.java b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/CallExpressionAnalyzer.java index 250e12e..a98e0ff 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/CallExpressionAnalyzer.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/CallExpressionAnalyzer.java @@ -77,8 +77,15 @@ public class CallExpressionAnalyzer implements ExpressionAnalyzer args = new ArrayList<>(); + for (ExpressionNode arg : call.arguments()) { + args.add(ctx.getRegistry().getExpressionAnalyzer(arg) + .analyze(ctx, mi, fn, locals, arg)); + } + // 查找目标函数签名(先在当前模块/显式模块查找) - FunctionType ft = target.getFunctions().get(functionName); + FunctionType ft = target.retrieveFunction(functionName, args); // 未找到则报错 if (ft == null) { @@ -88,13 +95,6 @@ public class CallExpressionAnalyzer implements ExpressionAnalyzer args = new ArrayList<>(); - for (ExpressionNode arg : call.arguments()) { - args.add(ctx.getRegistry().getExpressionAnalyzer(arg) - .analyze(ctx, mi, fn, locals, arg)); - } - // 参数数量检查 if (args.size() != ft.paramTypes().size()) { ctx.getErrors().add(new SemanticError(call, diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/statement/ReturnAnalyzer.java b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/statement/ReturnAnalyzer.java index 35f2fcf..6311f2b 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/statement/ReturnAnalyzer.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/statement/ReturnAnalyzer.java @@ -1,6 +1,7 @@ package org.jcnc.snow.compiler.semantic.analyzers.statement; import org.jcnc.snow.compiler.parser.ast.FunctionNode; +import org.jcnc.snow.compiler.parser.ast.ParameterNode; import org.jcnc.snow.compiler.parser.ast.ReturnNode; import org.jcnc.snow.compiler.semantic.analyzers.base.StatementAnalyzer; import org.jcnc.snow.compiler.semantic.core.Context; @@ -11,6 +12,9 @@ import org.jcnc.snow.compiler.semantic.type.BuiltinType; import org.jcnc.snow.compiler.semantic.type.FunctionType; import org.jcnc.snow.compiler.semantic.type.Type; +import java.util.ArrayList; +import java.util.List; + /** * {@code ReturnAnalyzer} 是用于分析 {@link ReturnNode} 返回语句的语义分析器。 *

@@ -42,12 +46,32 @@ public class ReturnAnalyzer implements StatementAnalyzer { ctx.log("检查 return"); - // 获取当前函数的定义信息 - FunctionType expected = ctx.getModules() + // 获取当前函数的重载列表 + var overloading = ctx.getModules() .get(mi.getName()) .getFunctions() .get(fn.name()); + List params = new ArrayList<>(); + for (ParameterNode pn : fn.parameters()) { + params.add(locals.resolve(pn.name()).type()); + } + + // fn 对应的函数签名 + FunctionType expected = overloading.stream() + .filter(ft -> ft.paramTypes().equals(params)) + .findFirst() + .orElse(null); + + if (expected == null) { + ctx.getErrors().add(new SemanticError( + fn, + "不存在的函数签名: " + params + )); + ctx.log("不存在的函数签名: " + params); + return; + } + // 情况 1: 存在返回表达式,需进行类型检查 ret.getExpression().ifPresentOrElse(exp -> { var exprAnalyzer = ctx.getRegistry().getExpressionAnalyzer(exp); diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/core/BuiltinTypeRegistry.java b/src/main/java/org/jcnc/snow/compiler/semantic/core/BuiltinTypeRegistry.java index 9f266c9..7f2dc71 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/core/BuiltinTypeRegistry.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/core/BuiltinTypeRegistry.java @@ -62,14 +62,54 @@ public final class BuiltinTypeRegistry { /* ---------- 注册标准库 os ---------- */ ModuleInfo utils = new ModuleInfo("os"); - // syscall(string, int): void —— 供标准库内部使用的调用接口 - utils.getFunctions().put( - "syscall", - new FunctionType( - Arrays.asList(BuiltinType.STRING, BuiltinType.INT), - BuiltinType.VOID - ) - ); + /* syscall(string, type): void 的一组重载 */ + List overloading = new ArrayList<>(); + { + // syscall(string, byte): void + overloading.add(new FunctionType( + Arrays.asList(BuiltinType.STRING, BuiltinType.BYTE), + BuiltinType.VOID + )); + + // syscall(string, short): void + overloading.add(new FunctionType( + Arrays.asList(BuiltinType.STRING, BuiltinType.SHORT), + BuiltinType.VOID + )); + + // syscall(string, int): void + overloading.add(new FunctionType( + Arrays.asList(BuiltinType.STRING, BuiltinType.INT), + BuiltinType.VOID + )); + + // syscall(string, long): void + overloading.add(new FunctionType( + Arrays.asList(BuiltinType.STRING, BuiltinType.LONG), + BuiltinType.VOID + )); + + // syscall(string, float): void + overloading.add(new FunctionType( + Arrays.asList(BuiltinType.STRING, BuiltinType.FLOAT), + BuiltinType.VOID + )); + + // syscall(string, double): void + overloading.add(new FunctionType( + Arrays.asList(BuiltinType.STRING, BuiltinType.DOUBLE), + BuiltinType.VOID + )); + + // syscall(string, boolean): void + overloading.add(new FunctionType( + Arrays.asList(BuiltinType.STRING, BuiltinType.BOOLEAN), + BuiltinType.VOID + )); + } + + // syscall(string, `type`): void —— 供标准库内部使用的调用接口 + utils.getFunctions().put("syscall", overloading); // 注册 BuiltinUtils 到上下文的模块表(若已存在则不重复添加) ctx.getModules().putIfAbsent("os", utils); diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/core/ModuleInfo.java b/src/main/java/org/jcnc/snow/compiler/semantic/core/ModuleInfo.java index 0761d50..3c211d9 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/core/ModuleInfo.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/core/ModuleInfo.java @@ -1,6 +1,7 @@ package org.jcnc.snow.compiler.semantic.core; import org.jcnc.snow.compiler.semantic.type.FunctionType; +import org.jcnc.snow.compiler.semantic.type.Type; import java.util.*; @@ -25,8 +26,8 @@ public class ModuleInfo { /** 该模块显式导入的模块名集合(用于跨模块访问符号) */ private final Set imports = new HashSet<>(); - /** 该模块中定义的函数名 → 函数类型映射 */ - private final Map functions = new HashMap<>(); + /** 该模块中定义的函数名 → 函数类型列表映射 */ + private final Map> functions = new HashMap<>(); /** * 构造模块信息对象。 @@ -65,8 +66,57 @@ public class ModuleInfo { * * @return 模块内函数定义映射表 */ - public Map getFunctions() { + public Map> getFunctions() { return functions; } + /** + * 添加一个新的函数类型 + * + * @param name 函数名 + * @param ft 函数类型 + */ + public void addFunction(String name, FunctionType ft) { + if (!functions.containsKey(name)) { + functions.put(name, new ArrayList<>()); + } + + functions.get(name).add(ft); + } + + /** + * 判断函数类型是否存在 + * + * @param name 函数名 + * @param ft 函数类型 + * @return 函数类型存在则返回 true,否则 false + */ + public boolean existsFunction(String name, FunctionType ft) { + if (!functions.containsKey(name)) { + return false; + } + + return functions.get(name).stream().anyMatch((t) -> t.equals(ft)); + } + + /** + * 检索函数类型 + * 通过函数名和参数列表唯一确定一个函数类型 + * + * @param name 函数名 + * @param params 参数列表 + * @return 唯一确定的函数类型,不存在则返回 null + */ + public FunctionType retrieveFunction(String name, List params) { + List fts = functions.get(name); + if (fts != null) { + for (FunctionType ft : fts) { + if (ft.paramTypes().equals(params)) { + return ft; + } + } + } + + return null; + } } diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/core/SignatureRegistrar.java b/src/main/java/org/jcnc/snow/compiler/semantic/core/SignatureRegistrar.java index e542646..8ddbed1 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/core/SignatureRegistrar.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/core/SignatureRegistrar.java @@ -78,8 +78,17 @@ public record SignatureRegistrar(Context ctx) { Type ret = Optional.ofNullable(ctx.parseType(fn.returnType())) .orElse(BuiltinType.VOID); - // 注册函数签名 - mi.getFunctions().put(fn.name(), new FunctionType(params, ret)); + FunctionType ft = new FunctionType(params, ret); + if (mi.existsFunction(fn.name(), ft)) { + ctx.errors().add(new SemanticError( + fn, + "有歧义的函数: " + fn.name() + )); + } + else { + // 注册函数签名 + mi.addFunction(fn.name(), ft); + } } } }