Esempio n. 1
0
        void CreateOperatorExpression(OperatorToken operatorToken)
        {
            switch (operatorToken.Operator)
            {
            case Operator.Add:
                mCurrentOperation = new Addition();
                break;

            case Operator.Subtract:
                HandleNegationIfNeeded();
                break;

            case Operator.Multiply:
                HandleMultiplicationOrDivisionBeforeAdditiveOperation <Multiplication>();
                break;

            case Operator.Divide:
                HandleMultiplicationOrDivisionBeforeAdditiveOperation <Division>();
                break;

            case Operator.Square:
                HandleMultiplicationOrDivisionBeforeAdditiveOperation <Power>();
                break;
            }
        }
Esempio n. 2
0
        void HandleDoubleMultiplicationInAdditiveOperation(
            IArithmeticOperation operation,
            Func <decimal, decimal, decimal> calculateLeftConstant)
        {
            var operationLeft  = (IArithmeticOperation)operation.Left;
            var operationRight = (IArithmeticOperation)operation.Right;

            if (operationLeft.Right is Variable && operationRight.Right is Variable && operationLeft.Left is Constant &&
                operationRight.Left is Constant)
            {
                var variableOne = (Variable)operationLeft.Right;
                var variableTwo = (Variable)operationRight.Right;
                if (variableOne.Name == variableTwo.Name)
                {
                    var constantOne = (Constant)operationLeft.Left;
                    var constantTwo = (Constant)operationRight.Left;
                    var replacement = new Multiplication
                    {
                        Left = new Constant {
                            Value = calculateLeftConstant(constantOne.Value, constantTwo.Value)
                        },
                        Right = variableOne
                    };
                    if (operation.HasParent)
                    {
                        operation.Parent.ReplaceChild(operation, replacement);
                    }
                    else
                    {
                        mCalculatedExpression = replacement;
                        mWasChanged           = true;
                    }
                }
            }
        }
Esempio n. 3
0
 void ModifySubtraction(
     IArithmeticOperation operation,
     IArithmeticOperation chainedOperation,
     Action <IArithmeticOperation, IArithmeticOperation> handler)
 {
     ModifySubtraction(operation, chainedOperation, handler, handler);
 }
Esempio n. 4
0
 IArithmeticOperation FindSuitableAdditionOrSubtraction(IArithmeticOperation operation)
 {
     while (!mWasChanged)
     {
         var multiplicationLeft  = operation.Left as Multiplication;
         var multiplicationRight = operation.Right as Multiplication;
         var variableRight       = (Variable)null;
         var variableLeft        = (Variable)null;
         if (multiplicationLeft != null)
         {
             variableLeft = multiplicationLeft.Right as Variable;
         }
         if (multiplicationRight != null)
         {
             variableRight = multiplicationRight.Right as Variable;
         }
         if (multiplicationRight != null && variableRight != null && variableRight.Name == mCurrentVariable)
         {
             mIsRight = true;
             return(operation);
         }
         if (multiplicationLeft != null && variableLeft != null && variableLeft.Name == mCurrentVariable)
         {
             mIsRight = false;
             return(operation);
         }
         if (operation.Left is Addition || operation.Left is Subtraction)
         {
             operation = (IArithmeticOperation)operation.Left;
             continue;
         }
         break;
     }
     return(null);
 }
