/// <summary> /// Populates tables according to the currently-processed expression. /// </summary> /// <param name="processedExpression">The expression that is being processed.</param> /// <param name="constantsTable">The constants table.</param> /// <param name="reverseConstantsTable">The reverse-lookup constants table.</param> /// <param name="symbolTable">The symbols table.</param> /// <param name="reverseSymbolTable">The reverse-lookup symbols table.</param> /// <param name="parameterRegistry">The parameters registry.</param> /// <param name="interpreters">The constant interpreters.</param> /// <param name="originalExpression">The expression before processing.</param> /// <param name="openParenthesis">The symbol of an open parenthesis.</param> /// <param name="allSymbols">All symbols on which to split, in order.</param> internal static void PopulateTables( string processedExpression, Dictionary <string, ConstantNodeBase> constantsTable, Dictionary <string, string> reverseConstantsTable, Dictionary <string, ExpressionSymbol> symbolTable, Dictionary <string, string> reverseSymbolTable, IParameterRegistry parameterRegistry, LevelDictionary <Type, IConstantInterpreter> interpreters, string originalExpression, string openParenthesis, string[] allSymbols) { // Split expression by all symbols string[] expressions = processedExpression.Split( allSymbols, StringSplitOptions.RemoveEmptyEntries); foreach (var exp in expressions) { if (constantsTable.ContainsKey(exp)) { // We have a constant continue; } if (reverseConstantsTable.ContainsKey(exp)) { // We have a constant that has bee evaluated before continue; } if (parameterRegistry.Exists(exp)) { // We have a parameter continue; } if (symbolTable.ContainsKey(exp)) { // We have an already-existing symbol continue; } if (reverseSymbolTable.ContainsKey(exp)) { // We have a symbol value that has been evaluated before continue; } if (exp.Contains(openParenthesis)) { // We have a part of a function continue; } // Let's check whether it is a constant if (ConstantsGenerator.CheckAndAdd( constantsTable, reverseConstantsTable, interpreters, originalExpression, exp) != null) { continue; } // It's not a constant, nor something ever encountered before // Therefore it should be a parameter _ = parameterRegistry.AdvertiseParameter(exp); } }
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)); } }