Beispiel #1
0
        public override RuntimeValueNode Evaluate()
        {
            // var functionNode = RuntimeScope.ResolveSymbolNode(Operator.Left.Root as SymbolNode);
            // var function = functionNode.Symbol as FunctionType;

            var function     = (Operator as OperatorInvoke).Function;
            var functionNode = function.Root;

            var             functionScope = RuntimeScope.Resolve(function.Scope);
            RuntimeFunction runtimeFunction;

            var argumentsNode = Operator.Right.Root as ArgumentsNode;
            var arguments     = argumentsNode.Arguments;

            if (!function.ExpectsThisArg)
            {
                arguments = arguments.Where(a => !a.IsThisArg).ToArray();
            }

            var argumentsValues = arguments
                                  .Select(arg => {
                var exp = new RuntimeExpression(
                    arg.Expression,
                    RuntimeScope
                    );
                return(exp.Evaluate());
            })
                                  .Cast <RuntimeValueNode>();

            if (function.Name == "!constructor")
            {
                var constructingType = function.Scope.GetClosestType();
                var typeInstance     = new RuntimeClassInstanceValueNode(
                    functionNode,
                    constructingType,
                    RuntimeScope.Resolve(constructingType.Scope)
                    );

                var constr = typeInstance.AccessMember("!constructor");
                runtimeFunction = new RuntimeFunction(
                    function,
                    constr.RuntimeScope,
                    argumentsValues.ToArray()
                    );

                runtimeFunction.Evaluate();
                return(typeInstance);
            }
            else
            {
                var left = new RuntimeExpression(
                    Operator.Left,
                    RuntimeScope//.ResolveRuntimeScope(Operator.Left.Scope)
                    ).Evaluate();

                if (!(left is RuntimeFunctionValueNode))
                {
                    throw new Exceptions.RuntimeException("Cannot invoke non-function", Operator.Left.DefiningToken);
                }

                var functionType = left.Value as FunctionType;
                var overload     = functionType.GetMatchingOverload(arguments, FunctionType.ArgumentParameterSpecificity.Bidirectional);

                runtimeFunction = new RuntimeFunction(
                    overload,
                    RuntimeScope.Resolve(overload.Scope),
                    argumentsValues.ToArray()
                    );
                return(runtimeFunction.Evaluate());
            }
        }