コード例 #1
0
ファイル: Compiler.cs プロジェクト: ViterAlex/UniversityApps
        /// <summary>
        /// Checks a compiled expression for stack balance.
        /// </summary>
        private bool isCompiledExpressionStackBalanced(CompiledExpression compiledExpression)
        {
            if (compiledExpression == null)
            {
                throw new ArgumentNullException("compiledExpression");
            }
            //
            int stackPointer = 0;

            //
            for (int i = 0; i < compiledExpression.CompiledExpressionItems.Count; i++)
            {
                CompiledExpressionItem item = compiledExpression.CompiledExpressionItems[i];
                //
                switch (item.Kind)
                {
                case CompiledExpressionItemKind.Constant: {
                    stackPointer++;
                    break;
                }

                case CompiledExpressionItemKind.Variable: {
                    stackPointer++;
                    break;
                }

                case CompiledExpressionItemKind.Operation: {
                    Operation operation = operationsRegistry.GetOperationByName(item.OperationName);
                    stackPointer -= operation.OperandsCount - 1;
                    break;
                }

                default: {
                    throw new InvalidOperationException("Unknown item kind.");
                }
                }
            }
            //
            if (stackPointer != 1)
            {
                return(false);
            }
            return(true);
        }
コード例 #2
0
        public PreparedExpression Decompile(CompiledExpression compiledExpression)
        {
            if (compiledExpression == null)
            {
                throw new ArgumentNullException("compiledExpression");
            }

            List <DecompiledExpressionItem> decompilationStack = new List <DecompiledExpressionItem>();

            for (int i = 0; i < compiledExpression.CompiledExpressionItems.Count; i++)
            {
                CompiledExpressionItem item = compiledExpression.CompiledExpressionItems[i];

                switch (item.Kind)
                {
                case CompiledExpressionItemKind.Constant:
                {
                    List <PreparedExpressionItem> items = new List <PreparedExpressionItem>();
                    items.Add(new PreparedExpressionItem(PreparedExpressionItemKind.Constant, item.Constant));
                    decompilationStack.Add(new DecompiledExpressionItem(false, new PreparedExpression(items)));
                    break;
                }

                case CompiledExpressionItemKind.Variable:
                {
                    List <PreparedExpressionItem> items = new List <PreparedExpressionItem>();
                    items.Add(new PreparedExpressionItem(PreparedExpressionItemKind.Variable, item.VariableName));
                    decompilationStack.Add(new DecompiledExpressionItem(false, new PreparedExpression(items)));
                    break;
                }

                case CompiledExpressionItemKind.Operation:
                {
                    Operation operation = operationsRegistry.GetOperationByName(item.OperationName);
                    List <PreparedExpressionItem> resultExpression = new List <PreparedExpressionItem>();
                    // Begining to construct a new expression string
                    if (operation.Kind == OperationKind.Function)
                    {
                        resultExpression.Add(new PreparedExpressionItem(PreparedExpressionItemKind.Signature, operation.Signature[0]));
                        resultExpression.Add(new PreparedExpressionItem(PreparedExpressionItemKind.Delimiter, DelimiterKind.OpeningBrace));
                    }
                    else if (operation.OperandsCount == 1)
                    {
                        // Unary operator
                        resultExpression.Add(new PreparedExpressionItem(PreparedExpressionItemKind.Signature, operation.Signature[0]));
                    }
                    // For each argument we have to determine, need there are braces or not
                    for (int j = 0; j < operation.OperandsCount; j++)
                    {
                        int index = decompilationStack.Count - operation.OperandsCount + j;
                        if (index < 0)
                        {
                            throw new MathProcessorException("Stack is empty.");
                        }

                        DecompiledExpressionItem decompiledItem = decompilationStack[index];
                        bool applyBraces = false;
                        if (operation.Kind != OperationKind.Function)
                        {
                            // First argument
                            if (j == 0)
                            {
                                if (decompiledItem.IsComplex)
                                {
                                    if (decompiledItem.LastOperation.Kind != OperationKind.Function)
                                    {
                                        if (decompiledItem.LastOperation.OperandsCount == 1)
                                        {
                                            applyBraces = true;
                                        }
                                        else
                                        {
                                            if (operation.Priority < decompiledItem.LastOperation.Priority)
                                            {
                                                applyBraces = true;
                                            }
                                            else if (operation.Priority == decompiledItem.LastOperation.Priority)
                                            {
                                                if (operationsRegistry.GetAssociationByPriority(operation.Priority) == PriorityAssociation.RightAssociated)
                                                {
                                                    applyBraces = true;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            // Last argument
                            if (j == operation.OperandsCount - 1)
                            {
                                if (decompiledItem.IsComplex)
                                {
                                    if (decompiledItem.LastOperation.Kind != OperationKind.Function)
                                    {
                                        if (decompiledItem.LastOperation.OperandsCount == 1)
                                        {
                                            applyBraces = true;
                                        }
                                        else
                                        {
                                            if (operation.Priority < decompiledItem.LastOperation.Priority)
                                            {
                                                applyBraces = true;
                                            }
                                            else if (operation.Priority == decompiledItem.LastOperation.Priority)
                                            {
                                                if (operationsRegistry.GetAssociationByPriority(operation.Priority) == PriorityAssociation.LeftAssociated)
                                                {
                                                    applyBraces = true;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (applyBraces)
                        {
                            resultExpression.Add(new PreparedExpressionItem(PreparedExpressionItemKind.Delimiter, DelimiterKind.OpeningBrace));
                        }
                        resultExpression.AddRange(decompiledItem.Expression.PreparedExpressionItems);
                        if (applyBraces)
                        {
                            resultExpression.Add(new PreparedExpressionItem(PreparedExpressionItemKind.Delimiter, DelimiterKind.ClosingBrace));
                        }


                        // Appending delimiters between arguments
                        if (j < operation.OperandsCount - 1)
                        {
                            if (operation.Kind == OperationKind.Function)
                            {
                                resultExpression.Add(new PreparedExpressionItem(PreparedExpressionItemKind.Delimiter, DelimiterKind.Comma));
                            }
                            else
                            {
                                resultExpression.Add(new PreparedExpressionItem(PreparedExpressionItemKind.Signature, operation.Signature[j]));
                            }
                        }
                    }
                    decompilationStack.RemoveRange(decompilationStack.Count - operation.OperandsCount, operation.OperandsCount);

                    if (operation.Kind == OperationKind.Function)
                    {
                        resultExpression.Add(new PreparedExpressionItem(PreparedExpressionItemKind.Delimiter, DelimiterKind.ClosingBrace));
                    }

                    decompilationStack.Add(new DecompiledExpressionItem(true, new PreparedExpression(resultExpression), operation));
                    break;
                }

                default:
                {
                    throw new InvalidOperationException("Unknown item kind.");
                }
                }
            }

            if (decompilationStack.Count != 1)
            {
                throw new MathProcessorException("Stack disbalance. Expression has invalid syntax.");
            }
            return(decompilationStack[0].Expression);
        }
コード例 #3
0
        public CompiledExpression Optimize(CompiledExpression compiledExpression)
        {
            if (compiledExpression == null)
            {
                throw new ArgumentNullException("compiledExpression");
            }

            List <CompiledExpressionItem> optimizedExpression = new List <CompiledExpressionItem>();

            for (int i = 0; i < compiledExpression.CompiledExpressionItems.Count; i++)
            {
                CompiledExpressionItem item = compiledExpression.CompiledExpressionItems[i];

                switch (item.Kind)
                {
                case CompiledExpressionItemKind.Constant:
                {
                    optimizedExpression.Add(item);
                    break;
                }

                case CompiledExpressionItemKind.Variable:
                {
                    optimizedExpression.Add(item);
                    break;
                }

                case CompiledExpressionItemKind.Operation:
                {
                    Operation operation = operationsRegistry.GetOperationByName(item.OperationName);
                    // If all arguments are constants, we can optimize this. Otherwise, we can't
                    bool noVariablesInArguments = true;
                    for (int j = 0; (j < operation.OperandsCount) && noVariablesInArguments; j++)
                    {
                        int index = optimizedExpression.Count - operation.OperandsCount + j;
                        if (index < 0)
                        {
                            throw new MathProcessorException("Stack is empty.");
                        }

                        if (optimizedExpression[index].Kind != CompiledExpressionItemKind.Constant)
                        {
                            noVariablesInArguments = false;
                        }
                    }
                    if (noVariablesInArguments)
                    {
                        double[] arguments = new double[operation.OperandsCount];
                        for (int j = optimizedExpression.Count - operation.OperandsCount, k = 0; j < optimizedExpression.Count; j++, k++)
                        {
                            arguments[k] = optimizedExpression[j].Constant;
                        }

                        optimizedExpression.RemoveRange(optimizedExpression.Count - operation.OperandsCount, operation.OperandsCount);
                        optimizedExpression.Add(new CompiledExpressionItem(CompiledExpressionItemKind.Constant,
                                                                           operation.Calculator.Calculate(arguments)));
                    }
                    else
                    {
                        optimizedExpression.Add(item);
                    }
                    break;
                }

                default:
                {
                    throw new InvalidOperationException("Unknown item kind.");
                }
                }
            }
            return(new CompiledExpression(optimizedExpression));
        }
コード例 #4
0
ファイル: Calculator.cs プロジェクト: rooddie/KKMT
        public double Calculate(CompiledExpression compiledExpression, List <VariableValue> variableValues)
        {
            if (compiledExpression == null)
            {
                throw new ArgumentNullException("compiledExpression");
            }
            if (variableValues == null)
            {
                throw new ArgumentNullException("variableValues");
            }
            //
            List <double> calculationsStack = new List <double>();

            //
            for (int i = 0; i < compiledExpression.CompiledExpressionItems.Count; i++)
            {
                CompiledExpressionItem item = compiledExpression.CompiledExpressionItems[i];
                //
                switch (item.Kind)
                {
                case CompiledExpressionItemKind.Constant: {
                    calculationsStack.Add(item.Constant);
                    break;
                }

                case CompiledExpressionItemKind.Variable: {
                    // TODO: Add dictionary optimizations.
                    bool variableValueFound = false;
                    foreach (VariableValue variableValue in variableValues)
                    {
                        if (item.VariableName == variableValue.VariableName)
                        {
                            variableValueFound = true;
                            calculationsStack.Add(variableValue.Value);
                            break;
                        }
                    }
                    if (!variableValueFound)
                    {
                        throw new MathProcessorException(String.Format("Variable {0} is not initialized.", item.VariableName));
                    }
                    break;
                }

                case CompiledExpressionItemKind.Operation: {
                    Operation operation       = operationsRegistry.GetOperationByName(item.OperationName);
                    double[]  parametersArray = new double[operation.OperandsCount];
                    //
                    if (calculationsStack.Count - operation.OperandsCount < 0)
                    {
                        throw new MathProcessorException("Stack is empty.");
                    }
                    for (int j = 0; j < operation.OperandsCount; j++)
                    {
                        int index = calculationsStack.Count - operation.OperandsCount + j;
                        parametersArray[j] = calculationsStack[index];
                    }
                    //
                    calculationsStack.RemoveRange(calculationsStack.Count - operation.OperandsCount, operation.OperandsCount);
                    calculationsStack.Add(operation.Calculator.Calculate(parametersArray));
                    break;
                }

                default: {
                    throw new InvalidOperationException("Unknown item kind.");
                }
                }
            }
            //
            if (calculationsStack.Count != 1)
            {
                throw new MathProcessorException("Stack disbalance. Expression has invalid syntax.");
            }
            return(calculationsStack[0]);
        }