/// <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);
        }
    }
示例#2
0
            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));
                }
            }