public static Symbol Unary(MiddleOperator middleOp, Symbol symbol)
        {
            Type type = symbol.Type;

            switch (middleOp)
            {
            case MiddleOperator.Address:
                if (symbol.Value is StaticValue) // &a[i], &s.i
                {
                    StaticValue   staticValue   = (StaticValue)symbol.Value;
                    StaticAddress staticAddress =
                        new StaticAddress(staticValue.UniqueName, staticValue.Offset);
                    return(new Symbol(new Type(type), staticAddress));
                }
                else if (symbol.IsExternOrStatic()) // &i
                {
                    StaticAddress staticAddress =
                        new StaticAddress(symbol.UniqueName, 0);
                    return(new Symbol(new Type(type), staticAddress));
                }
                break;
            }

            return(null);
        }
 public void Clear()
 {
     m_middleOperator  = MiddleOperator.Empty;
     m_operandArray[0] = null;
     m_operandArray[1] = null;
     m_operandArray[2] = null;
 }
        private static Expression ArithmeticIntegral(MiddleOperator middleOp,
                                                     Expression expression)
        {
            expression = TypeCast.LogicalToIntegral(expression);
            BigInteger value = (BigInteger)expression.Symbol.Value;

            Symbol resultSymbol = null;

            switch (middleOp)
            {
            case MiddleOperator.Plus:
                resultSymbol = new Symbol(expression.Symbol.Type, value);
                break;

            case MiddleOperator.Minus:
                resultSymbol = new Symbol(expression.Symbol.Type, -value);
                break;

            case MiddleOperator.BitwiseNot:
                resultSymbol = new Symbol(expression.Symbol.Type, ~value);
                break;
            }

            return(new Expression(resultSymbol, null, null));
        }
        private static Expression ArithmeticIntegral(MiddleOperator middleOp,
                                                     Expression leftExpression,
                                                     Expression rightExpression)
        {
            leftExpression  = LogicalToIntegral(leftExpression);
            rightExpression = LogicalToIntegral(rightExpression);
            Symbol symbol = ArithmeticIntegral(middleOp, leftExpression.Symbol,
                                               rightExpression.Symbol);

            return(new Expression(symbol, null, null));
        }
        public static bool IsModulo(MiddleOperator middleOperator)
        {
            switch (middleOperator)
            {
            case MiddleOperator.SignedModulo:
            case MiddleOperator.UnsignedModulo:
                return(true);

            default:
                return(false);
            }
        }
        public static bool IsShift(MiddleOperator middleOp)
        {
            switch (middleOp)
            {
            case MiddleOperator.ShiftLeft:
            case MiddleOperator.ShiftRight:
                return(true);

            default:
                return(false);
            }
        }
        public MiddleCode(MiddleOperator middleOp, object operand0 = null,
                          object operand1 = null, object operand2 = null)
        {
            m_middleOperator  = middleOp;
            m_operandArray[0] = operand0;
            m_operandArray[1] = operand1;
            m_operandArray[2] = operand2;

            /*if ((middleOp == MiddleOperator.InitializerZero) &&
             *  operand0.ToString().Equals("0")) {
             * int i = 1;
             * }*/
        }
Esempio n. 8
0
        public static bool IsMultiply(MiddleOperator middleOp)
        {
            switch (middleOp)
            {
            case MiddleOperator.Multiply:
            case MiddleOperator.Divide:
            case MiddleOperator.Modulo:
                return(true);

            default:
                return(false);
            }
        }
 public static Expression Arithmetic(MiddleOperator middleOp,
                                     Expression expression)
 {
     if (!IsConstant(expression))
     {
         return(null);
     }
     else if (expression.Symbol.Type.IsFloating())
     {
         return(ArithmeticFloating(middleOp, expression));
     }
     else
     {
         return(ArithmeticIntegral(middleOp, expression));
     }
 }
        public static bool IsAssociative(MiddleOperator middleOperator)
        {
            switch (middleOperator)
            {
            case MiddleOperator.BinaryAdd:
            case MiddleOperator.BinarySubtract:
            case MiddleOperator.BitwiseAnd:
            case MiddleOperator.BitwiseOr:
            case MiddleOperator.BitwiseXOr:
            case MiddleOperator.Index:
                return(true);

            default:
                return(false);
            }
        }
