/// <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()); }
/// <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 void ReportUnknownFunctionCall(RawFunctionNode node) { AddSyntaxError(node.FullSpan, string.Format(AnalysisMessage.UnknownFunctionCall, node.Name, node.Args.Descendants.Select(f => f.ReturnType.Name).ToArray()), SyntaxErrorKind.UnsupportedFunctionCall); }
/// <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); }
/// <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()); }
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()); }
/// <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)); }
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); } }
/// <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)); } }
/// <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); }
public ScopeContext GetScopeByFunction(RawFunctionNode node) { return(_functionScopeTable[node]); }
/// <summary> /// Visit Function node. /// </summary> /// <param name="node">Fuction node of AST</param> public abstract void Visit(RawFunctionNode node);
public void Visit(RawFunctionNode node) { _scope.AddFunction(node); }
/// <summary> /// Performs "Function" specific operations. /// </summary> /// <param name="node">The "Function" node.</param> public virtual void Visit(RawFunctionNode node) { Visit(node, out MethodInfo methodInfo); }
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(); }
public override void Visit(RawFunctionNode node) => ProduceDebuggerInstructions(node, n => base.Visit(n));
/// <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()); }