Exemplo n.º 1
0
            static NodeBase?ExpressionByBinaryOperator(
                WorkingExpressionSet innerWorkingSet,
                string s,
                int position,
                string op)
            {
                if (position == 0)
                {
                    // We certainly have an unary operator if the operator is at the beginning of the expression. We therefore cannot continue with binary
                    return(null);
                }

                if (innerWorkingSet.CancellationToken.IsCancellationRequested)
                {
                    // Cancellation requested, let's exit gracefully
                    return(null);
                }

                if (!innerWorkingSet.BinaryOperators.TryGetValue(
                        op,
                        out Func <MathDefinition, NodeBase, NodeBase, BinaryOperatorNodeBase> t))
                {
                    // Binary operator not actually found.
                    return(null);
                }

                // We have a normal, regular binary
                var eee = s.Substring(
                    0,
                    position);

                if (string.IsNullOrWhiteSpace(eee))
                {
                    // Empty space before operator. Normally, this should never be hit.
                    return(null);
                }

                NodeBase?left = GenerateExpression(
                    eee,
                    innerWorkingSet);

                if (left == null)
                {
                    // Left expression is invalid.
                    return(null);
                }

                eee = s.Substring(position + op.Length);
                if (string.IsNullOrWhiteSpace(eee))
                {
                    // Empty space after operator. Normally, this should never be hit.
                    return(null);
                }

                NodeBase?right = GenerateExpression(
                    eee,
                    innerWorkingSet);

                if (right == null)
                {
                    // Right expression is invalid.
                    return(null);
                }

                var resultingNode = t(
                    innerWorkingSet.Definition,
                    left,
                    right);

#pragma warning disable HAA0603 // Delegate allocation from a method group - Unavoidable
                ((ISpecialRequestNode)resultingNode).SetRequestSpecialObjectFunction(innerWorkingSet.OfferReservedType);
#pragma warning restore HAA0603 // Delegate allocation from a method group
                return(resultingNode.Simplify());
            }
Exemplo n.º 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));
    }
Exemplo n.º 3
0
    private static NodeBase?GenerateExpression(
        string?expression,
        WorkingExpressionSet workingSet)
    {
        if (expression == null)
        {
            // Expression could most likely not be computed
            return(null);
        }

        if (workingSet.CancellationToken.IsCancellationRequested)
        {
            // Cancellation requested, let's exit gracefully
            return(null);
        }

        // Expression might be an already-defined constant
        if (workingSet.ConstantsTable.TryGetValue(
                expression,
                out ConstantNodeBase c1))
        {
            return(c1);
        }

        if (workingSet.ReverseConstantsTable.TryGetValue(
                expression,
                out var c2))
        {
            if (workingSet.ConstantsTable.TryGetValue(
                    c2,
                    out ConstantNodeBase c3))
            {
                return(c3);
            }
        }

        // Check whether expression is an external parameter
        if (workingSet.ParameterRegistry.Exists(expression))
        {
            return(new ParameterNode(
                       expression,
                       workingSet.ParameterRegistry));
        }

        // Check whether the expression already exists in the symbols table
        if (workingSet.SymbolTable.TryGetValue(
                expression,
                out ExpressionSymbol e1))
        {
            return(GenerateExpression(
                       e1.Expression,
                       workingSet));
        }

        if (workingSet.ReverseSymbolTable.TryGetValue(
                expression,
                out var e2))
        {
            if (workingSet.SymbolTable.TryGetValue(
                    e2,
                    out ExpressionSymbol e3))
            {
                if (e3.Expression != expression)
                {
                    return(GenerateExpression(
                               e3.Expression,
                               workingSet));
                }
            }
        }

        // Check whether the expression is a function call
        if (expression.InvariantCultureContains(workingSet.Definition.Parentheses.Left) &&
            expression.InvariantCultureContains(workingSet.Definition.Parentheses.Right))
        {
            return(GenerateFunctionCallExpression(
                       expression,
                       workingSet));
        }

        // Check whether the expression is a binary operator
        foreach (var(_, operatorPosition, @operator) in OperatorSequenceGenerator
                 .GetOperatorsInOrderInExpression(
                     expression,
                     workingSet.BinaryOperators.KeysByLevel).OrderBy(p => p.Item1).ThenByDescending(p => p.Item2).ToArray())
        {
            NodeBase?exp = ExpressionByBinaryOperator(
                workingSet,
                expression,
                operatorPosition,
                @operator);