Esempio n. 11
0
        public static bool IsRelation(MiddleOperator middleOperator)
        {
            switch (middleOperator)
            {
            case MiddleOperator.Case:
            case MiddleOperator.Equal:
            case MiddleOperator.NotEqual:
            case MiddleOperator.LessThan:
            case MiddleOperator.LessThanEqual:
            case MiddleOperator.GreaterThan:
            case MiddleOperator.GreaterThanEqual:
                return(true);

            default:
                return(false);
            }
        }
 public static Expression Arithmetic(MiddleOperator middleOp,
                                     Expression leftExpression,
                                     Expression rightExpression)
 {
     if (!IsConstant(leftExpression) || !IsConstant(rightExpression))
     {
         return(null);
     }
     else if (leftExpression.Symbol.Type.IsFloating() ||
              rightExpression.Symbol.Type.IsFloating())
     {
         return(ArithmeticFloating(middleOp, leftExpression, rightExpression));
     }
     else
     {
         return(ArithmeticIntegral(middleOp, leftExpression, rightExpression));
     }
 }
Esempio n. 13
0
        public MiddleCode(MiddleOperator middleOp, object operand0 = null,
                          object operand1 = null, object operand2 = null)
        {
            m_middleOperator  = middleOp;
            m_operandArray[0] = operand0;
            m_operandArray[1] = operand1;
            m_operandArray[2] = operand2;

            if (m_middleOperator == MiddleOperator.InitializerZero)
            {
                int size = (int)operand0;
            }

            /*string s = ToString();
             * if ((s != null) && s.Equals("PopEmpty")) {
             * int i = 1;
             * }*/
        }
        public static Expression Logical(MiddleOperator middleOp,
                                         Expression leftExpression,
                                         Expression rightExpression)
        {
            if (!IsConstant(leftExpression) || !IsConstant(rightExpression))
            {
                return(null);
            }

            bool resultValue = false;

            switch (middleOp)
            {
            case MiddleOperator.LogicalAnd:
                resultValue = IsTrue(leftExpression) && IsTrue(rightExpression);
                break;

            case MiddleOperator.LogicalOr:
                resultValue = IsTrue(leftExpression) || IsTrue(rightExpression);
                break;
            }

            List <MiddleCode> longList = new List <MiddleCode>();
            MiddleCode        jumpCode = new MiddleCode(MiddleOperator.Jump);

            longList.Add(jumpCode);

            ISet <MiddleCode> jumpSet = new HashSet <MiddleCode>();

            jumpSet.Add(jumpCode);

            Symbol resultSymbol = new Symbol(null, null);

            if (resultValue)
            {
                resultSymbol.TrueSet = jumpSet;
            }
            else
            {
                resultSymbol.FalseSet = jumpSet;
            }

            return(new Expression(resultSymbol, null, longList));
        }
        // i = i + 1
        // ++i

        // i = i + (-1)
        // --i

        // i = i - 1
        // --i

        // i = i - (-1)
        // ++i

        // i = i
        // empty

        /*private void OptimizeBinary() {
         * foreach (MiddleCode middleCode in m_middleCodeList) {
         *  MiddleOperator middleOperator = middleCode.Operator;
         *
         *  if (middleOperator == MiddleOperator.BinaryAdd) {
         *    Symbol resultSymbol = (Symbol) middleCode[0], // i = i + 1
         *           leftSymbol = (Symbol) middleCode[1],
         *           rightSymbol = (Symbol) middleCode[2];
         *
         *    if (resultSymbol.Type.IsIntegralPointerArrayStringOrFunction() &&
         *        resultSymbol.Equals(leftSymbol)) {
         *      if (rightSymbol.IsValue() && rightSymbol.Value.Equals(((BigInteger) 1))) {
         *        middleCode.Operator = MiddleOperator.Increment;
         *        middleCode[0] = null;
         *        middleCode[2] = null;
         *        m_update = true;
         *      }
         *      else if (rightSymbol.IsValue() && rightSymbol.Value.Equals(-((BigInteger) 1))) {
         *        middleCode.Operator = MiddleOperator.Decrement;
         *        middleCode[0] = null;
         *        middleCode[2] = null;
         *        m_update = true;
         *      }
         *    }
         *  }
         *  else if (middleOperator == MiddleOperator.BinarySubtract) {
         *    Symbol resultSymbol = (Symbol) middleCode[0], // i = i - 1
         *           leftSymbol = (Symbol) middleCode[1],
         *           rightSymbol = (Symbol) middleCode[2];
         *
         *    if (resultSymbol.Type.IsIntegralPointerArrayStringOrFunction() &&
         *        resultSymbol.Equals(leftSymbol)) {
         *      if (rightSymbol.IsValue() &&
         *          rightSymbol.Value.Equals(((BigInteger) 1))) {
         *        middleCode.Operator = MiddleOperator.Decrement;
         *        middleCode[0] = null;
         *        middleCode[2] = null;
         *        m_update = true;
         *      }
         *      else if (rightSymbol.IsValue() &&
         *               rightSymbol.Value.Equals(-((BigInteger) 1))) {
         *        middleCode.Operator = MiddleOperator.Increment;
         *        middleCode[0] = null;
         *        middleCode[2] = null;
         *        m_update = true;
         *      }
         *    }
         *  }
         *  else if (middleOperator == MiddleOperator.Assign) {
         *    Symbol resultSymbol = (Symbol) middleCode[0], // i = i;
         *           assignSymbol = (Symbol) middleCode[1];
         *
         *    if (resultSymbol.Type.IsIntegralPointerArrayStringOrFunction() &&
         *       resultSymbol.Equals(assignSymbol)) {
         *      middleCode.Operator = MiddleOperator.Empty;
         *      m_update = true;
         *    }
         *  }
         * }
         * }*/

        private void RemoveTrivialAssign()
        {
            foreach (MiddleCode middleCode in m_middleCodeList)
            {
                MiddleOperator middleOperator = middleCode.Operator;

                if (middleOperator == MiddleOperator.Assign)
                {
                    Symbol resultSymbol = (Symbol)middleCode[0],
                           assignSymbol = (Symbol)middleCode[1];

                    if (resultSymbol == assignSymbol)
                    {
                        middleCode.Operator = MiddleOperator.Empty;
                        m_update            = true;
                    }
                }
            }
        }
        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));
        }
        /*private static Expression GenerateIndex(Symbol symbol,
         *                                      BigInteger value) {
         * int offset = ((int) value) * symbol.Type.ArrayType.Size();
         * StaticValue resultValue;
         *
         * if (symbol.Value is StaticAddress) {
         *  StaticAddress staticAddress = (StaticAddress) symbol.Value;
         *  resultValue = new StaticValue(staticAddress.UniqueName,
         *                                staticAddress.Offset + offset);
         * }
         * else {
         *  resultValue = new StaticValue(symbol.UniqueName, offset);
         * }
         *
         * Symbol resultSymbol = new Symbol(symbol.Type, resultValue);
         * return (new Expression(resultSymbol, null, null));
         * }*/

        public static Expression Unary(MiddleOperator middleOp, Expression expression)
        {
            Symbol symbol = expression.Symbol;

            switch (middleOp)
            {
            case MiddleOperator.Address:
                if (symbol.Value is StaticValue) // &a[i], &s.i
                {
                    StaticValue   staticValue   = (StaticValue)symbol.Value;
                    StaticAddress staticAddress =
                        new StaticAddress(staticValue.UniqueName, staticValue.Offset);
                    Symbol resultSymbol =
                        new Symbol(new Type(symbol.Type), staticAddress);
                    return(new Expression(resultSymbol, null, null));
                }
                else if (symbol.IsExternOrStatic()) // &i
                {
                    StaticAddress staticAddress =
                        new StaticAddress(symbol.UniqueName, 0);
                    Symbol resultSymbol =
                        new Symbol(new Type(symbol.Type), staticAddress);
                    return(new Expression(resultSymbol, null, null));
                }
                break;

            case MiddleOperator.Dereference:
                if (symbol.Value is StaticAddress)
                {
                    StaticAddress staticAddress = (StaticAddress)symbol.Value;
                    StaticValue   staticValue   =
                        new StaticValue(staticAddress.UniqueName, staticAddress.Offset);
                    Symbol resultSymbol =
                        new Symbol(new Type(symbol.Type), staticValue);
                    return(new Expression(resultSymbol, null, null));
                }
                break;
            }

            return(null);
        }
        private static Expression ArithmeticFloating(MiddleOperator middleOp,
                                                     Expression expression)
        {
            expression = LogicalToFloating(expression);
            decimal value        = (decimal)expression.Symbol.Value;
            Symbol  resultSymbol = null;

            switch (middleOp)
            {
            case MiddleOperator.Plus:
                resultSymbol = new Symbol(expression.Symbol.Type, value);
                break;

            case MiddleOperator.Minus:
                resultSymbol = new Symbol(expression.Symbol.Type, -value);
                break;
            }

            List <MiddleCode> longList = new List <MiddleCode>();

            MiddleCodeGenerator.AddMiddleCode(longList, MiddleOperator.PushFloat,
                                              resultSymbol);
            return(new Expression(resultSymbol, null, longList));
        }
        private void ClearDoubleRelationStatements()
        {
            for (int index = 0; index < (m_middleCodeList.Count - 1); ++index)
            {
                MiddleCode thisCode = m_middleCodeList[index],
                           nextCode = m_middleCodeList[index + 1];

                if ((thisCode.IsRelation() || thisCode.IsCarry()) &&
                    nextCode.IsGoto())
                {
                    int target1 = (int)thisCode[0],
                        target2 = (int)nextCode[0];

                    if (target1 == (index + 2))
                    {
                        MiddleOperator operator1 = thisCode.Operator;
                        thisCode.Operator = m_inverseMap[operator1];
                        thisCode[0]       = target2;
                        nextCode.Clear();
                        m_update = true;
                    }
                }
            }
        }
        public static Expression Relation(MiddleOperator middleOp,
                                          Expression leftExpression,
                                          Expression rightExpression)
        {
            if (!IsConstant(leftExpression) || !IsConstant(rightExpression))
            {
                return(null);
            }

            leftExpression  = LogicalToIntegral(leftExpression);
            rightExpression = LogicalToIntegral(rightExpression);

            Type leftType  = leftExpression.Symbol.Type,
                 rightType = rightExpression.Symbol.Type;

            object leftValue  = leftExpression.Symbol.Value,
                   rightValue = rightExpression.Symbol.Value;

            int compareTo = 0;

            if (leftType.IsFloating() || rightType.IsFloating())
            {
                decimal leftDecimal, rightDecimal;

                if (leftValue is BigInteger)
                {
                    leftDecimal  = (decimal)((BigInteger)leftValue);
                    rightDecimal = (decimal)rightValue;
                }
                else if (rightValue is BigInteger)
                {
                    leftDecimal  = (decimal)leftValue;
                    rightDecimal = (decimal)((BigInteger)rightValue);
                }
                else
                {
                    leftDecimal  = (decimal)leftValue;
                    rightDecimal = (decimal)rightValue;
                }

                compareTo = leftDecimal.CompareTo(rightDecimal);
            }
            else
            {
                BigInteger leftBigInteger  = (BigInteger)leftExpression.Symbol.Value,
                           rightBigInteger = (BigInteger)rightExpression.Symbol.Value;
                compareTo = leftBigInteger.CompareTo(rightBigInteger);
            }

            bool resultValue = false;

            switch (middleOp)
            {
            case MiddleOperator.Equal:
                resultValue = (compareTo == 0);
                break;

            case MiddleOperator.NotEqual:
                resultValue = (compareTo != 0);
                break;

            case MiddleOperator.LessThan:
                resultValue = (compareTo < 0);
                break;

            case MiddleOperator.LessThanEqual:
                resultValue = (compareTo <= 0);
                break;

            case MiddleOperator.GreaterThan:
                resultValue = (compareTo > 0);
                break;

            case MiddleOperator.GreaterThanEqual:
                resultValue = (compareTo >= 0);
                break;
            }

            List <MiddleCode> longList = new List <MiddleCode>();
            MiddleCode        jumpCode = new MiddleCode(MiddleOperator.Jump);

            longList.Add(jumpCode);

            ISet <MiddleCode> jumpSet = new HashSet <MiddleCode>();

            jumpSet.Add(jumpCode);

            Symbol resultSymbol = new Symbol(null, null);

            if (resultValue)
            {
                resultSymbol.TrueSet = jumpSet;
            }
            else
            {
                resultSymbol.FalseSet = jumpSet;
            }

            return(new Expression(resultSymbol, null, longList));
        }
        public static Expression Binary(MiddleOperator middleOp,
                                        Expression leftExpression,
                                        Expression rightExpression)
        {
            Type leftType     = leftExpression.Symbol.Type,
                 rightType    = rightExpression.Symbol.Type;
            object leftValue  = leftExpression.Symbol.Value,
                   rightValue = rightExpression.Symbol.Value;

            switch (middleOp)
            {
            case MiddleOperator.BinaryAdd: // &i + 2
                if ((leftValue is StaticAddress) && (rightValue is BigInteger))
                {
                    StaticAddress staticAddress = (StaticAddress)leftValue;
                    int           resultOffset  =
                        ((int)rightValue) * leftType.PointerType.Size();
                    object resultValue =
                        new StaticAddress(staticAddress.UniqueName,
                                          staticAddress.Offset + resultOffset);
                    Symbol resultSymbol = new Symbol(leftType, resultValue);
                    return(new Expression(resultSymbol, null, null));
                }

                // 2 + &i
                if ((leftValue is BigInteger) && (rightValue is StaticAddress))
                {
                    StaticAddress staticAddress = (StaticAddress)rightValue;
                    int           resultOffset  =
                        ((int)leftValue) * rightType.PointerType.Size();
                    object resultValue =
                        new StaticAddress(staticAddress.UniqueName,
                                          staticAddress.Offset + resultOffset);
                    Symbol resultSymbol = new Symbol(rightType, resultValue);
                    return(new Expression(resultSymbol, null, null));
                }

                if (leftExpression.Symbol.IsExternOrStatic() && leftType.IsArray() &&
                    (rightValue is BigInteger)) // a + 2
                {
                    int    resultOffset = ((int)rightValue) * leftType.ArrayType.Size();
                    object resultValue  =
                        new StaticAddress(leftExpression.Symbol.UniqueName,
                                          resultOffset);
                    Symbol resultSymbol = new Symbol(leftType, resultValue);
                    return(new Expression(resultSymbol, null, null));
                }

                if (leftExpression.Symbol.IsExternOrStatic() &&
                    (leftValue is BigInteger) && rightType.IsArray()) // 2 + a
                {
                    int    resultOffset = ((int)leftValue) * rightType.ArrayType.Size();
                    object resultValue  =
                        new StaticAddress(rightExpression.Symbol.UniqueName,
                                          resultOffset);
                    Symbol resultSymbol = new Symbol(rightType, resultValue);
                    return(new Expression(resultSymbol, null, null));
                }
                break;

            case MiddleOperator.BinarySubtract: // &i - 2
                if ((leftValue is StaticAddress) && (rightValue is BigInteger))
                {
                    StaticAddress staticAddress = (StaticAddress)leftValue;
                    int           resultOffset  = ((int)leftValue) * leftType.PointerType.Size();
                    object        resultValue   =
                        new StaticAddress(staticAddress.UniqueName,
                                          staticAddress.Offset - resultOffset);
                    Symbol resultSymbol = new Symbol(leftType, resultValue);
                    return(new Expression(resultSymbol, null, null));
                }

                if (leftExpression.Symbol.IsExternOrStatic() && leftType.IsArray() &&
                    (rightValue is BigInteger)) // a - 2
                {
                    int    resultOffset = ((int)rightValue) * leftType.ArrayType.Size();
                    object resultValue  =
                        new StaticAddress(leftExpression.Symbol.UniqueName,
                                          -resultOffset);
                    Symbol resultSymbol = new Symbol(leftType, resultValue);
                    return(new Expression(resultSymbol, null, null));
                }
                break;

            case MiddleOperator.Index:
                if (leftExpression.Symbol.IsExternOrStatic() && leftType.IsArray() &&
                    (rightValue is BigInteger)) // a[2]
                {
                    int         size        = leftType.ArrayType.Size();
                    int         offset      = ((int)((BigInteger)rightValue)) * size;
                    StaticValue resultValue =
                        new StaticValue(leftExpression.Symbol.UniqueName, offset);
                    Symbol resultSymbol = new Symbol(leftType, resultValue);
                    resultSymbol.Addressable = !leftExpression.Symbol.IsRegister() &&
                                               !leftType.ArrayType.IsBitfield();
                    resultSymbol.Assignable =
                        !leftType.ArrayType.IsConstantRecursive() &&
                        !leftType.ArrayType.IsArrayFunctionOrString();
                    return(new Expression(resultSymbol, null, null));
                }
                else if ((leftValue is BigInteger) && rightType.IsArray() &&
                         rightExpression.Symbol.IsExternOrStatic()) // [2]a
                {
                    int         size        = rightType.ArrayType.Size();
                    int         offset      = ((int)((BigInteger)leftValue)) * size;
                    StaticValue resultValue =
                        new StaticValue(rightExpression.Symbol.UniqueName, offset);
                    Symbol resultSymbol = new Symbol(rightType, resultValue);
                    resultSymbol.Addressable = !leftExpression.Symbol.IsRegister() &&
                                               !leftType.ArrayType.IsBitfield();
                    resultSymbol.Assignable =
                        !leftType.ArrayType.IsConstantRecursive() &&
                        !leftType.ArrayType.IsArrayFunctionOrString();
                    return(new Expression(resultSymbol, null, null));
                }
                break;

            case MiddleOperator.Dot:
                if (leftExpression.Symbol.IsExternOrStatic())
                {
                    object resultValue =
                        new StaticValue(leftExpression.Symbol.UniqueName,
                                        rightExpression.Symbol.Offset); // s.i
                    Symbol resultSymbol = new Symbol(leftType, resultValue);
                    return(new Expression(resultSymbol, null, null));
                }
                break;
            }

            return(null);
        }
        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));
        }
        public static Expression Binary(MiddleOperator middleOp,
                                        Expression leftExpression,
                                        Expression rightExpression)
        {
            Symbol leftSymbol = leftExpression.Symbol,
                   rightSymbol = rightExpression.Symbol;
            Type   leftType = leftSymbol.Type, rightType = rightSymbol.Type;
            object leftValue = leftSymbol.Value, rightValue = rightSymbol.Value;

            switch (middleOp)
            {
            case MiddleOperator.Add:
                if ((leftValue is StaticAddress) && (rightValue is BigInteger)) // &i + 2
                {
                    return(GenerateAddition(leftSymbol, (BigInteger)rightValue));
                }
                else if ((leftValue is BigInteger) && (rightValue is StaticAddress))// 2 + &i
                {
                    return(GenerateAddition(rightSymbol, (BigInteger)leftValue));
                }
                else if (leftSymbol.IsExternOrStaticArray() && (rightValue is BigInteger)) // a + 2
                {
                    return(GenerateAddition(leftSymbol, (BigInteger)rightValue));
                }
                else if ((leftValue is BigInteger) && rightSymbol.IsExternOrStaticArray()) // 2 + a
                {
                    return(GenerateAddition(rightSymbol, (BigInteger)leftValue));
                }
                break;

            case MiddleOperator.Subtract:
                if ((leftValue is StaticAddress) && (rightValue is BigInteger)) // &i - 2
                {
                    return(GenerateAddition(leftSymbol, -((BigInteger)rightValue)));
                }
                if (leftSymbol.IsExternOrStaticArray() && (rightValue is BigInteger)) // a - 2
                {
                    return(GenerateAddition(leftSymbol, -((BigInteger)rightValue)));
                }
                break;

            /*case MiddleOperator.Index:
             * if ((leftValue is StaticAddress)  && (rightValue is BigInteger)) { // a[2]
             *  return GenerateIndex(leftSymbol, (BigInteger) rightValue);
             * }
             * else if ((leftValue is BigInteger) && (rightValue is StaticAddress)) {
             *  return GenerateIndex(rightSymbol, (BigInteger) leftValue);
             * }
             * else if (leftSymbol.IsExternOrStaticArray() && (rightValue is BigInteger)) { // a[2]
             *  return GenerateIndex(leftSymbol, (BigInteger) rightValue);
             * }
             * else if ((leftValue is BigInteger) && rightSymbol.IsExternOrStaticArray()) {
             *  return GenerateIndex(rightSymbol, (BigInteger) leftValue);
             * }
             * break;*/

            case MiddleOperator.Dot:
                if (leftSymbol.IsExternOrStatic())
                {
                    object resultValue =
                        new StaticValue(leftSymbol.UniqueName,
                                        rightSymbol.Offset); // s.i
                    Symbol resultSymbol = new Symbol(leftType, resultValue);
                    return(new Expression(resultSymbol, null, null));
                }
                break;
            }

            return(null);
        }