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); }
private static Equation BuildEquationAndPutItToVariables( EquationSyntaxNode equation, IFunctionDictionary functionsDictionary, VariableDictionary variables, TypeInferenceResults typeInferenceResults) { var expression = ExpressionBuilderVisitor.BuildExpression( node: equation.Expression, functions: functionsDictionary, outputType: equation.OutputType, variables: variables, typeInferenceResults: typeInferenceResults, typesConverter: TicTypesConverter.Concrete); VariableSource outputVariableSource; if (equation.OutputTypeSpecified) { outputVariableSource = VariableSource.CreateWithStrictTypeLabel( name: equation.Id, type: equation.OutputType, typeSpecificationIntervalOrNull: equation.TypeSpecificationOrNull.Interval, attributes: equation.Attributes, isOutput: true); } else { outputVariableSource = VariableSource.CreateWithoutStrictTypeLabel( name: equation.Id, type: equation.OutputType, isOutput: true, equation.Attributes); } var itVariable = variables.GetSuperAnonymousVariableOrNull(); if (itVariable != null) { throw FunParseException.ErrorStubToDo("Variable cannot starts with it"); } if (!variables.TryAdd(outputVariableSource)) { //some equation referenced the source before var usages = variables.GetUsages(equation.Id); if (usages.Source.IsOutput) { throw ErrorFactory.OutputNameWithDifferentCase(equation.Id, equation.Expression.Interval); } else { throw ErrorFactory.CannotUseOutputValueBeforeItIsDeclared(usages); } } //ReplaceInputType if (outputVariableSource.Type != expression.Type) { throw new ImpossibleException("fitless"); } return(new Equation(equation.Id, expression, outputVariableSource)); }