Esempio n. 5
0
        void HandleLeftHandedVariableMultiplicationAndDivision(IArithmeticOperation operation,
                                                               IArithmeticOperation boundVariable)
        {
            var left  = (IExpressionWithValue)boundVariable.Left;
            var right = (IExpressionWithValue)operation.Right;

            if (operation is Multiplication)
            {
                operation.Left = new Constant {
                    Value = right.Value * left.Value
                };
            }
            else
            {
                if (operation.HasParent)
                {
                    operation = HandleParentedLeftHandedVariableDivisonInChain(operation);
                }
                else
                {
                    mCalculatedExpression = new Multiplication();
                    operation             = (IArithmeticOperation)mCalculatedExpression;
                }
                operation.Left = new Constant {
                    Value = left.Value / right.Value
                };
            }
            operation.Right = boundVariable.Right;
        }
 static void CheckForParent(IArithmeticOperation operation, IExpression replacement)
 {
     if (!operation.HasParent)
     {
         sMovedExpression = replacement;
     }
 }
 void CheckIfMoveIsAvailable(IArithmeticOperation operation)
 {
     if (operation.Right is Constant && (operation.Left is Addition || operation.Left is Subtraction))
     {
         MakeMove(operation, FindMoveableExpression((IArithmeticOperation)operation.Left));
     }
 }
 IArithmeticOperation FindMoveableExpression(IArithmeticOperation operation)
 {
     while (!mWasChanged)
     {
         var current = operation;
         if (operation.Right is Constant && !(operation.Left is Constant))
         {
             mIsRight = true;
             return(current);
         }
         if (operation.Left is Constant && !(operation.Right is Constant))
         {
             mIsRight = false;
             return(current);
         }
         if (operation.Left is Addition || operation.Left is Subtraction)
         {
             operation = (IArithmeticOperation)current.Left;
             continue;
         }
         if (operation.Right is Addition || operation.Right is Subtraction)
         {
             operation = (IArithmeticOperation)current.Right;
             continue;
         }
         break;
     }
     return(null);
 }
Esempio n. 9
0
        IArithmeticOperation HandleParentedRightHandedVariableDivisionInChain(IArithmeticOperation operation)
        {
            var parent = (IArithmeticOperation)operation.Parent;

            if (parent.Left == operation)
            {
                parent.Left = new Division();
                return((IArithmeticOperation)parent.Left);
            }
            parent.Right = new Division();

            return((IArithmeticOperation)parent.Right);
        }
 void MakeMove(IArithmeticOperation operation, IArithmeticOperation chainedOperation)
 {
     if (chainedOperation == null)
     {
         return;
     }
     new AdditionSubtractionDispatcher(operation, chainedOperation)
     {
         ForAddAdd = HandleAdditionInAddition,
         ForAddSub = HandleSubtractionInAddition,
         ForSubAdd = HandelAdditionInSubtraction,
         ForSubSub = HandelSubtractionInSubtraction
     }.Execute();
 }
Esempio n. 11
0
 void ModifyAddition(
     IArithmeticOperation operation,
     IArithmeticOperation chainedOperation,
     Action <IArithmeticOperation, IArithmeticOperation> handler)
 {
     if (mIsRight)
     {
         chainedOperation.Parent.ReplaceChild(chainedOperation, chainedOperation.Left);
         handler(operation, (IArithmeticOperation)chainedOperation.Right);
     }
     else
     {
         chainedOperation.Parent.ReplaceChild(chainedOperation, chainedOperation.Right);
         handler(operation, (IArithmeticOperation)chainedOperation.Left);
     }
 }
Esempio n. 12
0
        void MakeMove(IArithmeticOperation operation, IArithmeticOperation chainedOperation)
        {
            if (chainedOperation == null)
            {
                return;
            }

            new AdditionSubtractionDispatcher(operation, chainedOperation)
            {
                ForAddAdd = (op, chained) => ModifyAddition(op, chained, HandleAdditionOfVariables),
                ForSubAdd = (op, chained) => ModifyAddition(op, chained, HanldeSubtractionToAddition),
                ForSubSub = (op, chained) => ModifySubtraction(op, chained, HandleSubtractionToSubtraction),
                ForAddSub =
                    (op, chained) =>
                    ModifySubtraction(op, chained, HandleSubtractionToAddition, HandleAdditionOfVariables)
            }.Execute();
        }
