public String WriteTemp(Temp n, ARGU argu,int vRegister)
	   {
         Proc currProc = (Proc)argu;
		 String t1 = currProc.GetReg(Integer.parseInt(n.f1.f0.tokenImage));
         if(t1.equals("OverFlow"))
		   return RegPlan.RegList[vRegister+4];
		 else//如果当前temp 占用寄存器的话
            return t1;
		
       }
		public String ReadTemp(Temp n,ARGU argu, int vRegister)
	   {
         Proc currProc = (Proc)argu;
		 String t1 = currProc.GetReg(Integer.parseInt(n.f1.f0.tokenImage));
		 if(t1.equals("OverFlow"))
		 {
		  	OutPut.con(" ALOAD " + RegPlan.RegList[vRegister+4] + " SPILLEDARG " +currProc.StackRecorder.indexOf(Integer.parseInt(n.f1.f0.tokenImage))+ "\n");
			return RegPlan.RegList[vRegister+4];
		 }
		 else//如果当前temp 要占用寄存器的话
            return t1;
	   }
       	public void SpillToStack(Temp n, ARGU argu,int vRegister)
	    {//如果转换之前HLOAD的第一个寄存器是注定要溢出的,那么用v0或v1先存放HLOAD进来的值,然后把该值溢出到栈里
	     Proc currProc = (Proc)argu;
		 String t1 = currProc.GetReg(Integer.parseInt(n.f1.f0.tokenImage));
		 if(t1.equals("OverFlow"))
		 {
		   if( !currProc.StackRecorder.contains(Integer.parseInt(n.f1.f0.tokenImage)))
		   {
		    OutPut.con(" ASTORE " + " SPILLEDARG " + currProc.StackRecorder.size()+ " " + RegPlan.RegList[vRegister+4] + "\n");
		    currProc.StackRecorder.add(Integer.parseInt(n.f1.f0.tokenImage));
		   }
		   else  
			OutPut.con(" ASTORE " + " SPILLEDARG " + currProc.StackRecorder.indexOf(Integer.parseInt(n.f1.f0.tokenImage))+ " " + RegPlan.RegList[vRegister+4] + "\n");
		 }
		 return ;
	    }
	/**
	 * Grammar production:
	 * f0 -> "HLOAD"
	 * f1 -> Temp()
	 * f2 -> Temp()
	 * f3 -> IntegerLiteral()
	 */
	public void visit(HLoadStmt n,ARGU argu)
	{
		Proc currProc = (Proc)argu;
		String t = currProc.GetReg(Integer.parseInt(n.f1.f1.f0.tokenImage));
        if(t==null)  
        {
    		OutPut.con(" NOOP \n");
        	return;
        }            
        String t1 = WriteTemp(n.f1,argu, 0);
		String t2 = ReadTemp(n.f2,argu, 0);
		OutPut.con(" HLOAD " + t1 + " " + t2 + " ");
		n.f3.accept(this, argu);
		OutPut.con("\n");
		SpillToStack(n.f1,argu,0);
	}
	/**
	 * Grammar production:
	 * f0 -> "MOVE"
	 * f1 -> Temp()
	 * f2 -> Exp()	
	 *				 Exp() Grammar production:
	 						* f0 -> Call()
	 						*       | HAllocate()
	 						*       | BinOp()
	 						*       | SimpleExp()
 */
	public void visit(MoveStmt n,ARGU argu)
	{
		Proc currProc = (Proc)argu;
		String t = currProc.GetReg(Integer.parseInt(n.f1.f1.f0.tokenImage));;
		if(t==null)                //************************************************
		{
			OutPut.con(" NOOP  \n" );
			return;
		}                        //*************************************************
		int i = n.f2.f0.which;
		
		if(i == 0)//是call语句
		{
			n.f2.accept(this, argu);
			OutPut.con("\n");
			String t1 = WriteTemp(n.f1,argu, 0);
			OutPut.con(" MOVE " + t1 + " v0\n" );
			SpillToStack(n.f1,argu,0);
			return;
		}
		else if(i == 1)//是HALLOCATE
		{
            String t1 = SimpleExpCode(((HAllocate)n.f2.f0.choice).f1, argu,0);//s1 返回的是个数值
			String t2 = WriteTemp(n.f1, argu, 0);
			OutPut.con(" MOVE " + t2 + " HALLOCATE " + t1 + "\n");
			SpillToStack(n.f1,argu,0);
			return;			
		}
		else if(i == 2)//是binop
		{
			String t1 = ReadTemp(((BinOp)n.f2.f0.choice).f1, argu, 0);//b.f1是个寄存器
			String t2 = SimpleExpCode(((BinOp)n.f2.f0.choice).f2, argu,1);//s1 返回的是个数值
			String t3 = WriteTemp(n.f1, argu, 0);
			OutPut.con(" MOVE " + t3 + " ");
			((BinOp)n.f2.f0.choice).f0.accept(this, argu);//b.f0是个运算符
			OutPut.con(" " + t1 + " " + t2 + "\n");
			SpillToStack(n.f1,argu,0);
	    }
		else if(i == 3)//是简单表达式
		{
            String t1 = WriteTemp(n.f1,argu, 0);
			String t2 = SimpleExpCode(((SimpleExp)n.f2.f0.choice), argu,0);//s1 返回的是个数值
			OutPut.con(" MOVE " + t1 + " " + t2 + "\n");
			SpillToStack(n.f1,argu,0);
		}
		return;		
	}