예제 #1
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));
                }
            }
예제 #2
0
    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));
    }