Esempio n. 13
0
        void CheckOperation(IArithmeticOperation operation)
        {
            var checkDoubleVariableInMultiplication = operation.Left as Multiplication;

            if (operation.Right is Multiplication && (operation.Left is Addition || operation.Left is Subtraction))
            {
                var multiplication = (IArithmeticOperation)operation.Right;
                if (multiplication.Right is Variable)
                {
                    var variable = (Variable)multiplication.Right;
                    mCurrentVariable = variable.Name;
                }
                MakeMove(operation, FindSuitableAdditionOrSubtraction((IArithmeticOperation)operation.Left));
            }
            else if (operation.Right is Multiplication && operation.Left is Multiplication)
            {
                if (operation is Addition)
                {
                    HandleDoubleMultiplicationInAddition(operation);
                }
                else if (operation is Subtraction)
                {
                    HandleDoubleMultiplicationInSubtraction(operation);
                }
            }
            else if (checkDoubleVariableInMultiplication?.Left is Variable && checkDoubleVariableInMultiplication.Right is Variable)
            {
            }
            else if (operation.Right is Constant && operation.Left is Multiplication && (operation is Multiplication || operation is Division))
            {
                var boundVariable = (IArithmeticOperation)operation.Left;
                if (boundVariable.Right is Variable)
                {
                    HandleLeftHandedVariableMultiplicationAndDivision(operation, boundVariable);
                }
            }
            else if (operation.Right is Multiplication && operation.Left is Constant && (operation is Multiplication || operation is Division))
            {
                var boundVariable = (IArithmeticOperation)operation.Right;
                if (boundVariable.Right is Variable)
                {
                    HandleRightHandedVariableMultiplicationAndDivision(operation, boundVariable);
                }
            }
        }
Esempio n. 14
0
        void AddNewParenthesesExpression()
        {
            var parenthesedExpression = new ParenthesedExpression();

            if (mCurrent is ParenthesedExpression)
            {
                var parent = (ParenthesedExpression)mCurrent;
                parent.Wrapped = parenthesedExpression;
            }
            mCurrent     = parenthesedExpression;
            mParenthesed = (ParenthesedExpression)mCurrent;
            if (mCurrentOperation != null)
            {
                mCurrentOperation.Right = mCurrent;
                mWasOpening             = true;
                mCurrentOperation       = null;
            }
        }
Esempio n. 15
0
 bool IsMultiplicationWithAtLeastOneSideBeingAParenthesedExpression(IArithmeticOperation multiplication)
 {
     if (multiplication.Left is ParenthesedExpression && multiplication.Right is ParenthesedExpression)
     {
         mIsParenthesesLeftSided = null;
         return(true);
     }
     if (multiplication.Left is ParenthesedExpression)
     {
         mIsParenthesesLeftSided = true;
         return(true);
     }
     if (multiplication.Right is ParenthesedExpression)
     {
         mIsParenthesesLeftSided = false;
         return(true);
     }
     return(false);
 }
Esempio n. 16
0
 void ModifySubtraction(
     IArithmeticOperation operation,
     IArithmeticOperation chainedOperation,
     Action <IArithmeticOperation, IArithmeticOperation> righthandler,
     Action <IArithmeticOperation, IArithmeticOperation> leftHandler)
 {
     if (mIsRight)
     {
         righthandler(operation, (IArithmeticOperation)chainedOperation.Right);
         chainedOperation.Right = new Constant {
             Value = 0
         };
     }
     else
     {
         leftHandler(operation, (IArithmeticOperation)chainedOperation.Left);
         chainedOperation.Left = new Constant {
             Value = 0
         };
     }
 }
Esempio n. 17
0
        void HanldeSubtractionToAddition(IArithmeticOperation operation, IArithmeticOperation multiplication)
        {
            var multiplicationOfOperation = (IArithmeticOperation)operation.Right;
            var constantTwo = (Constant)multiplication.Left;
            var constantOne = (Constant)multiplicationOfOperation.Left;
            var replacement = new Subtraction
            {
                Left  = operation.Left,
                Right =
                    new Multiplication
                {
                    Left = new Constant {
                        Value = constantOne.Value - constantTwo.Value
                    },
                    Right = new Variable {
                        Name = mCurrentVariable
                    }
                }
            };

            HandleReplacement(operation, replacement);
        }
