Пример #1
0
        public static string ToFailureFunString(FunCallSyntaxNode headNode, ISyntaxNode headNodeChild)
        {
            StringBuilder sb = new StringBuilder();

            foreach (var child in headNode.Args)
            {
                if (child == headNodeChild)
                {
                    sb.Append("???");
                }
                if (child is VarDefinitionSyntaxNode varDef)
                {
                    sb.Append(varDef.Id);
                }
                else if (child is NamedIdSyntaxNode varSyntax)
                {
                    sb.Append(varSyntax.Id);
                }

                if (headNode.Args.Last() != child)
                {
                    sb.Append(",");
                }
            }

            return(sb.ToString());
        }
Пример #2
0
        public static Exception WrongFunctionArgumentDefinition(FunCallSyntaxNode headNode, ISyntaxNode headNodeChild)
        {
            var sb = ErrorsHelper.ToFailureFunString(headNode, headNodeChild);

            return(new FunParseException(336,
                                         $"{headNode.Id}({sb}) = ... {Nl} Function argument is invalid. Variable name (with optional type) expected",
                                         headNodeChild.Interval));
        }
Пример #3
0
        public IExpressionNode Visit(FunCallSyntaxNode node)
        {
            var id = node.Id;

            var someFunc = node.FunctionSignature ?? _functions.GetOrNull(id, node.Args.Length);

            if (someFunc is null)
            {
                //todo move to variable syntax node
                //hi order function
                var functionalVariableSource = _variables.GetSourceOrNull(id);
                if (functionalVariableSource?.Type.FunTypeSpecification == null)
                {
                    throw ErrorFactory.FunctionOverloadNotFound(node, _functions);
                }
                return(CreateFunctionCall(node, ConcreteHiOrderFunction.Create(functionalVariableSource)));
            }

            if (someFunc is IConcreteFunction f) //concrete function
            {
                return(CreateFunctionCall(node, f));
            }

            if (someFunc is IGenericFunction genericFunction) //generic function
            {
                FunnyType[] genericArgs;
                // Generic function type arguments usually stored in tic results
                var genericTypes = _typeInferenceResults.GetGenericCallArguments(node.OrderNumber);
                if (genericTypes == null)
                {
                    // Generic call arguments are unknown  in case of generic recursion function .
                    // Take them from type inference results
                    var recCallSignature = _typeInferenceResults.GetRecursiveCallOrNull(node.OrderNumber);
                    //if generic call arguments not exist in type inference result - it is NFUN core error
                    if (recCallSignature == null)
                    {
                        throw new ImpossibleException($"MJ78. Function {id}`{node.Args.Length} was not found");
                    }

                    var varTypeCallSignature = _typesConverter.Convert(recCallSignature);
                    //Calculate generic call arguments by concrete function signature
                    genericArgs = genericFunction.CalcGenericArgTypeList(varTypeCallSignature.FunTypeSpecification);
                }
                else
                {
                    genericArgs = new FunnyType[genericTypes.Length];
                    for (int i = 0; i < genericTypes.Length; i++)
                    {
                        genericArgs[i] = _typesConverter.Convert(genericTypes[i]);
                    }
                }

                var function = genericFunction.CreateConcrete(genericArgs);
                return(CreateFunctionCall(node, function));
            }

            throw new ImpossibleException($"MJ101. Function {id}`{node.Args.Length} type is unknown");
        }
Пример #4
0
        public static Exception FunctionOverloadNotFound(FunCallSyntaxNode node, IFunctionDictionary functions)
        {
            var           candidates = functions.SearchAllFunctionsIgnoreCase(node.Id, node.Args.Length);
            StringBuilder msg        = new StringBuilder($"Function '{node.Id}({string.Join(",", node.Args.Select(_ => "_"))})' is not found. ");

            if (candidates.Any())
            {
                var candidate = candidates.First();
                msg.Append(
                    $"\r\nDid you mean function '{TypeHelper.GetFunSignature(candidate.Name, candidate.ReturnType, candidate.ArgTypes)}' ?");
            }
            return(new FunParseException(533, msg.ToString(), node.Interval));
        }
Пример #5
0
        public static Exception FunctionArgumentInBracketDefinition(FunCallSyntaxNode headNode, ISyntaxNode headNodeChild,
                                                                    Tok flowCurrent)
        {
            if (flowCurrent == null)
            {
                throw new ArgumentNullException(nameof(flowCurrent));
            }
            var sb = ErrorsHelper.ToFailureFunString(headNode, headNodeChild);

            return(new FunParseException(339,
                                         $"{headNode.Id}({sb}) = ... {Nl} Function argument is in bracket. Variable name (with optional type) without brackets expected",
                                         headNodeChild.Interval.Start, headNodeChild.Interval.Finish));
        }
