internal static string GenerateSymbolExpression( Dictionary <string, ExpressionSymbol> symbolTable, Dictionary <string, string> reverseSymbolTable, string expression, bool isFunction) { if (reverseSymbolTable.TryGetValue( expression, out var itemName)) { return(itemName); } itemName = $"item{symbolTable.Count.ToString(CultureInfo.InvariantCulture).PadLeft(4, '0')}"; ExpressionSymbol symb = isFunction ? ExpressionSymbol.GenerateFunctionCall( itemName, expression) : ExpressionSymbol.GenerateSymbol( itemName, expression); symbolTable.Add( itemName, symb); reverseSymbolTable.Add( symb.Expression, itemName); return(itemName); }
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)); }