Exemple #1
0
    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;
 }
Exemple #3
0
        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()));
        }
Exemple #4
0
        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()));
        }
Exemple #5
0
        /// <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);
        }
Exemple #6
0
 public virtual void VisitCallExpression(CallExpressionSyntax node) =>
 this.DefaultVisit(node);