Пример #6
0
        public override VisitorEnterResult Visit(FunCallSyntaxNode node)
        {
            var nodeName = node.Id + "(" + node.Args.Length + ")";

            if (nodeName == _functionAlias)
            {
                HasSelfRecursion = true;
            }
            else if (_userFunctionsNames.TryGetValue(nodeName, out int id))
            {
                _dependencies.Add(id);
            }
            return(VisitorEnterResult.Continue);
        }
Пример #7
0
 public static Exception OperatorOverloadNotFound(FunCallSyntaxNode node, ISyntaxNode failedArg)
 {
     return(new FunParseException(536,
                                  $"Invalid argument type for '{node.Id}' operator",
                                  failedArg.Interval));
 }
Пример #8
0
 public static Exception UnexpectedBracketsOnFunDefinition(FunCallSyntaxNode headNode, int start, int finish)
 => new FunParseException(333, $"Unexpected brackets on function definition ({headNode.Id}(...))=... {Nl}Example: {headNode.Id}(...)=...",
                          start, finish);
Пример #9
0
 public static Exception AttributeOnFunction(FunCallSyntaxNode lexNode)
 => new FunParseException(288, $"Function cannot has attributes.", lexNode.Interval);
Пример #10
0
 public virtual VisitorEnterResult Visit(FunCallSyntaxNode node) => DefaultVisitEnter(node);
Пример #11
0
        public bool Visit(FunCallSyntaxNode node)
        {
            var signature = _dictionary.GetOrNull(node.Id, node.Args.Length);

            node.FunctionSignature = signature;
            //Apply visitor to child types
            for (int i = 0; i < node.Args.Length; i++)
            {
                if (signature != null)
                {
                    _parentFunctionArgType = signature.ArgTypes[i];
                }
                node.Args[i].Accept(this);
            }
            //Setup ids arrays
            var ids = new int[node.Args.Length + 1];

            for (int i = 0; i < node.Args.Length; i++)
            {
                ids[i] = node.Args[i].OrderNumber;
            }
            ids[ids.Length - 1] = node.OrderNumber;

            var userFunction = _resultsBuilder.GetUserFunctionSignature(node.Id, node.Args.Length);

            if (userFunction != null)
            {
                //Call user-function if it is being built at the same time as the current expression is being built
                //for example: recursive calls, or if function relates to global variables
#if DEBUG
                Trace(node, $"Call UF{node.Id}({string.Join(",", ids)})");
#endif
                _ticTypeGraph.SetCall(userFunction, ids);
                //in the case of generic user function  - we dont know generic arg types yet
                //we need to remember generic TIC signature to used it at the end of interpritation
                _resultsBuilder.RememberRecursiveCall(node.OrderNumber, userFunction);
                return(true);
            }

            if (signature == null)
            {
                //Functional variable
#if DEBUG
                Trace(node, $"Call hi order {node.Id}({string.Join(",", ids)})");
#endif
                _ticTypeGraph.SetCall(node.Id, ids);
                return(true);
            }
            //Normal function call
#if DEBUG
            Trace(node, $"Call {node.Id}({string.Join(",", ids)})");
#endif
            if (signature is PureGenericFunctionBase pure)
            {
                // Сase of (T,T):T signatures
                // This case is most common, so the call is optimized
                var genericType = InitializeGenericType(pure.Constrainses[0]);
                _resultsBuilder.RememberGenericCallArguments(node.OrderNumber, new[] { genericType });
                _ticTypeGraph.SetCall(genericType, ids);
                return(true);
            }
            StateRefTo[] genericTypes;
            if (signature is GenericFunctionBase t)
            {
                // Optimization
                // Remember generic arguments to use it again at the built time
                genericTypes = InitializeGenericTypes(t.Constrainses);
                // save refernces to generic types, for use at 'apply tic results' step
                _resultsBuilder.RememberGenericCallArguments(node.OrderNumber, genericTypes);
            }
            else
            {
                genericTypes = new StateRefTo[0];
            }

            var types = new ITicNodeState[signature.ArgTypes.Length + 1];
            for (int i = 0; i < signature.ArgTypes.Length; i++)
            {
                types[i] = signature.ArgTypes[i].ConvertToTiType(genericTypes);
            }
            types[types.Length - 1] = signature.ReturnType.ConvertToTiType(genericTypes);

            _ticTypeGraph.SetCall(types, ids);
            return(true);
        }
Пример #12
0
 public string Visit(FunCallSyntaxNode node) => $"{node.Id}(...)";
Пример #13
0
 public virtual bool Visit(FunCallSyntaxNode node) => true;