static string?ReplaceFunctionsLocal( string source, string openParenthesisSymbol, string closeParenthesisSymbol, string parameterSeparatorSymbol, Dictionary <string, ConstantNodeBase> constantsTableReference, Dictionary <string, string> reverseConstantsTableReference, Dictionary <string, ExpressionSymbol> symbolTableReference, Dictionary <string, string> reverseSymbolTableReference, LevelDictionary <Type, IConstantInterpreter> interpretersReference, IParameterRegistry parametersTableReference, string expressionSymbol, string[] allSymbolsSymbols) { var op = -1; var opl = openParenthesisSymbol.Length; var cpl = closeParenthesisSymbol.Length; while (true) { op = source.InvariantCultureIndexOf( openParenthesisSymbol, op + opl); if (op == -1) { return(null); } if (op == 0) { continue; } var functionHeaderCheck = source.Substring( 0, op); if (allSymbolsSymbols.Any( ( p, check) => check.InvariantCultureEndsWith(p), functionHeaderCheck)) { continue; } var functionHeader = functionHeaderCheck.Split( allSymbolsSymbols, StringSplitOptions.None).Last(); var oop = source.InvariantCultureIndexOf( openParenthesisSymbol, op + opl); var cp = source.InvariantCultureIndexOf( closeParenthesisSymbol, op + cpl); while (oop < cp && oop != -1 && cp != -1) { oop = source.InvariantCultureIndexOf( openParenthesisSymbol, oop + opl); cp = source.InvariantCultureIndexOf( closeParenthesisSymbol, cp + cpl); } if (cp == -1) { continue; } var arguments = source.Substring( op + opl, cp - op - opl); var originalArguments = arguments; var q = arguments; while (q != null) { arguments = q; q = ReplaceFunctionsLocal( q, openParenthesisSymbol, closeParenthesisSymbol, parameterSeparatorSymbol, constantsTableReference, reverseConstantsTableReference, symbolTableReference, reverseSymbolTableReference, interpretersReference, parametersTableReference, expressionSymbol, allSymbolsSymbols); } var argPlaceholders = new List <string>(); foreach (var s in arguments.Split( new[] { parameterSeparatorSymbol }, StringSplitOptions.RemoveEmptyEntries)) { TablePopulationGenerator.PopulateTables( s, constantsTableReference, reverseConstantsTableReference, symbolTableReference, reverseSymbolTableReference, parametersTableReference, interpretersReference, expressionSymbol, openParenthesisSymbol, allSymbolsSymbols); // We check whether or not this is actually a constant argPlaceholders.Add( ConstantsGenerator.CheckAndAdd( constantsTableReference, reverseConstantsTableReference, interpretersReference, expressionSymbol, s) ?? (!parametersTableReference.Exists(s) ? SymbolExpressionGenerator.GenerateSymbolExpression( symbolTableReference, reverseSymbolTableReference, s, false) : s)); } var functionCallBody = $"{functionHeader}{openParenthesisSymbol}{string.Join(parameterSeparatorSymbol, argPlaceholders)}{closeParenthesisSymbol}"; var functionCallToReplace = $"{functionHeader}{openParenthesisSymbol}{originalArguments}{closeParenthesisSymbol}"; var functionCallItem = SymbolExpressionGenerator.GenerateSymbolExpression( symbolTableReference, reverseSymbolTableReference, functionCallBody, true); return(source.Replace( functionCallToReplace, functionCallItem)); } }
internal static ComputationBody CreateBody(WorkingExpressionSet workingSet) { if (workingSet.CancellationToken.IsCancellationRequested) { return(ComputationBody.Empty); } foreach (Type extractorType in workingSet.Extractors.KeysByLevel.OrderBy(p => p.Key) .SelectMany(p => p.Value).ToArray()) { workingSet.Expression = workingSet.Extractors[extractorType].ExtractAllConstants( workingSet.Expression, workingSet.ConstantsTable, workingSet.ReverseConstantsTable, workingSet.Definition); if (workingSet.CancellationToken.IsCancellationRequested) { return(ComputationBody.Empty); } } workingSet.Expression = workingSet.Expression.Trim().Replace( " ", string.Empty); // Start preparing expression workingSet.SymbolTable.Add( string.Empty, ExpressionSymbol.GenerateSymbol( string.Empty, workingSet.Expression)); // Prepares expression and takes care of operators to ensure that they are all OK and usable workingSet.Initialize(); workingSet.SymbolTable[string.Empty].Expression = workingSet.Expression; if (workingSet.CancellationToken.IsCancellationRequested) { return(ComputationBody.Empty); } // Break expression based on function calls FunctionsExtractor.ReplaceFunctions( workingSet.Definition.Parentheses.Left, workingSet.Definition.Parentheses.Right, workingSet.Definition.ParameterSeparator, workingSet.ConstantsTable, workingSet.ReverseConstantsTable, workingSet.SymbolTable, workingSet.ReverseSymbolTable, workingSet.Interpreters, workingSet.ParameterRegistry, workingSet.SymbolTable[string.Empty].Expression, workingSet.AllSymbols); if (workingSet.CancellationToken.IsCancellationRequested) { return(ComputationBody.Empty); } // We save a split expression for determining parameter order var splitExpression = workingSet.Expression.Split( workingSet.AllSymbols.ToArray(), StringSplitOptions.RemoveEmptyEntries); // Break by parentheses ParenthesesParser.FormatParentheses( workingSet.Definition.Parentheses.Left, workingSet.Definition.Parentheses.Right, workingSet.Definition.ParameterSeparator, workingSet.AllOperatorsInOrder, workingSet.SymbolTable, workingSet.ReverseSymbolTable); if (workingSet.CancellationToken.IsCancellationRequested) { return(ComputationBody.Empty); } // Populating symbol tables foreach (var p in workingSet.SymbolTable.Where(p => !p.Value.IsFunctionCall) .Select(p => p.Value.Expression)) { TablePopulationGenerator.PopulateTables( p, workingSet.ConstantsTable, workingSet.ReverseConstantsTable, workingSet.SymbolTable, workingSet.ReverseSymbolTable, workingSet.ParameterRegistry, workingSet.Interpreters, workingSet.Expression, workingSet.Definition.Parentheses.Left, workingSet.AllSymbols); } // For each parameter from the table we've just populated, see where it's first used, and fill in that index as the order foreach (ParameterContext paramForOrdering in workingSet.ParameterRegistry.Dump()) { paramForOrdering.Order = Array.IndexOf( splitExpression, paramForOrdering.Name); } if (workingSet.CancellationToken.IsCancellationRequested) { return(ComputationBody.Empty); } // Generate expressions NodeBase?body; try { body = GenerateExpression( workingSet.SymbolTable[string.Empty].Expression, workingSet); } catch { body = null; } if (body == null || workingSet.CancellationToken.IsCancellationRequested) { return(ComputationBody.Empty); } if (body is ConstantNodeBase && workingSet.ParameterRegistry.Populated) { return(ComputationBody.Empty); } workingSet.Success = true; return(new ComputationBody( body, workingSet.ParameterRegistry)); }