private void DereferenceToIndex()
        {
            for (int index = 0; index < (m_middleCodeList.Count - 1); ++index)
            {
                MiddleCode thisCode = m_middleCodeList[index],
                           nextCode = m_middleCodeList[index + 1];

                // *(a + 3) <=> a[3] <=> *(3 + a) <=> 3[a]
                if ((thisCode.Operator == MiddleOperator.Add) &&
                    (nextCode.Operator == MiddleOperator.Dereference) &&
                    (thisCode[0] == nextCode[1]))
                {
                    Symbol leftSymbol  = (Symbol)thisCode[1],
                           rightSymbol = (Symbol)thisCode[2];

                    if (leftSymbol.Value is BigInteger)
                    {
                        Symbol resultSymbol = (Symbol)nextCode[0];
                        resultSymbol.AddressSymbol = rightSymbol;
                        resultSymbol.AddressOffset = ((int)((BigInteger)leftSymbol.Value));
                        thisCode.Clear();
                    }
                    else if (rightSymbol.Value is BigInteger)
                    {
                        Symbol resultSymbol = (Symbol)nextCode[0];
                        resultSymbol.AddressSymbol = leftSymbol;
                        resultSymbol.AddressOffset = ((int)((BigInteger)rightSymbol.Value));
                        thisCode.Clear();
                    }
                }
                // *(a - 3) <=> a[-3]
                else if ((thisCode.Operator == MiddleOperator.Subtract) &&
                         (nextCode.Operator == MiddleOperator.Dereference) &&
                         (thisCode[0] == nextCode[1]))
                {
                    Symbol leftSymbol  = (Symbol)thisCode[1],
                           rightSymbol = (Symbol)thisCode[2];

                    if (rightSymbol.Value is BigInteger)
                    {
                        Symbol resultSymbol = (Symbol)nextCode[0];
                        resultSymbol.AddressSymbol = leftSymbol;
                        resultSymbol.AddressOffset = -((int)((BigInteger)rightSymbol.Value));
                        thisCode.Clear();
                    }
                }
            }
        }
        // Top x + Pop => Pop x

        // top x
        // pop

        // pop x

        public void MergeTopPopEmptyToPop()
        {
            for (int index = 0; index < (m_middleCodeList.Count - 1); ++index)
            {
                MiddleCode thisCode = m_middleCodeList[index],
                           nextCode = m_middleCodeList[index + 1];

                if ((thisCode.Operator == MiddleOperator.TopFloat) &&
                    (nextCode.Operator == MiddleOperator.PopEmpty))
                {
                    thisCode.Operator = MiddleOperator.PopFloat;
                    nextCode.Clear();
                    m_update = true;
                }
            }
        }
        // t = a
        // b = t

        // b = a

        private void MergeDoubleAssign()
        {
            for (int index = 0; index < (m_middleCodeList.Count - 1); ++index)
            {
                MiddleCode thisCode = m_middleCodeList[index],
                           nextCode = m_middleCodeList[index + 1];

                if ((thisCode.Operator == MiddleOperator.Assign) &&
                    (nextCode.Operator == MiddleOperator.Assign) &&
                    thisCode[0] == nextCode[1])
                {
                    thisCode[0] = nextCode[0];
                    nextCode.Clear();
                    m_update = true;
                }
            }
        }
        // Push x + Pop => empty

        // push x
        // pop

        // empty

        public void RemovePushPop()
        {
            for (int index = 0; index < (m_middleCodeList.Count - 1); ++index)
            {
                MiddleCode thisCode = m_middleCodeList[index],
                           nextCode = m_middleCodeList[index + 1];
                if ((thisCode.Operator == MiddleOperator.PushFloat) &&
                    ((nextCode.Operator == MiddleOperator.PopEmpty) ||
                     ((nextCode.Operator == MiddleOperator.PopFloat) &&
                      (thisCode[0] == nextCode[0]))))
                {
                    thisCode.Clear();
                    nextCode.Clear();
                    m_update = true;
                }
            }
        }
        // --------------------------------------------------------------------------

        // 1. goto 2
        // 2. ...

        private void ClearGotoNextStatements()
        {
            for (int index = 0; index < (m_middleCodeList.Count - 1); ++index)
            {
                MiddleCode middleCode = m_middleCodeList[index];

                if (middleCode.IsRelationCarryOrGoto())
                {
                    int target = (int)middleCode[0];

                    if (target == (index + 1))
                    {
                        middleCode.Clear();
                        m_update = true;
                    }
                }
            }
        }
        // t = b + c
        // a = t

        // a = b + c

        private void MergeBinary()
        {
            for (int index = 0; index < (m_middleCodeList.Count - 1); ++index)
            {
                MiddleCode thisCode = m_middleCodeList[index],
                           nextCode = m_middleCodeList[index + 1];

                if ((/*thisCode.IsUnary() ||*/ thisCode.IsBinary()) &&
                    (nextCode.Operator == MiddleOperator.Assign) &&
                    ((Symbol)thisCode[0]).IsTemporary() &&
                    (thisCode[0] == nextCode[1]))
                {
                    thisCode[0] = nextCode[0];
                    nextCode.Clear();
                    m_update = true;
                }
            }
        }
        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;
                    }
                }
            }
        }