Esempio n. 18
0
        void HandleSubtractionToSubtraction(IArithmeticOperation operation, IArithmeticOperation multiplication)
        {
            var multiplicationOfOperation = (IArithmeticOperation)operation.Right;
            var constantOne = (Constant)multiplication.Left;
            var constantTwo = (Constant)multiplicationOfOperation.Left;
            var replacement = new Subtraction
            {
                Left  = operation.Left,
                Right =
                    new Multiplication
                {
                    Left = new Constant {
                        Value = constantOne.Value + constantTwo.Value
                    },
                    Right = new Variable {
                        Name = mCurrentVariable
                    }
                }
            };

            HandleReplacement(operation, replacement);
            if (!operation.HasParent && !mIsRight)
            {
                mCalculatedExpression = new Addition
                {
                    Left  = operation.Left,
                    Right =
                        new Multiplication
                    {
                        Left = new Constant {
                            Value = constantOne.Value - constantTwo.Value
                        },
                        Right = new Variable {
                            Name = mCurrentVariable
                        }
                    }
                };
            }
        }
Esempio n. 19
0
 void HandleMultiplicationOrDivisionBeforeAdditiveOperation <TSelf>() where TSelf : IArithmeticOperation, new()
 {
     if (mCurrentOperation?.Right is Variable)
     {
         if (mCurrentOperation.HasParent && !(mCurrentOperation.Parent is ParenthesedExpression))
         {
             var parent = (IArithmeticOperation)mCurrentOperation.Parent;
             var temp   = parent.Right;
             parent.Right = new TSelf()
             {
                 Left = temp
             };
             mCurrentOperation  = (IArithmeticOperation)parent.Right;
             mWasMultiplication = true;
         }
         else
         {
             var temp = mCurrentOperation;
             mCurrentOperation = new TSelf {
                 Left = temp
             };
         }
     }
     else if (mCurrentOperation != null && !(mCurrent is ParenthesedExpression))
     {
         var temp = mCurrentOperation.Right;
         var multiplicationOrDivision = new TSelf {
             Left = temp
         };
         mCurrentOperation.Right = multiplicationOrDivision;
         mCurrentOperation       = multiplicationOrDivision;
         mWasMultiplication      = true;
     }
     else
     {
         mCurrentOperation = new TSelf();
     }
 }
Esempio n. 20
0
        void HandleNegationIfNeeded()
        {
            var parentheses = mCurrent as ParenthesedExpression;

            if (mCurrent != null && !(mCurrent is ParenthesedExpression))
            {
                mCurrentOperation = new Subtraction();
            }
            else if (parentheses?.Wrapped != null)
            {
                mCurrentOperation = new Subtraction();
            }
            else
            {
                var constant = new Constant {
                    Value = 0
                };
                mCurrentOperation = new Subtraction {
                    Left = constant
                };
                mIsNegated = true;
            }
        }
Esempio n. 21
0
 public ArithmeticOperation(IArithmeticOperation operation, IArithmeticOpMetadata metadata)
 {
     Operation = operation;
     Metadata  = metadata;
 }
 void VisitOperands(IArithmeticOperation operation)
 {
     operation.Left.Accept(this);
     operation.Right.Accept(this);
 }
Esempio n. 23
0
 public AdditionSubtractionDispatcher(IArithmeticOperation operation, IArithmeticOperation chainedOperation)
 {
     mOperation        = operation;
     mChainedOperation = chainedOperation;
 }
Esempio n. 24
0
 /// <summary>
 /// Handles subtraction of Variables next to each other
 /// </summary>
 /// <param name="operation"></param>
 void HandleDoubleMultiplicationInSubtraction(IArithmeticOperation operation)
 {
     HandleDoubleMultiplicationInAdditiveOperation(operation, (l, r) => l - r);
 }
Esempio n. 25
0
 IExpression ExecuteMultiplicationWithOneParentheses(IArithmeticOperation multiplication)
 => mIsParenthesesLeftSided != null && mIsParenthesesLeftSided.Value
         ? CreateMultiplicationReplacement(multiplication.Right, multiplication.Left)
         : CreateMultiplicationReplacement(multiplication.Left, multiplication.Right);
Esempio n. 26
0
 IExpression ExecuteMultiplicationWithTwoParentheses(IArithmeticOperation multiplication)
 => mHelper.GetAllUnderLyingMultipliableExpressions(multiplication.Left).Count <=
 mHelper.GetAllUnderLyingMultipliableExpressions(multiplication.Right).Count
         ? CreateMultiplicationReplacement(multiplication.Left, multiplication.Right)
         : CreateMultiplicationReplacement(multiplication.Right, multiplication.Left);