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 c71f54a..ee30418 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 @@ -1,44 +1,74 @@ package org.jcnc.snow.compiler.semantic.analyzers.expression; -import org.jcnc.snow.compiler.parser.ast.*; +import org.jcnc.snow.compiler.parser.ast.CallExpressionNode; +import org.jcnc.snow.compiler.parser.ast.FunctionNode; +import org.jcnc.snow.compiler.parser.ast.IdentifierNode; +import org.jcnc.snow.compiler.parser.ast.MemberExpressionNode; import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode; -import org.jcnc.snow.compiler.parser.ast.base.NodeContext; import org.jcnc.snow.compiler.semantic.analyzers.base.ExpressionAnalyzer; import org.jcnc.snow.compiler.semantic.core.Context; import org.jcnc.snow.compiler.semantic.core.ModuleInfo; import org.jcnc.snow.compiler.semantic.error.SemanticError; +import org.jcnc.snow.compiler.semantic.symbol.Symbol; import org.jcnc.snow.compiler.semantic.symbol.SymbolTable; 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; import java.util.List; /** - * {@code CallExpressionAnalyzer} 是函数调用表达式的语义分析器。 - *

- * 它负责处理类似 {@code callee(arg1, arg2, ...)} 形式的调用表达式,执行如下操作: + * {@code CallExpressionAnalyzer} 是函数调用表达式 ({@link CallExpressionNode}) 的语义分析器。 + * + *

它负责处理所有形式的调用表达式(如 {@code callee(arg1, arg2, ...)}),并执行如下操作: *

+ * + *

此分析器是编译器语义分析阶段的重要组成部分,确保调用表达式在类型系统和模块作用域中合法。

*/ public class CallExpressionAnalyzer implements ExpressionAnalyzer { /** - * 分析函数调用表达式并推断其类型。 + * 分析函数调用表达式,推断返回类型并执行语义检查。 * * @param ctx 当前语义分析上下文,提供日志、错误记录、模块访问等功能。 * @param mi 当前模块信息,用于函数查找及模块依赖判断。 - * @param fn 当前分析的函数节点。 - * @param locals 局部符号表,用于变量查找。 + * @param fn 当前正在分析的函数节点(函数作用域)。 + * @param locals 局部符号表,用于变量和结构体实例查找。 * @param call 待分析的函数调用表达式节点。 - * @return 表达式的返回类型。如果存在语义错误,默认返回 {@code BuiltinType.INT}。 + * @return 调用表达式的返回类型;若存在语义错误,返回 {@link BuiltinType#INT}。 */ @Override public Type analyze(Context ctx, @@ -46,88 +76,148 @@ 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()) { + // -------- 参数数量检查 -------- + if (args.size() != funcType.paramTypes().size()) { ctx.getErrors().add(new SemanticError(call, - "参数数量不匹配: 期望 " + ft.paramTypes().size() + "参数数量不匹配: 期望 " + funcType.paramTypes().size() + " 个, 实际 " + args.size() + " 个")); ctx.log("错误: 参数数量不匹配: 期望 " - + ft.paramTypes().size() + ", 实际 " + args.size()); - + + funcType.paramTypes().size() + ", 实际 " + args.size()); } else { - // 参数类型检查与转换支持 + // -------- 参数类型检查与转换 -------- for (int i = 0; i < args.size(); i++) { - Type expected = ft.paramTypes().get(i); - Type actual = args.get(i); + Type expected = funcType.paramTypes().get(i); + Type actual = args.get(i); - // 完全兼容或数值宽化转换 boolean ok = expected.isCompatible(actual) || (expected.isNumeric() && actual.isNumeric() && Type.widen(actual, expected) == expected); - // 支持将数值自动转换为字符串 + // 特殊情况:数值自动转 string if (!ok && expected == BuiltinType.STRING && actual.isNumeric()) { ctx.log(String.format( "隐式将参数 %d 的数值类型 %s 转换为 string (to_string)", @@ -136,7 +226,6 @@ public class CallExpressionAnalyzer implements ExpressionAnalyzer