public IExpressionNode Visit(SuperAnonymFunctionSyntaxNode arrowAnonymFunNode) { var outputTypeFunDefinition = arrowAnonymFunNode.OutputType.FunTypeSpecification; if (outputTypeFunDefinition == null) { throw new ImpossibleException("Fun definition expected"); } string[] argNames = null; if (outputTypeFunDefinition.Inputs.Length == 1) { argNames = new[] { "it" } } ; else { argNames = new string[outputTypeFunDefinition.Inputs.Length]; for (int i = 0; i < outputTypeFunDefinition.Inputs.Length; i++) { argNames[i] = $"it{i + 1}"; } } //Prepare local variable scope //Capture all outerscope variables var localVariables = new VariableDictionary(_variables.GetAllSources()); var arguments = new VariableSource[argNames.Length]; for (var i = 0; i < argNames.Length; i++) { var arg = argNames[i]; var type = outputTypeFunDefinition.Inputs[i]; var source = VariableSource.CreateWithoutStrictTypeLabel(arg, type, false); //collect argument arguments[i] = source; //add argument to local scope //if argument with it* name already exist - replace it localVariables.AddOrReplace(source); } var body = arrowAnonymFunNode.Body; return(BuildAnonymousFunction(arrowAnonymFunNode.Interval, body, localVariables, arguments)); }
private static VariableSource CreateVariableSourceForArgument( TypedVarDefSyntaxNode argSyntax, FunnyType actualType) { if (argSyntax.FunnyType != FunnyType.Empty) { return(VariableSource.CreateWithStrictTypeLabel( name: argSyntax.Id, type: actualType, typeSpecificationIntervalOrNull: argSyntax.Interval, isOutput: false)); } else { return(VariableSource.CreateWithoutStrictTypeLabel( name: argSyntax.Id, type: actualType, isOutput: false)); } }
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)); }