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()); }
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)); }
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"); }
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)); }
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)); }
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); }
public static Exception OperatorOverloadNotFound(FunCallSyntaxNode node, ISyntaxNode failedArg) { return(new FunParseException(536, $"Invalid argument type for '{node.Id}' operator", failedArg.Interval)); }
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);
public static Exception AttributeOnFunction(FunCallSyntaxNode lexNode) => new FunParseException(288, $"Function cannot has attributes.", lexNode.Interval);
public virtual VisitorEnterResult Visit(FunCallSyntaxNode node) => DefaultVisitEnter(node);
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); }
public string Visit(FunCallSyntaxNode node) => $"{node.Id}(...)";
public virtual bool Visit(FunCallSyntaxNode node) => true;