Example #1
0
        /// <summary>
        ///     Gets stringied definition of function.
        /// </summary>
        /// <param name="node">The Function node.</param>
        /// <returns>stringied definition of function.</returns>
        public static string DetailedFunctionIdentifier(this RawFunctionNode node)
        {
            var builder = new StringBuilder();

            builder.Append(node.ReturnType.Name);
            builder.Append(node.Name);

            if (node.Descendants.Length > 0)
            {
                foreach (var descendant in node.Descendants)
                {
                    builder.Append(descendant);
                    builder.Append(':');
                    builder.Append(descendant.ReturnType.Name);
                }
            }
            else
            {
                builder.Append("none");
                builder.Append(':');
                builder.Append("void");
            }

            return(builder.ToString());
        }
Example #2
0
        /// <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);
        }
Example #3
0
 private void ReportUnknownFunctionCall(RawFunctionNode node)
 {
     AddSyntaxError(node.FullSpan,
                    string.Format(AnalysisMessage.UnknownFunctionCall, node.Name,
                                  node.Args.Descendants.Select(f => f.ReturnType.Name).ToArray()),
                    SyntaxErrorKind.UnsupportedFunctionCall);
 }
Example #4
0
 /// <summary>
 ///     Visit Function node in DFS manner.
 /// </summary>
 /// <param name="node">Function node that will be visited.</param>
 public virtual void Visit(RawFunctionNode node)
 {
     foreach (var item in node.Descendants.Reverse())
     {
         item.Accept(this);
     }
     node.Accept(_visitor);
 }
Example #5
0
        /// <summary>
        /// Gets general identifier of function (without using parameters)
        /// </summary>
        /// <param name="node">The raw function node.</param>
        /// <returns>Identifier of function</returns>
        public static string GeneralFunctionIdentifier(this RawFunctionNode node)
        {
            var builder = new StringBuilder();

            builder.Append(node.ReturnType.Name);
            builder.Append(node.Name);

            return(builder.ToString());
        }
Example #6
0
        public static string SpecificFunctionIdentifier(this RawFunctionNode node)
        {
            var builder = new StringBuilder();

            builder.Append(node.ReturnType.Name);
            builder.Append(node.Name);
            builder.Append(node.FullSpan.Start);
            builder.Append(node.FullSpan.Length);

            return(builder.ToString());
        }
Example #7
0
        /// <summary>
        ///     Performs "Function" specific operations.
        /// </summary>
        /// <param name="node">The "Function" node.</param>
        /// <param name="foundedMethod">The founded .NET method.</param>
        private void Visit(RawFunctionNode node, out MethodInfo foundedMethod)
        {
            var argTypes         = node.Descendants.Select(f => f.ReturnType).ToArray();
            var registeredMethod = _metadatas.GetMethod(node.Name, argTypes);

            foundedMethod = registeredMethod;
            var occurenceAmount = _functionOccurences[node.GeneralFunctionIdentifier()];
            var occurenceOrder  = _functionOccurences[node.SpecificFunctionIdentifier()] - 1;

            Instructions.Add(new CallExternal(_callMethodContext, registeredMethod, argTypes.Length, _partOfDate, occurenceAmount, occurenceOrder));
        }
Example #8
0
 public override void Visit(RawFunctionNode node)
 {
     try
     {
         if (!_metadatas.HasMethod(node.Name, node.Args.Descendants.Select(f => f.ReturnType).ToArray()))
         {
             ReportUnknownFunctionCall(node);
         }
     }
     catch (Exception e)
     {
         _criticalErrors.Add(e);
     }
 }
Example #9
0
        /// <summary>
        ///     Visit Function node in DFS manner.
        /// </summary>
        /// <param name="node">Function node that will be visited.</param>
        public override void Visit(RawFunctionNode node)
        {
            var scope        = _scope.GetScopeByFunction(node);
            var inScopePlace = scope.HasVisibleInvocation(node);

            if (!IsCacheable(node))
            {
                base.Visit(node);
            }
            else if (inScopePlace == InvocationVisibilityStatus.FirstCall)
            {
                Visit(new CallFunctionAndStoreValueNode(node));
            }
            else
            {
                Visit(new CachedFunctionNode(node));
            }
        }
Example #10
0
 /// <summary>
 ///     Determine if function is cacheable.
 /// </summary>
 /// <param name="node">The raw function.</param>
 /// <returns>True if node is cacheable, else false.</returns>
 private static bool IsCacheable(RawFunctionNode node)
 {
     return(!node.DoNotCache);
 }
Example #11
0
 public ScopeContext GetScopeByFunction(RawFunctionNode node)
 {
     return(_functionScopeTable[node]);
 }
Example #12
0
 /// <summary>
 ///     Visit Function node.
 /// </summary>
 /// <param name="node">Fuction node of AST</param>
 public abstract void Visit(RawFunctionNode node);
Example #13
0
 public void Visit(RawFunctionNode node)
 {
     _scope.AddFunction(node);
 }
Example #14
0
 /// <summary>
 ///     Performs "Function" specific operations.
 /// </summary>
 /// <param name="node">The "Function" node.</param>
 public virtual void Visit(RawFunctionNode node)
 {
     Visit(node, out MethodInfo methodInfo);
 }
Example #15
0
        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();
        }
Example #16
0
 public override void Visit(RawFunctionNode node) => ProduceDebuggerInstructions(node, n => base.Visit(n));
Example #17
0
 /// <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());
 }