/// <summary>
 /// 跳转之后的调整
 /// </summary>
 /// <param name="f">四元式</param>
 /// <param name="reg1">寄存器1</param>
 /// <param name="reg2">寄存器2</param>
 /// <param name="varTable">变量表</param>
 /// <param name="cmdList">汇编指令列表</param>
 private void adjustAfterJump(FourExp f, string reg1, string reg2, VarTable varTable, List<AssemblerIns> cmdList)
 {
     if (varTable.GetPeekActInfo(f.Arg1) == false)
     {
         cmdList.Add(AssemblerFac.GenSW(reg1, varTable.GetAddr(f.Arg1).ToString(), "$ZERO"));
         varTable.SetAddrInfo(f.Arg1, "");
         regUseTable.GetContent(reg1).Remove(f.Arg1);
     }
     if (varTable.GetPeekActInfo(f.Arg2) == false)
     {
         cmdList.Add(AssemblerFac.GenSW(reg2, varTable.GetAddr(f.Arg2).ToString(), "$ZERO"));
         varTable.SetAddrInfo(f.Arg2, "");
         regUseTable.GetContent(reg2).Remove(f.Arg2);
     }
 }
        /// <summary>
        /// 将四元式翻译为汇编指令
        /// </summary>
        /// <param name="f">四元式</param>
        /// <param name="varTable">变量表</param>
        /// <param name="cmdList">汇编指令列表</param>
        private void convert(FourExp f, VarTable varTable, List<AssemblerIns> cmdList)
        {
            #region Label FourExp
            if (f.Op == FourExpOperation.label)
            {
                cmdList.Add(AssemblerFac.GenLABEL(f.LabelName));
            }
            #endregion

            #region Jump Operation
            if (f.Op >= FourExpOperation.jmp && f.Op <= FourExpOperation.jle)
            {
                string operation = "";
                switch (f.Op)
                {
                    case FourExpOperation.jmp:
                        operation = Mnemonic.J.ToString();
                        cmdList.Add(AssemblerFac.GenJ(f.TargetLabel));
                        break;
                    case FourExpOperation.je:
                        operation = Mnemonic.BEQ.ToString();
                        doJump(f, operation, varTable, cmdList);
                        break;
                    case FourExpOperation.jne:
                        operation = Mnemonic.BNE.ToString();
                        doJump(f, operation, varTable, cmdList);
                        break;
                    case FourExpOperation.jg:
                        operation = Mnemonic.BGTZ.ToString();
                        doJump(f, operation, varTable, cmdList);
                        break;
                    case FourExpOperation.jge:
                        operation = Mnemonic.BGEZ.ToString();
                        doJump(f, operation, varTable, cmdList);
                        break;
                    case FourExpOperation.jl:
                        operation = Mnemonic.BLTZ.ToString();
                        doJump(f, operation, varTable, cmdList);
                        break;
                    case FourExpOperation.jle:
                        operation = Mnemonic.BLEZ.ToString();
                        doJump(f, operation, varTable, cmdList);
                        break;
                    default:
                        //错误处理
                        break;
                }

            }
            #endregion

            #region Move Operation
            else if (f.Op == FourExpOperation.mov)
            {
                string regB = "";
                if (isNumber(f.Arg1))
                {
                    regB = getReg(f, varTable, false, cmdList);
                    int value = Convert.ToInt32(f.Arg1);
                    if (value <= 32767 && value >= -32768)
                    {
                        cmdList.Add(AssemblerFac.GenLUI(regB, value.ToString()));
                        cmdList.Add(AssemblerFac.GenSRL(regB, regB, 16 + ""));
                    }
                    else
                    {
                        short high = Convert.ToInt16(value >> 16);
                        cmdList.Add(AssemblerFac.GenLUI(regB, high + ""));
                        short low = Convert.ToInt16(value & 0xffff);
                        cmdList.Add(AssemblerFac.GenORI(regB, regB, low + ""));
                    }
                }
                else
                {
                    if (varTable.GetAddrInfo(f.Arg1) == "")
                    {
                        regB = getReg(f, varTable, false, cmdList);
                        cmdList.Add(AssemblerFac.GenLW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO"));
                        regUseTable.GetContent(regB).Add(f.Arg1);
                        varTable.SetAddrInfo(f.Arg1, regB);
                    }
                    else
                    {
                        regB = varTable.GetAddrInfo(f.Arg1);
                    }
                }
                regUseTable.GetContent(regB).Add(f.Result);
                varTable.SetAddrInfo(f.Result, regB);

                if(varTable.Contains(f.Arg1) && varTable.GetPeekActInfo(f.Arg1) == false)
                {
                    cmdList.Add(AssemblerFac.GenSW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO"));
                    varTable.SetAddrInfo(f.Arg1, "");
                    regUseTable.GetContent(regB).Remove(f.Arg1);
                }

                if (varTable.Contains(f.Result) && varTable.GetPeekActInfo(f.Result) == false)
                {
                    cmdList.Add(AssemblerFac.GenSW(regB, varTable.GetAddr(f.Result).ToString(), "$ZERO"));
                    varTable.SetAddrInfo(f.Result, "");
                    regUseTable.GetContent(regB).Remove(f.Result);
                }
            }
            #endregion

            #region Arithmetical or Logical Operation
            else if (f.Op <= FourExpOperation.or)//数学或逻辑运算
            {
                //获取第一个参数的寄存器
                string regA, regB, regC;
                if (isNumber(f.Arg1))
                {
                    regB = getReg(f, varTable, false, cmdList);
                    int value = Convert.ToInt32(f.Arg1);
                    if (value <= 32767 && value >= -32768)
                    {
                        cmdList.Add(AssemblerFac.GenLUI(regB, value.ToString()));
                        cmdList.Add(AssemblerFac.GenSRL(regB, regB, 16 + ""));
                    }
                    else
                    {
                        short high = Convert.ToInt16(value >> 16);
                        cmdList.Add(AssemblerFac.GenLUI(regB, high + ""));
                        short low = Convert.ToInt16(value & 0xffff);
                        cmdList.Add(AssemblerFac.GenORI(regB, regB, low + ""));
                    }
                }
                else
                {
                    if (varTable.GetAddrInfo(f.Arg1) == "")
                    {
                        regB = getReg(f, varTable, false, cmdList);
                        varTable.SetAddrInfo(f.Arg1, regB);
                        regUseTable.Add(regB, f.Arg1);
                        cmdList.Add(AssemblerFac.GenLW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO"));
                    }
                    else
                    {
                        regB = varTable.GetAddrInfo(f.Arg1);
                    }
                }
                //获取第二个参数的寄存器
                if (isNumber(f.Arg1))
                {
                    regC = getReg(f, varTable, false, cmdList);
                    int value = Convert.ToInt32(f.Arg2);
                    if (value <= 32767 && value >= -32768)
                    {
                        cmdList.Add(AssemblerFac.GenLUI(regC, value.ToString()));
                        cmdList.Add(AssemblerFac.GenSRL(regC, regC, 16 + ""));
                    }
                    else
                    {
                        short high = Convert.ToInt16(value >> 16);
                        cmdList.Add(AssemblerFac.GenLUI(regC, high + ""));
                        short low = Convert.ToInt16(value & 0xffff);
                        cmdList.Add(AssemblerFac.GenORI(regC, regC, low + ""));
                    }
                }
                else
                {
                    if (varTable.GetAddrInfo(f.Arg2) == "")
                    {
                        regC = getReg(f, varTable, false, cmdList);
                        varTable.SetAddrInfo(f.Arg2, regC);
                        regUseTable.Add(regC, f.Arg2);
                        cmdList.Add(AssemblerFac.GenLW(regC, varTable.GetAddr(f.Arg2).ToString(), "$ZERO"));
                    }
                    else
                    {
                        regC = varTable.GetAddrInfo(f.Arg2);
                    }
                }

                //获取计算结果的寄存器
                regA = getReg(f, varTable, true, cmdList);
                varTable.SetAddrInfo(f.Result, regA);
                regUseTable.Add(regA, f.Result);

                if (regA == regB)
                {
                    foreach (string var in regUseTable.GetContent(regB))
                    {
                        cmdList.Add(AssemblerFac.GenSW(regB, varTable.GetAddr(var).ToString(), "$ZERO"));
                        varTable.SetAddrInfo(var, "");
                        regUseTable.GetContent(regB).Remove(var);
                    }
                }
                if (regA == regC)
                {
                    foreach (string var in regUseTable.GetContent(regC))
                    {
                        cmdList.Add(AssemblerFac.GenSW(regC, varTable.GetAddr(var).ToString(), "$ZERO"));
                        varTable.SetAddrInfo(var, "");
                        regUseTable.GetContent(regC).Remove(var);
                    }
                }
                string operation = "";
                switch (f.Op)
                {
                    case FourExpOperation.add:
                        operation = Mnemonic.ADD.ToString();
                        break;
                    case FourExpOperation.sub:
                        operation = Mnemonic.SUB.ToString();
                        break;
                    //case FourExpOperation.mul:

                    //    break;
                    //case FourExpOperation.div:

                    //    break;
                    case FourExpOperation.and:
                        operation = Mnemonic.AND.ToString();
                        break;
                    case FourExpOperation.or:
                        operation = Mnemonic.OR.ToString();
                        break;
                    case FourExpOperation.xor:
                        operation = Mnemonic.XOR.ToString();
                        break;
                    case FourExpOperation.nor:
                        operation = Mnemonic.NOR.ToString();
                        break;
                    default:
                        //错误处理
                        break;
                }
                cmdList.Add(AssemblerFac.GenMathOrLog(operation, regA, regB, regC));
                if (varTable.Contains(f.Arg1) && (varTable.GetAddrInfo(f.Arg1) != null) && (varTable.GetPeekActInfo(f.Arg1) == false))
                {
                    cmdList.Add(AssemblerFac.GenSW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO"));
                    varTable.SetAddrInfo(f.Arg1, "");
                    regUseTable.GetContent(regB).Remove(f.Arg1);
                }
                if (varTable.Contains(f.Arg2) && (varTable.GetAddrInfo(f.Arg2) != null) && (varTable.GetPeekActInfo(f.Arg2) == false))
                {
                    cmdList.Add(AssemblerFac.GenSW(regC, varTable.GetAddr(f.Arg2).ToString(), "$ZERO"));
                    varTable.SetAddrInfo(f.Arg2, "");
                    regUseTable.GetContent(regC).Remove(f.Arg2);
                }
                if (varTable.Contains(f.Result) && varTable.GetPeekActInfo(f.Result) == false)
                {
                    cmdList.Add(AssemblerFac.GenSW(regA, varTable.GetAddr(f.Result).ToString(), "$ZERO"));
                    varTable.SetAddrInfo(f.Result, "");
                    regUseTable.GetContent(regA).Remove(f.Result);
                }
            }
            #endregion

            #region Not or Neg Operation
            else if (f.Op == FourExpOperation.neg)
            {
                string regB;
                if (isNumber(f.Arg1))
                {
                    regB = getReg(f, varTable, false, cmdList);
                    int value = Convert.ToInt32(f.Arg1);
                    if (value <= 32767 && value >= -32768)
                    {
                        cmdList.Add(AssemblerFac.GenLUI(regB, value.ToString()));
                        cmdList.Add(AssemblerFac.GenSRL(regB, regB, 16 + ""));
                    }
                    else
                    {
                        short high = Convert.ToInt16(value >> 16);
                        cmdList.Add(AssemblerFac.GenLUI(regB, high + ""));
                        short low = Convert.ToInt16(value & 0xffff);
                        cmdList.Add(AssemblerFac.GenORI(regB, regB, low + ""));
                    }
                }
                else
                {
                    regB = varTable.GetAddrInfo(f.Arg1);
                    if (regB == "")
                    {
                        regB = getReg(f, varTable, false, cmdList);
                        cmdList.Add(AssemblerFac.GenLW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO"));
                        varTable.SetAddrInfo(f.Arg1, regB);
                        regUseTable.GetContent(regB).Add(f.Arg1);
                    }
                }

                string regA = varTable.GetAddrInfo(f.Result);
                if (regA == "")
                {
                    regA = getReg(f, varTable, true, cmdList);
                    varTable.SetAddrInfo(f.Result, regA);
                    regUseTable.GetContent(regA).Add(f.Result);
                }
                cmdList.Add(AssemblerFac.GenSUB(regA, "$ZERO", regB));
                if (varTable.Contains(f.Arg1) && varTable.GetPeekActInfo(f.Arg1) == false)
                {
                    cmdList.Add(AssemblerFac.GenSW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO"));
                    varTable.SetAddrInfo(f.Arg1, "");
                    regUseTable.GetContent(regB).Remove(f.Arg1);
                }
                if (varTable.Contains(f.Arg1) && varTable.GetPeekActInfo(f.Result) == false)
                {
                    cmdList.Add(AssemblerFac.GenSW(regA, varTable.GetAddr(f.Result).ToString(), "$ZERO"));
                    varTable.SetAddrInfo(f.Result, "");
                    regUseTable.GetContent(regA).Remove(f.Result);
                }
            }
            else if (f.Op == FourExpOperation.not)
            {
                string regB;
                if (isNumber(f.Arg1))
                {
                    regB = getReg(f, varTable, false, cmdList);
                    int value = Convert.ToInt32(f.Arg1);
                    if (value <= 32767 && value >= -32768)
                    {
                        cmdList.Add(AssemblerFac.GenLUI(regB, value.ToString()));
                        cmdList.Add(AssemblerFac.GenSRL(regB, regB, 16 + ""));
                    }
                    else
                    {
                        short high = Convert.ToInt16(value >> 16);
                        cmdList.Add(AssemblerFac.GenLUI(regB, high + ""));
                        short low = Convert.ToInt16(value & 0xffff);
                        cmdList.Add(AssemblerFac.GenORI(regB, regB, low + ""));
                    }
                }
                else
                {
                    regB = varTable.GetAddrInfo(f.Arg1);
                    if (regB == "")
                    {
                        regB = getReg(f, varTable, false, cmdList);
                        cmdList.Add(AssemblerFac.GenLW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO"));
                        varTable.SetAddrInfo(f.Arg1, regB);
                        regUseTable.GetContent(regB).Add(f.Arg1);
                    }
                }

                string regA = varTable.GetAddrInfo(f.Result);
                if (regA == "")
                {
                    regA = getReg(f, varTable, true, cmdList);
                    varTable.SetAddrInfo(f.Result, regA);
                    regUseTable.GetContent(regA).Add(f.Result);
                }
                cmdList.Add(AssemblerFac.GenXORI(regA, regB, Convert.ToString(1)));//a = NOT b => a = b xor 1
                if (varTable.Contains(f.Arg1) && varTable.GetPeekActInfo(f.Arg1) == false)
                {
                    cmdList.Add(AssemblerFac.GenSW(regB, varTable.GetAddr(f.Arg1).ToString(), "$ZERO"));
                    varTable.SetAddrInfo(f.Arg1, "");
                    regUseTable.GetContent(regB).Remove(f.Arg1);
                }
                if (varTable.Contains(f.Result) && varTable.GetPeekActInfo(f.Result) == false)
                {
                    cmdList.Add(AssemblerFac.GenSW(regA, varTable.GetAddr(f.Result).ToString(), "$ZERO"));
                    varTable.SetAddrInfo(f.Result, "");
                    regUseTable.GetContent(regA).Remove(f.Result);
                }
            }
            #endregion

            #region Rightshift or Leftshift
            else if (f.Op == FourExpOperation.leftshift || f.Op == FourExpOperation.rightshift)
            {

            }
            #endregion

            else
            {
                //错误处理
            }
        }
 /// <summary>
 /// 翻译跳转指令
 /// </summary>
 /// <param name="f">四元式</param>
 /// <param name="operation">汇编指令的操作助记符</param>
 /// <param name="varTable">变量表</param>
 /// <param name="cmdList">汇编指令列表</param>
 private void doJump(FourExp f, string operation, VarTable varTable, List<AssemblerIns> cmdList)
 {
     string reg1 = "", reg2 = "";
     reg1 = varTable.GetAddrInfo(f.Arg1);
     reg2 = varTable.GetAddrInfo(f.Arg2);
     if (reg1 == "")
     {
         reg1 = getReg(f, varTable, false, cmdList);
         cmdList.Add(AssemblerFac.GenLW(reg1, varTable.GetAddr(f.Arg1).ToString(), "$ZERO"));
         regUseTable.GetContent(reg1).Add(f.Arg1);
         varTable.SetAddrInfo(f.Arg1, reg1);
     }
     if (reg2 == "")
     {
         reg2 = getReg(f, varTable, false, cmdList);
         cmdList.Add(AssemblerFac.GenLW(reg2, varTable.GetAddr(f.Arg2).ToString(), "$ZERO"));
         regUseTable.GetContent(reg2).Add(f.Arg2);
         varTable.SetAddrInfo(f.Arg2, reg2);
     }
     cmdList.Add(AssemblerFac.GenSLT("$T0", reg1, reg2));
     cmdList.Add(AssemblerFac.GenJUMP(operation, "$T0", f.TargetLabel.ToString()));
     adjustAfterJump(f, reg1, reg2, varTable, cmdList);
 }
 /// <summary>
 /// 生成数据段
 /// </summary>
 /// <param name="varNameList">变量名列表</param>
 /// <param name="varTable">变量表</param>
 /// <param name="cmdList">汇编指令列表</param>
 private void genDataIns(List<string> varNameList, VarTable varTable, List<AssemblerIns> cmdList)
 {
     foreach (string varName in varNameList)
     {
         if (varTable.GetType(varName) == VariableType.INT || varTable.GetType(varName) == VariableType.CHAR || varTable.GetType(varName) == VariableType.BOOL)
         {
             short varValue = (short)varTable.GetValue(varName);
             short varAddr = varTable.GetAddr(varName);
             cmdList.Add(AssemblerFac.GenLUI("$T0", varValue.ToString()));
             cmdList.Add(AssemblerFac.GenSRL("$T0", "$T0", Convert.ToString(16)));
             cmdList.Add(AssemblerFac.GenSW("$T0", varAddr.ToString(), "$ZERO"));
         }
         else
         {
             int value = varTable.GetValue(varName);
             short high = (short)(value>>16);
             short varAddr = varTable.GetAddr(varName);
             cmdList.Add(AssemblerFac.GenLUI("$T0", high.ToString()));
             short low = (short)(value & 0xffff);
             cmdList.Add(AssemblerFac.GenORI("$T0", "$T0", low.ToString()));
             cmdList.Add(AssemblerFac.GenSW("$T0", varAddr.ToString(), "$ZERO"));
         }
     }
 }
 /// <summary>
 /// 调整变量表和寄存器表中的相关域
 /// </summary>
 /// <param name="regName">计算器名</param>
 /// <param name="varTable">变量表</param>
 /// <param name="cmdList">汇编指令列表</param>
 private void doAdjust(string regName, VarTable varTable, List<AssemblerIns> cmdList)
 {
     foreach (string varName in regUseTable.GetContent(regName))
     {
         cmdList.Add(AssemblerFac.GenSW(regName, varTable.GetAddr(varName).ToString(), "$ZERO"));
         varTable.SetAddrInfo(varName, "");
     }
     regUseTable.Clear(regName);
 }