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; } }
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; } } } }
void ModifySubtraction( IArithmeticOperation operation, IArithmeticOperation chainedOperation, Action <IArithmeticOperation, IArithmeticOperation> handler) { ModifySubtraction(operation, chainedOperation, handler, handler); }
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); }
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); }
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(); }
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); } }
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(); }
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); } } }
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; } }
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); }
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 }; } }
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); }
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 } } }; } }
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(); } }
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; } }
public ArithmeticOperation(IArithmeticOperation operation, IArithmeticOpMetadata metadata) { Operation = operation; Metadata = metadata; }
void VisitOperands(IArithmeticOperation operation) { operation.Left.Accept(this); operation.Right.Accept(this); }
public AdditionSubtractionDispatcher(IArithmeticOperation operation, IArithmeticOperation chainedOperation) { mOperation = operation; mChainedOperation = chainedOperation; }
/// <summary> /// Handles subtraction of Variables next to each other /// </summary> /// <param name="operation"></param> void HandleDoubleMultiplicationInSubtraction(IArithmeticOperation operation) { HandleDoubleMultiplicationInAdditiveOperation(operation, (l, r) => l - r); }
IExpression ExecuteMultiplicationWithOneParentheses(IArithmeticOperation multiplication) => mIsParenthesesLeftSided != null && mIsParenthesesLeftSided.Value ? CreateMultiplicationReplacement(multiplication.Right, multiplication.Left) : CreateMultiplicationReplacement(multiplication.Left, multiplication.Right);
IExpression ExecuteMultiplicationWithTwoParentheses(IArithmeticOperation multiplication) => mHelper.GetAllUnderLyingMultipliableExpressions(multiplication.Left).Count <= mHelper.GetAllUnderLyingMultipliableExpressions(multiplication.Right).Count ? CreateMultiplicationReplacement(multiplication.Left, multiplication.Right) : CreateMultiplicationReplacement(multiplication.Right, multiplication.Left);