コード例 #1
0
        public void SubtractionExpressionEvaluatesDifferenceInComplexExpression()
        {
            //mnozenje djeljenje testovi, cos i sin sa metodom

            // 2 + x - 7 + x - 10
            IExpression two   = new Constant(2);
            IExpression x     = new VariableX();
            IExpression seven = new Constant(7);
            IExpression ten   = new Constant(10);

            IExpression result = new SumExpression(two, x);

            result = new SubtractionExpression(result, seven);
            result = new SumExpression(result, x);
            result = new SubtractionExpression(result, ten);
            Context            c          = new Context(5);
            List <IExpression> operand    = new List <IExpression>();
            List <IExpression> operations = new List <IExpression>();

            var y = result.Interpret(c);

            Assert.AreEqual(-5, y, 1e-10);


            c = new Context(-3);
            y = result.Interpret(c);
            Assert.AreEqual(-21, y, 1e-10);
        }
コード例 #2
0
        public double SubtractionReal(SubtractionExpression node, List <object> parameters)
        {
            double leftOperand  = _interpreter.DispatchReal(node.Children[0], parameters);
            double rightOperand = _interpreter.DispatchReal(node.Children[1], parameters);

            return(leftOperand - rightOperand);
        }
コード例 #3
0
        public void MultiplicationExpressionEvaluatesDifferenceOfComplexDecimalExpression()
        {
            // 3 / x - 7 + x / 2
            IExpression three = new Constant(3);
            IExpression x     = new VariableX();
            IExpression seven = new Constant(7);
            IExpression two2  = new Constant(2);

            IExpression result = new DivideExpression(three, x);

            result = new SubtractionExpression(result, seven);
            result = new SumExpression(result, x);
            result = new DivideExpression(result, two2);
            Context c = new Context(0.5);


            var y = result.Interpret(c);

            Assert.AreEqual(-0.25, y, 1e-10);


            c = new Context(1.5);
            y = result.Interpret(c);
            Assert.AreEqual(-1.75, y, 1e-10);
        }
コード例 #4
0
        protected virtual double VisitSubtractionExpression(SubtractionExpression expr)
        {
            var arg1 = Visit(expr.Arg1);
            var arg2 = Visit(expr.Arg2);

            return(arg1 - arg2);
        }
コード例 #5
0
        public void MultiplicationExpressionEvaluatesDifferenceOfComplexDecimalExpression()
        {
            // 2 * x - 7 + x * 10
            IExpression two   = new Constant(2);
            IExpression x     = new VariableX();
            IExpression seven = new Constant(7);
            IExpression ten   = new Constant(10);

            IExpression result = new MultiplyExpression(two, x);

            result = new SubtractionExpression(result, seven);
            result = new SumExpression(result, x);
            result = new MultiplyExpression(result, ten);
            Context c = new Context(0.5);


            var y = result.Interpret(c);

            Assert.AreEqual(-55, y, 1e-10);


            c = new Context(1.5);
            y = result.Interpret(c);
            Assert.AreEqual(-25, y, 1e-10);
        }
コード例 #6
0
        public int SubtractionInteger(SubtractionExpression node, List <Object> parameters)
        {
            int leftOperand  = _interpreter.DispatchInt(node.Children[0], parameters);
            int rightOperand = _interpreter.DispatchInt(node.Children[1], parameters);

            return(leftOperand - rightOperand);
        }
