private static Expression ArithmeticFloating(MiddleOperator middleOp,
                                                     Expression leftExpression,
                                                     Expression rightExpression)
        {
            leftExpression  = TypeCast.LogicalToFloating(leftExpression);
            rightExpression = TypeCast.LogicalToFloating(rightExpression);

            Type maxType = TypeCast.MaxType(leftExpression.Symbol.Type,
                                            rightExpression.Symbol.Type);

            leftExpression  = ConstantCast(leftExpression, maxType);
            rightExpression = ConstantCast(rightExpression, maxType);

            decimal leftDecimal   = (decimal)leftExpression.Symbol.Value,
                    rightDecimal  = (decimal)rightExpression.Symbol.Value,
                    resultDecimal = 0;

            switch (middleOp)
            {
            case MiddleOperator.Add:
                resultDecimal = leftDecimal + rightDecimal;
                break;

            case MiddleOperator.Subtract:
                resultDecimal = leftDecimal - rightDecimal;
                break;

            case MiddleOperator.Multiply:
                resultDecimal = leftDecimal * rightDecimal;
                break;

            case MiddleOperator.Divide:
                resultDecimal = leftDecimal / rightDecimal;
                break;
            }

            Symbol            resultSymbol = new Symbol(maxType, resultDecimal);
            List <MiddleCode> longList     = new List <MiddleCode>();

            MiddleCodeGenerator.AddMiddleCode(longList, MiddleOperator.PushFloat,
                                              resultSymbol);
            return(new Expression(resultSymbol, null, longList));
        }
        public static Symbol ArithmeticIntegral(MiddleOperator middleOp,
                                                Symbol leftSymbol,
                                                Symbol rightSymbol)
        {
            Type leftType  = leftSymbol.Type,
                 rightType = rightSymbol.Type;

            BigInteger leftValue   = (BigInteger)leftSymbol.Value,
                       rightValue  = (BigInteger)rightSymbol.Value,
                       resultValue = 0;

            switch (middleOp)
            {
            case MiddleOperator.Add:
                if (leftType.IsPointerOrArray())
                {
                    resultValue = leftValue +
                                  (rightValue * leftType.PointerOrArrayType.Size());
                }
                else if (leftType.IsPointerOrArray())
                {
                    resultValue = (leftValue * rightType.PointerOrArrayType.Size()) +
                                  rightValue;
                }
                else
                {
                    resultValue = leftValue + rightValue;
                }
                break;

            case MiddleOperator.Subtract:
                if (leftType.IsPointerOrArray() && rightType.IsPointerOrArray())
                {
                    resultValue = (leftValue - rightValue) /
                                  leftType.PointerOrArrayType.Size();
                }
                else if (leftType.IsPointerOrArray())
                {
                    resultValue = leftValue -
                                  (rightValue * leftType.PointerOrArrayType.Size());
                }
                else
                {
                    resultValue = leftValue - rightValue;
                }
                break;

            case MiddleOperator.Multiply:
                resultValue = leftValue * rightValue;
                break;

            case MiddleOperator.Divide:
                resultValue = leftValue / rightValue;
                break;

            case MiddleOperator.Modulo:
                resultValue = leftValue % rightValue;
                break;

            case MiddleOperator.BitwiseOr:
                resultValue = leftValue | rightValue;
                break;

            case MiddleOperator.BitwiseXOr:
                resultValue = leftValue ^ rightValue;
                break;

            case MiddleOperator.BitwiseAnd:
                resultValue = leftValue & rightValue;
                break;

            case MiddleOperator.ShiftLeft:
                resultValue = leftValue << ((int)rightValue);
                break;

            case MiddleOperator.ShiftRight:
                resultValue = leftValue >> ((int)rightValue);
                break;
            }

            Type maxType = TypeCast.MaxType(leftSymbol.Type, rightSymbol.Type);

            return(new Symbol(maxType, resultValue));
        }