/// <summary> /// Determine if specific function occured in any of the outer scope. /// </summary> /// <param name="function">The function to check.</param> /// <returns>True if outer scope contains function, otherwise false.</returns> public InvocationVisibilityStatus HasVisibleInvocation(RawFunctionNode function) { var identifier = function.DetailedFunctionIdentifier(); var stack = new Stack <ScopeContext>(); if (OuterScope != null) { stack.Push(OuterScope); } while (stack.Count > 0) { var scope = stack.Pop(); if (scope.HasFunctionIdentifier(identifier)) { return(InvocationVisibilityStatus.AnotherCall); } if (scope.OuterScope != null) { stack.Push(scope.OuterScope); } } return(InvocationVisibilityStatus.FirstCall); }
private RdlSyntaxNode ComposeBaseTypes() { switch (Current.TokenType) { case StatementType.Numeric: var token = ConsumeAndGetToken(StatementType.Numeric); return(new NumericNode(token, InferMinimalNumericType(token))); case StatementType.Word: return(new WordNode(ConsumeAndGetToken(StatementType.Word))); case StatementType.Var: return(new VarNode(ConsumeAndGetToken(StatementType.Var) as VarToken)); case StatementType.Case: return(new CaseNode(ConsumeAndGetToken(), ComposeWhenThenNodes(), ComposeAndSkip(f => ComposeElseNode(), StatementType.CaseEnd))); case StatementType.Function: if (!(Current is FunctionToken func)) { throw new ArgumentNullException(); } Consume(StatementType.Function); var args = ComposeArgs(); var argsTypes = args.Descendants.Select(f => f.ReturnType).ToArray(); if (_resolver.TryResolveMethod(func.Value, argsTypes, out var registeredMethod)) { var function = new RawFunctionNode(func, args, registeredMethod.ReturnType, !_resolver.CanBeCached(registeredMethod)); var detailedIdentifierHash = function.DetailedFunctionIdentifier(); var generalIdentifierHash = function.GeneralFunctionIdentifier(); var specificIdentifierHash = function.SpecificFunctionIdentifier(); if (!FunctionCallOccurence.ContainsKey(detailedIdentifierHash)) { FunctionCallOccurence.Add(detailedIdentifierHash, 1); } else { FunctionCallOccurence[detailedIdentifierHash] += 1; } if (!FunctionCallOccurence.ContainsKey(generalIdentifierHash)) { FunctionCallOccurence.Add(generalIdentifierHash, 1); } else { FunctionCallOccurence[generalIdentifierHash] += 1; } if (!FunctionCallOccurence.ContainsKey(specificIdentifierHash)) { FunctionCallOccurence.Add(specificIdentifierHash, FunctionCallOccurence[generalIdentifierHash]); } else { FunctionCallOccurence[specificIdentifierHash] = FunctionCallOccurence[generalIdentifierHash]; } return(function); } throw new MethodNotFoundedException(); case StatementType.LeftParenthesis: return(SkipComposeSkip(StatementType.LeftParenthesis, f => f.ComposeWhere(), StatementType.RightParenthesis)); } throw new NotSupportedException(); }
/// <summary> /// Adds the function to current scope. /// </summary> /// <param name="node">The function to add.</param> public void AddFunction(RawFunctionNode node) { _functionScopeTable.Add(node, this); _functions.Add(node.DetailedFunctionIdentifier()); }