コード例 #7
0
 public TypeNode Dispatch(ExpressionNode node, List <TypeNode> parameterTypes)
 {
     return(node switch
     {
         IBinaryNumberOperator n => _numberHelper.VisitBinaryNumOp(n, parameterTypes),
         IBinaryBooleanOperator n => _booleanHelper.VisitBinaryBoolOp(n, parameterTypes),
         IBinarySetOperator n => _setHelper.VisitBinarySetOp(n, parameterTypes),
         SubsetExpression n => _setHelper.VisitSubset(n, parameterTypes),
         SetExpression n => _setHelper.VisitSet(n, parameterTypes),
         NotExpression n => _booleanHelper.VisitNot(n, parameterTypes),
         FunctionCallExpression n => _declarationHelper.VisitFunctionCall(n, parameterTypes),
         IdentifierExpression n => _declarationHelper.VisitIdentifier(n, parameterTypes),
         IntegerLiteralExpression _ => _declarationHelper.VisitIntegerLiteral(),
         RealLiteralExpression _ => _declarationHelper.VisitRealLiteral(),
         BooleanLiteralExpression _ => _declarationHelper.VisitBooleanLiteral(),
         StringLiteralExpression _ => _declarationHelper.VisitStringLiteral(),
         EmptySetLiteralExpression _ => _declarationHelper.VisitEmptySetLiteral(),
         AdditionExpression n => _commonOperatorHelper.VisitAddition(n, parameterTypes),
         SubtractionExpression n => _commonOperatorHelper.VisitSubtraction(n, parameterTypes),
         AbsoluteValueExpression n => _commonOperatorHelper.VisitAbsoluteValue(n, parameterTypes),
         IRelationOperator n => _commonOperatorHelper.VisitRelationalOperator(n, parameterTypes),
         IEquivalenceOperator n => _commonOperatorHelper.VisitEquivalenceOperator(n, parameterTypes),
         NegativeExpression n => _numberHelper.VisitNegative(n, parameterTypes),
         ElementExpression n => _commonOperatorHelper.VisitElement(n, parameterTypes),
         ISetGraphField n => _commonOperatorHelper.VisitISetGraphField(n, parameterTypes),
         IFunctionGraphField n => _commonOperatorHelper.VisitIFunctionGraphField(n, parameterTypes),
         GraphExpression n => _commonOperatorHelper.VisitGraph(n, parameterTypes),
         AnonymousFunctionExpression n => _declarationHelper.VisitAnonymousFunction(n, parameterTypes),
         _ => throw new UnimplementedTypeCheckerException(node, "Dispatch"),
     });
コード例 #8
0
        protected void Evaluate(SubtractionExpression subtraction)
        {
            Visit(subtraction.Left);
            var leftResult = Result;

            Visit(subtraction.Right);
            Result = leftResult - Result;
        }
コード例 #9
0
        public void EvaluateWithTwoNormalOperands()
        {
            var left = new Expression { Value = 1 };
            var right = new Expression { Value = 2 };

            var expression = new SubtractionExpression(left, right);
            Assert.AreEqual(-1, expression.Evaluate());
        }
        protected void Evaluate(SubtractionExpression subtraction)
        {
            Visit(subtraction.Left);
            var tempEquation = "(" + Equation + " - ";

            Visit(subtraction.Right);
            Equation = tempEquation + Equation + ")";
        }
コード例 #11
0
        /// <summary>
        /// Creates a tree for math expression represented in Infix notation.
        /// </summary>
        /// <param name="s">String representing math expression in Infix notation.</param>
        /// <returns>Built expression.</returns>
        public MathExpression Build(string s)
        {
            if (string.IsNullOrEmpty(s))
            {
                throw new ArgumentException("Value cannot be null or empty.", nameof(s));
            }

            // Convert expression to use Reverse Polish (postfix) notation
            var notationConverter = new ExpressionNotationConverter();
            var rpnExprStr        = notationConverter.ToReversePolishNotation(s);

            var stack = new Stack <MathExpression>();

            string token;
            var    index = 0;

            while ((token = ReadNextToken(rpnExprStr, ref index)) != null)
            {
                MathExpression expr;

                var tokenKind = GetTokenKind(token);
                switch (tokenKind)
                {
                case TokenKind.Number:
                    expr = new NumberExpression(token);
                    break;

                case TokenKind.Addition:
                    expr = new AdditionExpression(GetChildExpressions(stack, 2, tokenKind));
                    break;

                case TokenKind.Subtraction:
                    expr = new SubtractionExpression(GetChildExpressions(stack, 2, tokenKind));
                    break;

                case TokenKind.Multiplication:
                    expr = new MultiplicationExpression(GetChildExpressions(stack, 2, tokenKind));
                    break;

                case TokenKind.Division:
                    expr = new DivisionExpression(GetChildExpressions(stack, 2, tokenKind));
                    break;

                default:
                    throw new ArgumentOutOfRangeException($"Unexpected token kind: '{tokenKind}'.");
                }

                stack.Push(expr);
            }

            if (stack.Count != 1)
            {
                throw new InvalidOperationException("Incorrect math expression.");
            }

            return(stack.Pop());
        }
コード例 #12
0
        public void EvaluateWithTwoNormalOperands()
        {
            var left  = new ConstantExpression(1);
            var right = new ConstantExpression(2);

            var expression = new SubtractionExpression(left, right);

            Assert.AreEqual(-1, expression.Evaluate());
        }
コード例 #13
0
        public void EvaluateWithOneSubtractionExpression()
        {
            var left = new Expression { Value = 1 };
            var leftTwo = new Expression { Value = 2 };
            var rightTwo = new Expression { Value = 3 };
            var right = new SubtractionExpression(leftTwo, rightTwo);

            var expression = new SubtractionExpression(left, right);
            Assert.AreEqual(2, expression.Evaluate());
        }
コード例 #14
0
        public Set SubtractionSet(SubtractionExpression node, List <Object> parameters)
        {
            Set leftSet  = _interpreter.DispatchSet(node.Children[0], parameters);
            Set rightSet = _interpreter.DispatchSet(node.Children[1], parameters);

            HashSet <Element> set = leftSet.SetCopy;

            set.ExceptWith(rightSet.Elements);
            return(new Set(set));
        }
コード例 #15
0
        public void VisitSubtractionExpressionReturnsCorrectResult(int x, int y, EquationPrintingVisitor sut)
        {
            var left        = new Constant(x);
            var right       = new Constant(y);
            var subtraction = new SubtractionExpression(left, right);

            sut.Visit(subtraction);
            var expected = $"({x} - {y})";

            Assert.Equal(expected, sut.Equation);
        }
コード例 #16
0
        public void EvaluateWithOneSubtractionExpression()
        {
            var left     = new ConstantExpression(1);
            var leftTwo  = new ConstantExpression(2);
            var rightTwo = new ConstantExpression(3);
            var right    = new SubtractionExpression(leftTwo, rightTwo);

            var expression = new SubtractionExpression(left, right);

            Assert.AreEqual(2, expression.Evaluate());
        }
        public void VisitSubtractionExpressionReturnsCorrectResult(int x, int y, CalculationVisitor sut)
        {
            var left        = new Constant(x);
            var right       = new Constant(y);
            var subtraction = new SubtractionExpression(left, right);

            sut.Visit(subtraction);
            var expected = x - y;

            Assert.Equal(expected, sut.Result);
        }
コード例 #18
0
        public void SubtractionExpressionEvaluatesDifferenceOf2Constants()
        {
            IExpression leftConstant  = new Constant(4);
            IExpression rightConstant = new Constant(6);

            IExpression difference = new SubtractionExpression(leftConstant, rightConstant);
            Context     context    = new Context(0);
            var         result     = difference.Interpret(context);

            Assert.AreEqual(-2, result, 1e-10);
        }
コード例 #19
0
        public void SubtractionInteger_TwoIntegers_ReturnsCorrectResultOfSubtraction(int input1, int input2, int expected)
        {
            IntegerLiteralExpression intLit1 = new IntegerLiteralExpression(input1.ToString(), 1, 1);
            IntegerLiteralExpression intLit2 = new IntegerLiteralExpression(input2.ToString(), 2, 2);
            SubtractionExpression    subExpr = new SubtractionExpression(intLit1, intLit2, 1, 1);
            IInterpreterInteger      parent  = Substitute.For <IInterpreterInteger>();

            parent.DispatchInt(intLit1, Arg.Any <List <object> >()).Returns(input1);
            parent.DispatchInt(intLit2, Arg.Any <List <object> >()).Returns(input2);
            IntegerHelper integerHelper = SetUpHelper(parent);

            int res = integerHelper.SubtractionInteger(subExpr, new List <object>());

            Assert.AreEqual(expected, res);
        }
コード例 #20
0
        public void SubtractionReal_TwoReals_ReturnsCorrectResult(double input1, double input2, double expected)
        {
            RealLiteralExpression realLit1        = new RealLiteralExpression(input1, 1, 1);
            RealLiteralExpression realLit2        = new RealLiteralExpression(input2, 2, 2);
            SubtractionExpression subtractionExpr = new SubtractionExpression(realLit1, realLit2, 1, 1);
            IInterpreterReal      parent          = Substitute.For <IInterpreterReal>();

            parent.DispatchReal(realLit1, Arg.Any <List <object> >()).Returns(input1);
            parent.DispatchReal(realLit2, Arg.Any <List <object> >()).Returns(input2);
            RealHelper realHelper = SetUpHelper(parent);

            double res = realHelper.SubtractionReal(subtractionExpr, new List <object>());

            Assert.AreEqual(expected, res);
        }
コード例 #21
0
        public void SubtractionSet_f_f(int[,] left, int[,] right, int[,] expected)
        {
            IInterpreterSet       parent    = Substitute.For <IInterpreterSet>();
            SetHelper             setHelper = SetUpHelper(parent);
            SetExpression         lhsExpr   = new SetExpression(null, null, null, 1, 1);
            SetExpression         rhsExpr   = new SetExpression(null, null, null, 1, 1);
            SubtractionExpression expr      = new SubtractionExpression(lhsExpr, rhsExpr, 0, 0);

            parent.DispatchSet(lhsExpr, Arg.Any <List <object> >()).Returns(getSetFrom2dArray(left));
            parent.DispatchSet(rhsExpr, Arg.Any <List <object> >()).Returns(getSetFrom2dArray(right));

            Set res = setHelper.SubtractionSet(expr, new List <object>());

            res.Should().BeEquivalentTo(getSetFrom2dArray(expected));
        }
コード例 #22
0
 public Set DispatchSet(ExpressionNode node, List <Object> parameters)
 {
     return(node switch
     {
         SetExpression e => _setHelper.SetExpression(e, parameters),
         UnionExpression e => _setHelper.UnionSet(e, parameters),
         IntersectionExpression e => _setHelper.IntersectionSet(e, parameters),
         SubtractionExpression e => _setHelper.SubtractionSet(e, parameters),
         IdentifierExpression e => _genericHelper.Identifier <Set>(e, parameters),
         FunctionCallExpression e => _genericHelper.FunctionCall <Set>(e, parameters),
         VerticesGraphField e => _setHelper.VerticesField(e, parameters),
         EdgesGraphField e => _setHelper.EdgesField(e, parameters),
         EmptySetLiteralExpression e => _setHelper.EmptySetLiteral(e, parameters),
         _ => throw new UnimplementedInterpreterException(node, "DispatctSet")
     });
コード例 #23
0
ファイル: Program.cs プロジェクト: hatchan/ArithmeticVisitor
        static void Main(string[] args)
        {
            IArithmeticVisitor visitor = new ConsoleArithmeticVisitor();

            IArithmeticExpression leftInnerNode = new ConstantExpression(39);
            IArithmeticExpression rightInnerNode = new ConstantExpression(13);

            IArithmeticExpression leftNode = new ConstantExpression(15);
            IArithmeticExpression rightNode = new SubtractionExpression(leftInnerNode, rightInnerNode);

            IArithmeticExpression rootNode = new MultiplicationExpression(leftNode, new BracketsExpression(rightNode));

            rootNode.Accept(visitor);

            Console.WriteLine();
        }
コード例 #24
0
ファイル: Program.cs プロジェクト: hatchan/ArithmeticVisitor
        static void Main(string[] args)
        {
            IArithmeticVisitor visitor = new ConsoleArithmeticVisitor();

            IArithmeticExpression leftInnerNode  = new ConstantExpression(39);
            IArithmeticExpression rightInnerNode = new ConstantExpression(13);

            IArithmeticExpression leftNode  = new ConstantExpression(15);
            IArithmeticExpression rightNode = new SubtractionExpression(leftInnerNode, rightInnerNode);

            IArithmeticExpression rootNode = new MultiplicationExpression(leftNode, new BracketsExpression(rightNode));

            rootNode.Accept(visitor);

            Console.WriteLine();
        }
コード例 #25
0
        public void DispatchReal_SubtractionAndObjectList_CorrectListPassed()
        {
            List <Object> expected = new List <Object>()
            {
                23, 2.334, null
            };
            SubtractionExpression input1      = new SubtractionExpression(null, null, 0, 0);
            IRealHelper           rhelper     = Substitute.For <IRealHelper>();
            Interpreter           interpreter = Utilities.GetIntepreterOnlyWith(rhelper);
            List <Object>         res         = null;

            rhelper.SubtractionReal(Arg.Any <SubtractionExpression>(), Arg.Do <List <Object> >(x => res = x));

            interpreter.DispatchReal(input1, expected);

            res.Should().BeEquivalentTo(expected);
        }
コード例 #26
0
        protected IExpression ParseExpression()
        {
            var left = ParseTerm();

            while (Accept("+") || Accept("-"))
            {
                if (Prev().Type == "+")
                {
                    left = AdditionExpression.Create(left, ParseTerm());
                }
                else
                {
                    left = SubtractionExpression.Create(left, ParseTerm());
                }
            }
            return(left);
        }
コード例 #27
0
        public void DispatchReal_SubtractionAndObjectList_CorrectValueReturned()
        {
            double expected = 17;
            SubtractionExpression input1 = new SubtractionExpression(null, null, 0, 0);
            List <Object>         input2 = new List <Object>()
            {
                23, 2.334, null
            };
            IRealHelper rhelper     = Substitute.For <IRealHelper>();
            Interpreter interpreter = Utilities.GetIntepreterOnlyWith(rhelper);

            rhelper.SubtractionReal(Arg.Any <SubtractionExpression>(), Arg.Any <List <Object> >()).Returns(expected);

            double res = interpreter.DispatchReal(input1, input2);

            Assert.AreEqual(expected, res);
        }
コード例 #28
0
        public void DispatchInteger_SubtractionAndObjectList_CorrectSubtractionExprPassed()
        {
            SubtractionExpression expected = new SubtractionExpression(null, null, 0, 0);
            SubtractionExpression input1   = expected;
            List <Object>         input2   = new List <Object>()
            {
                23, 2.334, null
            };
            IIntegerHelper        ihelper     = Substitute.For <IIntegerHelper>();
            Interpreter           interpreter = Utilities.GetIntepreterOnlyWith(ihelper);
            SubtractionExpression res         = null;

            ihelper.SubtractionInteger(Arg.Do <SubtractionExpression>(x => res = x), Arg.Any <List <Object> >());

            interpreter.DispatchInt(input1, input2);

            res.Should().BeEquivalentTo(expected);
        }
コード例 #29
0
        public void AdditionAndSubtractionWithBrackets()
        {
            Expression         expression = parseExpression("a + b + (1 - g)");
            AdditionExpression a          = assertTypeAndCast <AdditionExpression>(expression);

            AdditionExpression    b = assertTypeAndCast <AdditionExpression>(a.left);
            SubtractionExpression c = assertTypeAndCast <SubtractionExpression>(a.right);

            VariableReferenceExpression d = assertTypeAndCast <VariableReferenceExpression>(b.left);
            VariableReferenceExpression e = assertTypeAndCast <VariableReferenceExpression>(b.right);
            IntegralLiteralExpression   f = assertTypeAndCast <IntegralLiteralExpression>(c.left);
            VariableReferenceExpression g = assertTypeAndCast <VariableReferenceExpression>(c.right);

            Assert.AreEqual(d.name, "a");
            Assert.AreEqual(e.name, "b");
            Assert.AreEqual(f.value, 1);
            Assert.AreEqual(g.name, "g");
        }
コード例 #30
0
        public void WhileLoop()
        {
            Expression               expression = parseExpression("while(true){a + b - c;}");
            WhileLoopExpression      a          = assertTypeAndCast <WhileLoopExpression>(expression);
            BooleanLiteralExpression condition  = assertTypeAndCast <BooleanLiteralExpression>(a.condition);

            Assert.IsTrue(condition.value);

            Assert.AreEqual(1, a.loop.innerExpressions.Count);
            SubtractionExpression       b = assertTypeAndCast <SubtractionExpression>(a.loop.innerExpressions[0]);
            AdditionExpression          c = assertTypeAndCast <AdditionExpression>(b.left);
            VariableReferenceExpression d = assertTypeAndCast <VariableReferenceExpression>(b.right);
            VariableReferenceExpression e = assertTypeAndCast <VariableReferenceExpression>(c.left);
            VariableReferenceExpression f = assertTypeAndCast <VariableReferenceExpression>(c.right);

            Assert.AreEqual("a", e.name);
            Assert.AreEqual("b", f.name);
            Assert.AreEqual("c", d.name);
        }
コード例 #31
0
        public void BEDMASTest()
        {
            Expression expression = parseExpression("a + b * g / p - y");

            SubtractionExpression       a = assertTypeAndCast <SubtractionExpression>(expression);
            AdditionExpression          b = assertTypeAndCast <AdditionExpression>(a.left);
            VariableReferenceExpression c = assertTypeAndCast <VariableReferenceExpression>(a.right);
            VariableReferenceExpression d = assertTypeAndCast <VariableReferenceExpression>(b.left);
            DivisionExpression          e = assertTypeAndCast <DivisionExpression>(b.right);
            MultiplicationExpression    f = assertTypeAndCast <MultiplicationExpression>(e.left);
            VariableReferenceExpression g = assertTypeAndCast <VariableReferenceExpression>(e.right);
            VariableReferenceExpression h = assertTypeAndCast <VariableReferenceExpression>(f.left);
            VariableReferenceExpression i = assertTypeAndCast <VariableReferenceExpression>(f.right);

            Assert.AreEqual(c.name, "y");
            Assert.AreEqual(d.name, "a");
            Assert.AreEqual(g.name, "p");
            Assert.AreEqual(h.name, "b");
            Assert.AreEqual(i.name, "g");
        }
コード例 #32
0
ファイル: QueryCompiler.cs プロジェクト: trylock/viewer
        public void ExitExpression(QueryParser.ExpressionContext context)
        {
            CompileLeftAssociativeOperator(context.ADD_SUB(), _expressions,
                                           (opNode, left, right) =>
            {
                var op = opNode.Symbol;
                BinaryOperatorExpression value = null;
                switch (op.Text)
                {
                case "+":
                    value = new AdditionExpression(op.Line, op.Column, left, right);
                    break;

                case "-":
                    value = new SubtractionExpression(op.Line, op.Column, left, right);
                    break;
                }

                Trace.Assert(value != null, "Invalid addition operator " + op.Text);
                return(value);
            });
        }
コード例 #33
0
        public void TupleDefinition()
        {
            Expression expression       = parseExpression("(a, b, 4+6,\"dsas\\\"dasd\", a - g + p * t)");
            TupleDefinitionExpression a = assertTypeAndCast <TupleDefinitionExpression>(expression);

            Assert.AreEqual(a.members.Count, 5);

            VariableReferenceExpression b = assertTypeAndCast <VariableReferenceExpression>(a.members[0]);
            VariableReferenceExpression c = assertTypeAndCast <VariableReferenceExpression>(a.members[1]);
            AdditionExpression          z = assertTypeAndCast <AdditionExpression>(a.members[2]);
            StringLiteralExpression     d = assertTypeAndCast <StringLiteralExpression>(a.members[3]);
            AdditionExpression          e = assertTypeAndCast <AdditionExpression>(a.members[4]);

            Assert.AreEqual(b.name, "a");
            Assert.AreEqual(c.name, "b");

            IntegralLiteralExpression y = assertTypeAndCast <IntegralLiteralExpression>(z.left);
            IntegralLiteralExpression x = assertTypeAndCast <IntegralLiteralExpression>(z.right);

            Assert.AreEqual(4, y.value);
            Assert.AreEqual(6, x.value);

            Assert.AreEqual(d.value, "dsas\"dasd");

            SubtractionExpression    f = assertTypeAndCast <SubtractionExpression>(e.left);
            MultiplicationExpression g = assertTypeAndCast <MultiplicationExpression>(e.right);

            VariableReferenceExpression h = assertTypeAndCast <VariableReferenceExpression>(f.left);
            VariableReferenceExpression i = assertTypeAndCast <VariableReferenceExpression>(f.right);
            VariableReferenceExpression j = assertTypeAndCast <VariableReferenceExpression>(g.left);
            VariableReferenceExpression k = assertTypeAndCast <VariableReferenceExpression>(g.right);

            Assert.AreEqual(h.name, "a");
            Assert.AreEqual(i.name, "g");
            Assert.AreEqual(j.name, "p");
            Assert.AreEqual(k.name, "t");
        }
コード例 #34
0
        /// <summary>
        /// Reads an arithmetic expression.
        /// </summary>
        /// <param name="expressionProxy">Proxy object for the expression being created.</param>
        /// <param name="leftHandSide">The expression on the left hand side of the operator.</param>
        /// <param name="previousPrecedence">The precedence of the expression just before this one.</param>
        /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param>
        /// <returns>Returns the expression.</returns>
        private ArithmeticExpression GetArithmeticExpression(
            CodeUnitProxy expressionProxy, Expression leftHandSide, ExpressionPrecedence previousPrecedence, bool unsafeCode)
        {
            Param.AssertNotNull(expressionProxy, "expressionProxy");
            Param.AssertNotNull(leftHandSide, "leftHandSide");
            Param.Ignore(previousPrecedence);
            Param.Ignore(unsafeCode);

            ArithmeticExpression expression = null;
            
            // Read the details of the expression.
            OperatorSymbolToken operatorToken = this.PeekOperatorSymbolToken();
            CsLanguageService.Debug.Assert(
                operatorToken.Category == OperatorCategory.Arithmetic || operatorToken.Category == OperatorCategory.Shift, 
                "Expected an arithmetic or shift operator");

            // Check the precedence of the operators to make sure we can gather this statement now.
            ExpressionPrecedence precedence = GetOperatorPrecedence(operatorToken.SymbolType);
            if (CheckPrecedence(previousPrecedence, precedence))
            {
                // Create the operator toke again and save it.
                operatorToken = this.GetOperatorSymbolToken(expressionProxy);

                // Get the expression on the right-hand side of the operator.
                Expression rightHandSide = this.GetOperatorRightHandExpression(expressionProxy, precedence, unsafeCode);

                // Get the expression operator type.
                switch (operatorToken.SymbolType)
                {
                    case OperatorType.Plus:
                        expression = new AdditionExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.Minus:
                        expression = new SubtractionExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.Multiplication:
                        expression = new MultiplicationExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.Division:
                        expression = new DivisionExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.Mod:
                        expression = new ModExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.LeftShift:
                        expression = new LeftShiftExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    case OperatorType.RightShift:
                        expression = new RightShiftExpression(expressionProxy, leftHandSide, rightHandSide);
                        break;

                    default:
                        CsLanguageService.Debug.Fail("Unexpected operator type");
                        throw new InvalidOperationException();
                }
            }

            return expression;
        }