Example #1
0
    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);
    }
Example #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));
    }