public override void ExitFunctionCall([NotNull] PigeonParser.FunctionCallContext context) { var functionName = context.ID().GetText(); if (!GlobalScope.TryGetFunction(functionName, out var function)) { errorBag.ReportUndeclaredFunction(context.GetTextSpan(), functionName); return; } var argumentCount = context.functionArgs()?.expr()?.Length ?? 0; if (argumentCount != function.Parameters.Length) { errorBag.ReportInvalidNumberOfArguments(context.GetTextSpan(), functionName, function.Parameters.Length); return; } for (var i = 0; i < argumentCount; ++i) { var argument = context.functionArgs().expr(i); var argumentType = Types.Get(argument); if (function.Parameters[i].Type != PigeonType.Any && argumentType != function.Parameters[i].Type) { errorBag.ReportInvalidArgumentType(argument.GetTextSpan(), i + 1, function.Parameters[i].Type, argumentType); } } }
public override void EnterFunctionDecl([NotNull] PigeonParser.FunctionDeclContext context) { scope = new Scope(GlobalScope); GlobalScope.TryGetFunction(context.ID().GetText(), out var function); foreach (var parameter in function.Parameters) { scope.DeclareVariable(parameter.Type, parameter.Name, parameter.ReadOnly); } }
public override void ExitFunctionCallExpression([NotNull] PigeonParser.FunctionCallExpressionContext context) { var functionName = context.functionCall().ID().GetText(); if (GlobalScope.TryGetFunction(functionName, out var function)) { Types.Put(context, function.ReturnType); } else { Types.Put(context, PigeonType.Error); errorBag.ReportUndeclaredFunction(context.GetTextSpan(), functionName); } }
public override void ExitReturnStatement([NotNull] PigeonParser.ReturnStatementContext context) { var returnType = context.expr() != null?Types.Get(context.expr()) : PigeonType.Void; RuleContext node = context; while (!(node is PigeonParser.FunctionDeclContext)) { node = node.Parent; } var functionName = ((PigeonParser.FunctionDeclContext)node).ID().GetText(); GlobalScope.TryGetFunction(functionName, out var function); if (returnType != function.ReturnType) { if (!NumberTypes(returnType, function.ReturnType)) { errorBag.ReportUnexpectedType(context.expr().GetTextSpan(), function.ReturnType, returnType); } } }