private static TypeInferenceResults SolveBodyTypes( SyntaxTree syntaxTree, IConstantList constants, IFunctionDictionary functionDictionary, AprioriTypesMap aprioriTypes) { var bodyTypeSolving = RuntimeBuilderHelper.SolveBodyOrThrow( syntaxTree, functionDictionary, constants, aprioriTypes); var enterVisitor = new ApplyTiResultEnterVisitor(bodyTypeSolving, TicTypesConverter.Concrete); var exitVisitor = new ApplyTiResultsExitVisitor(); foreach (var syntaxNode in syntaxTree.Nodes) { //function nodes were solved above if (syntaxNode is UserFunctionDefinitionSyntaxNode) { continue; } //set types to nodes syntaxNode.ComeOver(enterVisitor, exitVisitor); } return(bodyTypeSolving); }
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); }