private BoundExpression BindCallExpression(CallExpressionSyntax syntax) { if (syntax.Arguments.Count == 1 && TypeSymbol.Lookup(syntax.Identifier.Text) is TypeSymbol type) { return(this.BindConversion(syntax.Arguments[0], type, allowExplicit: true)); } var functions = BuiltinFunctions.GetAll(); var function = functions.SingleOrDefault(_ => _.Name == syntax.Identifier.Text); if (function == null) { this.Diagnostics.ReportUndefinedFunction(syntax.Identifier); return(new BoundErrorExpression(syntax)); } if (syntax.Arguments.Count != function.Parameters.Length) { this.Diagnostics.ReportWrongArgumentCount(syntax.Location, function.Name, function.Parameters.Length, syntax.Arguments.Count); return(new BoundErrorExpression(syntax)); } var boundArguments = ImmutableArray.CreateBuilder <BoundExpression>(); foreach (var argument in syntax.Arguments) { var boundArgument = this.BindExpression(argument); boundArguments.Add(boundArgument); } for (var i = 0; i < syntax.Arguments.Count; i++) { var argumentLocation = syntax.Arguments[i].Location; var argument = boundArguments[i]; var parameter = function.Parameters[i]; boundArguments[i] = this.BindConversion(argumentLocation, argument, parameter.Type); } if (function == BuiltinFunctions.E || function == BuiltinFunctions.N) { if (boundArguments[0] is BoundLiteralExpression literalArgument && literalArgument.Type == TypeSymbol.Integer) { var targetLineNumber = (BigInteger)literalArgument.Value; this.LineNumberValidations.Add((targetLineNumber, syntax.Arguments[0].Location)); } } if (function == BuiltinFunctions.Defer) { this.deferWasInvoked = syntax; this.doesStatementExistAfterDefer = false; } return(new BoundCallExpression(syntax, function, boundArguments.ToImmutable())); }
public ObjectAccessExpression(SyntaxTree syntaxTree, SyntaxToken identifierToken, AccessType type, CallExpressionSyntax call, SyntaxToken lookingFor, ExpressionSyntax value, SyntaxToken package, ExpressionSyntax expression) : base(syntaxTree) { IdentifierToken = identifierToken; Type = type; Call = call; LookingFor = lookingFor; Value = value; Package = package; Expression = expression; }
private BoundExpression BindCallExpression(CallExpressionSyntax syntax) { var arguments = ImmutableArray.CreateBuilder <BoundExpression>(); foreach (var argument in syntax.Arguments) { var boundArgument = BindExpression(argument); arguments.Add(boundArgument); } var functions = BuiltinFunctions.GetAll(); var function = functions.SingleOrDefault(f => f.Name == syntax.IdentifierToken.Text); if (function == null) { _diagnostics.ReportUndefinedFunction(syntax.IdentifierToken.Span, syntax.IdentifierToken.Text); return(new BoundErrorExpression()); } if (syntax.Arguments.Count != function.Parameters.Length) { _diagnostics.ReportIncorrectArgumentCount(syntax.Span, function.Name, function.Parameters.Length, syntax.Arguments.Count); return(new BoundErrorExpression()); } for (var i = 0; i < function.Parameters.Length; i++) { var parameter = function.Parameters[i]; var argument = arguments[i]; if (parameter.Type != argument.Type) { _diagnostics.ReportTypeMismatch(syntax.Span, argument.Type, function.Parameters[i].Type); return(new BoundErrorExpression()); } } return(new BoundCallExpression(function, arguments.ToImmutable())); }
private BoundExpression BindCallExpression(CallExpressionSyntax syntax) { if (syntax.Arguments.Count == 1 && LookupType(syntax.Identifier.Text) is TypeSymbol type) { return(BindConversion(syntax.Arguments[0], type, allowExplicit: true)); } var boundArguments = ImmutableArray.CreateBuilder <BoundExpression>(); foreach (var argument in syntax.Arguments) { var boundArgument = BindExpression(argument); boundArguments.Add(boundArgument); } if (!_scope.TryLookupFunction(syntax.Identifier.Text, out var function)) { _diagnostics.ReportUndefinedFunction(syntax.Identifier.Span, syntax.Identifier.Text); return(new BoundErrorExpression()); } if (syntax.Arguments.Count != function.Parameters.Length) { _diagnostics.ReportWrongArgumentCount(syntax.Span, function.Name, function.Parameters.Length, syntax.Arguments.Count); return(new BoundErrorExpression()); } for (var i = 0; i < syntax.Arguments.Count; i++) { var argument = boundArguments[i]; var parameter = function.Parameters[i]; if (argument.Type != parameter.Type) { _diagnostics.ReportWrongArgumentType(syntax.Arguments[i].Span, parameter.Name, parameter.Type, argument.Type); return(new BoundErrorExpression()); } } return(new BoundCallExpression(function, boundArguments.ToImmutable())); }
/// <summary> /// Tries to get a function from this imported class symbol. /// </summary> /// <param name="text">The name of the function.</param> /// <param name="callExpression">The call expression.</param> /// <param name="arguments">The bound arguments.</param> /// <param name="function">The resulting function, if one is found.</param> /// <returns>Whether we found a matching function or not.</returns> public bool TryLookupFunction(string text, CallExpressionSyntax callExpression, ImmutableArray <BoundExpression> arguments, out ImportedFunctionSymbol function) { function = null; var methods = ClassType.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); var nameMatches = methods.Where(m => m.Name == text).ToList(); foreach (var match in nameMatches) { var parameters = match.GetParameters(); if (arguments.Length != parameters.Length) { continue; } bool hasMatchError = false; for (var i = 0; i < arguments.Length; i++) { var argument = arguments[i]; var parameter = parameters[i]; if (!TypesMatch(argument.Type, parameter.ParameterType)) { hasMatchError = true; break; } } if (!hasMatchError) { function = new ImportedFunctionSymbol(text, this, match, callExpression); return(true); } } return(false); }
public virtual void VisitCallExpression(CallExpressionSyntax node) => this.DefaultVisit(node);