Exemplo n.º 1
0
        public static ConcreteUserFunction BuildConcrete(
            this UserFunctionDefinitionSyntaxNode functionSyntax,
            FunnyType[] argTypes,
            FunnyType returnType,
            IFunctionDictionary functionsDictionary,
            TypeInferenceResults results,
            TicTypesConverter converter)
        {
            var vars = new VariableDictionary(functionSyntax.Args.Count);

            for (int i = 0; i < functionSyntax.Args.Count; i++)
            {
                var variableSource = RuntimeBuilderHelper.CreateVariableSourceForArgument(
                    argSyntax: functionSyntax.Args[i],
                    actualType: argTypes[i]);

                if (!vars.TryAdd(variableSource))
                {
                    throw ErrorFactory.FunctionArgumentDuplicates(functionSyntax, functionSyntax.Args[i]);
                }
            }

            var bodyExpression = ExpressionBuilderVisitor.BuildExpression(
                node: functionSyntax.Body,
                functions: functionsDictionary,
                outputType: returnType,
                variables: vars,
                typeInferenceResults: results,
                typesConverter: converter);

            vars.ThrowIfSomeVariablesNotExistsInTheList(
                functionSyntax.Args.Select(a => a.Id));

            var function = ConcreteUserFunction.Create(
                isRecursive: functionSyntax.IsRecursive,
                name: functionSyntax.Id,
                variables: vars.GetAllSources().ToArray(),
                isReturnTypeStrictlyTyped: functionSyntax.ReturnType != FunnyType.Empty,
                expression: bodyExpression);

            return(function);
        }
Exemplo n.º 2
0
        private IExpressionNode BuildAnonymousFunction(Interval interval, ISyntaxNode body,
                                                       VariableDictionary localVariables, VariableSource[] arguments)
        {
            var sources         = localVariables.GetAllSources().ToArray();
            var originVariables = new string[sources.Length];

            for (int i = 0; i < originVariables.Length; i++)
            {
                originVariables[i] = sources[i].Name;
            }

            var expr = BuildExpression(body, _functions, localVariables, _typeInferenceResults, _typesConverter);

            //New variables are new closured
            var closured = localVariables.GetAllUsages()
                           .Where(s => !originVariables.Contains(s.Source.Name))
                           .ToList();

            if (closured.Any(c => Helper.DoesItLooksLikeSuperAnonymousVariable(c.Source.Name)))
            {
                throw FunParseException.ErrorStubToDo("Unexpected it* variable");
            }

            //Add closured vars to outer-scope dictionary
            foreach (var newVar in closured)
            {
                _variables.TryAdd(newVar); //add full usage info to allow analyze outer errors
            }
            var fun = ConcreteUserFunction.Create(
                isRecursive: false,
                name: "anonymous",
                variables: arguments,
                isReturnTypeStrictlyTyped: false,
                expression: expr);

            return(new FunVariableExpressionNode(fun, interval));
        }