コード例 #1
0
        public override IConcreteFunction CreateConcrete(FunnyType[] concreteTypes)
        {
            BuiltCount++;

            var id = string.Join(",", concreteTypes);

            if (_concreteFunctionsCache.TryGetValue(id, out var alreadyExists))
            {
                return(alreadyExists);
            }
            //set types to nodes
            var converter    = TicTypesConverter.ReplaceGenericTypesConverter(_constrainsMap, concreteTypes);
            var ticSignature = _typeInferenceResults.GetVariableType(_syntaxNode.Id + "'" + _syntaxNode.Args.Count);
            var funType      = converter.Convert(ticSignature);

            var returnType = funType.FunTypeSpecification.Output;
            var argTypes   = funType.FunTypeSpecification.Inputs;

            // Create a function prototype and put it to cache for recursive cases
            // If the function is recursive - function will take recursive prototype from cache
            var concretePrototype = new ConcreteUserFunctionPrototype(Name, returnType, argTypes);

            _concreteFunctionsCache.Add(id, concretePrototype);

            _syntaxNode.ComeOver(
                enterVisitor: new ApplyTiResultEnterVisitor(
                    solving: _typeInferenceResults,
                    tiToLangTypeConverter: converter),
                exitVisitor: new ApplyTiResultsExitVisitor());

            var function = _syntaxNode.BuildConcrete(
                argTypes:   argTypes,
                returnType: returnType,
                functionsDictionary: _dictionary,
                results:    _typeInferenceResults,
                converter:  converter);

            concretePrototype.SetActual(function, _syntaxNode.Interval);
            return(function);
        }
コード例 #2
0
ファイル: RuntimeBuilder.cs プロジェクト: tmteam/NFun
        private static IFunctionSignature BuildFunctionAndPutItToDictionary(
            UserFunctionDefinitionSyntaxNode functionSyntaxNode,
            IConstantList constants,
            ScopeFunctionDictionary functionsDictionary)
        {
#if DEBUG
            TraceLog.WriteLine($"\r\n====BUILD {functionSyntaxNode.Id}(..) ====");
#endif
            ////introduce function variable
            var         graphBuider    = new GraphBuilder();
            var         resultsBuilder = new TypeInferenceResultsBuilder();
            ITicResults types;

            try
            {
                if (!TicSetupVisitor.SetupTicForUserFunction(
                        userFunctionNode: functionSyntaxNode,
                        ticGraph:  graphBuider,
                        functions: functionsDictionary,
                        constants: constants,
                        results:   resultsBuilder))
                {
                    throw FunParseException.ErrorStubToDo($"Function '{functionSyntaxNode.Id}' is not solved");
                }

                // solve the types
                types = graphBuider.Solve();
            }
            catch (TicException e) { throw ErrorFactory.TranslateTicError(e, functionSyntaxNode); }

            resultsBuilder.SetResults(types);
            var typeInferenceResuls = resultsBuilder.Build();

            if (!types.HasGenerics)
            {
                #region concreteFunction

                //set types to nodes
                functionSyntaxNode.ComeOver(
                    enterVisitor: new ApplyTiResultEnterVisitor(
                        solving: typeInferenceResuls,
                        tiToLangTypeConverter: TicTypesConverter.Concrete),
                    exitVisitor: new ApplyTiResultsExitVisitor());

                var funType = TicTypesConverter.Concrete.Convert(
                    typeInferenceResuls.GetVariableType(functionSyntaxNode.Id + "'" + functionSyntaxNode.Args.Count));

                var returnType = funType.FunTypeSpecification.Output;
                var argTypes   = funType.FunTypeSpecification.Inputs;
                if (TraceLog.IsEnabled)
                {
                    TraceLog.WriteLine($"\r\n=====> Generic {functionSyntaxNode.Id} {funType}");
                }
                //make function prototype
                var prototype = new ConcreteUserFunctionPrototype(functionSyntaxNode.Id, returnType, argTypes);
                //add prototype to dictionary for future use
                functionsDictionary.Add(prototype);
                var function =
                    functionSyntaxNode.BuildConcrete(
                        argTypes:   argTypes,
                        returnType: returnType,
                        functionsDictionary: functionsDictionary,
                        results:    typeInferenceResuls,
                        converter:  TicTypesConverter.Concrete);

                prototype.SetActual(function, functionSyntaxNode.Interval);
                return(function);

                #endregion
            }
            else
            {
                var function = GenericUserFunction.Create(typeInferenceResuls, functionSyntaxNode, functionsDictionary);
                functionsDictionary.Add(function);
                if (TraceLog.IsEnabled)
                {
                    TraceLog.WriteLine($"\r\n=====> Concrete {functionSyntaxNode.Id} {function}");
                }
                return(function);
            }
        }