⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tm.cpp

📁 上课时老师用过的SNL编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:

/****************************************************/
/* 函数名 doCommand									*/
/* 功  能 TM机交互命令处理函数						*/
/* 说  明 函数处理用户输入的TM操作命令,完成相应动作	*/
/****************************************************/
int Ctm::doCommand (void)

{ char cmd;				/* 用户输入命令简称 */

  int stepcnt=0, i;
  int printcnt;
  int stepResult;
  int regNo, loc;

  Cindialog  myinput;

  do
  { 
	
	  //创建模式对话框,接受用户输入命令:
	  myinput.DoModal();
	  //m_input记录了用户输入的命令:
	  strcpy( in_Line , myinput.m_input);

	  lineLen = strlen(in_Line);
	  inCol = 0;
  }
  /* 重复请求用户输入命令名,直到得到文字输入 */
  while (! getWord ()); 


  cmd = word[0] ;		/* 取输入命令名中的第一个字符给cmd */

  //声明帮助对话框:
  //Ccomhelp  myhelp;

  switch ( cmd )
  { 
 	/* 该命令用于设置指令执行追踪标志,追踪指令执行 */
    case 't' :

      traceflag = ! traceflag ;		/* 取反设置追踪标志traceflag */

	  /* 输出TM机t命令执行结果信息 */
      //fprintf(listing,"Tracing now ");
	  str2 += "Tracing now ";

      if ( traceflag ) 
		  //fprintf(listing,"on.\r\n");
		  str2 += "on.\r\n";
	  else
		  //fprintf(listing,"off.\r\n");
		  str2 += "off.\r\n";
      break;
    /**************************************************************/
    
	//注:由于输入对话框已经给出提示,故这里的帮助已经没有用了。

    /* 该命令输出帮助信息列表,显示各种命令及其功能 */
    //case 'h' :

	//myhelp.DoModal();

    //break;
    /**************************************************************/

	/* 跟踪显示所有执行过指令的p命令 */
    case 'p' :

      icountflag = ! icountflag ;		/* 设置执行指令计数标志 */

	  /* 输出p命令执行的结果信息 */
      //fprintf(listing,"Printing instruction count now ");
      str2+= "Printing instruction count now ";
	  if ( icountflag ) 
		  //fprintf(listing,"on.\r\n");
		  str2+="on.\r\n";
	  else
		  //fprintf(listing,"off.\r\n");
          str2+="off.\r\n";
	  break;
    /**************************************************************/

	/* 按步执行s命令 */
    case 's' :

	  /* 缺省的命令模式,不带命令参数,单步执行 */
      if ( atEOL ())  stepcnt = 1;

	  /* 带有命令参数的命令模式,取得参数stepcnt */
      else if ( getNum ())  stepcnt = abs(num);

	  /* 输出未知命令执行步数信息 */
      else  
		  //fprintf(listing,"Step count?\r\n");
		  str2+= "Step count?\r\n" ;
	  break;
    /**************************************************************/


	/* 执行到结束g命令 */
    case 'g' :   stepcnt = 1 ;     break;
    /**************************************************************/

    /* 显示寄存器内容(regs)命令 */
    case 'r' :

  	  /* 格式化显示所有寄存器内容 */
      for (i = 0; i < NO_REGS; i++)
      { //fprintf(listing,"%1d: %4d    ", i,reg[i]);
        str1.Format("%1d: %4d    ", i,reg[i]);
		str2+=str1;
		 if ( (i % 4) == 3 ) 
			 //printf ("\r\n");
			 str2+="\r\n";
	  }
      break;
    /**************************************************************/

	/* 输出指令存储区iMem中指令的i命令 */
    case 'i' :

	  /* 初始化输出指令数printcnt为1 */
	  printcnt = 1 ;

      if ( getNum ())
      { 
		/* 得到命令的第一个执行参数,iloc指定输出指令的开始地址 */
		iloc = num ;
		
		/* 得到命令的第二个执行参数,printcnt指定输出指令的数量 */
        if ( getNum ()) printcnt = num ;
      }

	  /* 未给定指令开始地址和输出指令数量 */
      if ( ! atEOL ())
        //fprintf(listing,"Instruction locations?\r\n");
		str2+="Instruction locations?\r\n";
      else
      { 
		/* 指令地址iloc在指令存储区iMem地址范围中,						*
		 * 且指令输出数量printcnt大于0,从iloc指定地址输出指定数量指令	*/
	    while ((iloc >= 0) && (iloc < IADDR_SIZE)
                && (printcnt > 0) )
        { writeInstruction(iloc);
          iloc++ ;
          printcnt-- ;
        }
      }
     break;
    /**************************************************************/

	/* 输出数据存储区dMem中的数据的d命令 */
    case 'd' :

	  printcnt = 1 ;
      if ( getNum  ())
      { 
		/* 取得命令的第一执行参数,数据存储的开始地址dloc */
		dloc = num ;

		/* 取得命令的第二执行参数,输出数据的数量printcnt */
        if ( getNum ()) printcnt = num ;
      }

	  /* 未给定数据存储区中的数据开始地址和数量 */
      if ( ! atEOL ())
       // fprintf(listing,"Data locations?\r\n");
		str2+= "Data locations?\r\n";
      else
      {
  	    /* 给定数据地址dloc在数据存储区dMen地址范围内,					*
		 * 且数据输出数量printcnt大于0,从dloc指定地址输出指定数量的数据 */
		while ((dloc >= 0) && (dloc < DADDR_SIZE)
                  && (printcnt > 0))
        {
		  //fprintf(listing,"%5d: %5d\r\n",dloc,dMem[dloc]);
          str1.Format("%5d: %5d\r\n",dloc,dMem[dloc]);
		  str2+= str1;

		  dloc++;
          printcnt--;
        }
      }
      break;
    /**************************************************************/

    /* 重置tm机用以执行新的程序(clear)指令 */
    case 'c' :

      iloc = 0;			/* 指令存储地址,初始为0 */

      dloc = 0;			/* 数据存储地址,初始为0 */

      stepcnt = 0;		/* 指令执行步数,初始为0 */

	  /* 初始化各寄存器reg[]为0 */
      for (regNo = 0;  regNo < NO_REGS ; regNo++)
            reg[regNo] = 0 ;			

	  /* 数据存储区0地址单元用于记录数据存储区dMem的高端地址 */
      dMem[0] = DADDR_SIZE - 1 ;

	  /* 初始化其它数据存储区单元为0 */
      for (loc = 1 ; loc < DADDR_SIZE ; loc++)
            dMem[loc] = 0 ;				
      break;
    /**************************************************************/

    case 'q' : return FALSE;		/* 停止执行并退出命令 */
    /**************************************************************/

	/* 其它未定义命令,输出错误信息 */
    default : 
		//fprintf(listing,"Command %c unknown.\r\n", cmd); break;
		str1.Format("Command %c unknown.\r\n", cmd);
		str2+=str1;

  }  /* case */

  /******************** 命令的后续处理 **********************/

  stepResult = srOKAY;		/* 命令执行结果为srOKAY */

  if ( stepcnt > 0 )
  { if ( cmd == 'g' )
    { stepcnt = 0;			/* 此处stepcnt作为已经执行过的指令数目 */

      while (stepResult == srOKAY)
      { 
		/* 根据执行指令追踪标志traceflag,将当前地址iloc上指令输出到屏幕 */
		iloc = reg[PC_REG] ;
        if ( traceflag ) writeInstruction( iloc ) ;


		/* 单步执行当前指令,结果返回stepResult */
        stepResult = stepTM ();

		/* 执行过指令计数stepcnt加1 */
        stepcnt++;

      }

	  /* 根据执行执行数量追踪标志icountflag,显示已经执行过的指令数量 */
      if ( icountflag )
        //fprintf(listing,"Number of instructions executed = %d\r\n",stepcnt);
		str1.Format("Number of instructions executed = %d\r\n",stepcnt);
	    str2+= str1;
  }

    else
    { 
	  /* 在其它命令中stepcnt作为将执行,输出的指令或数据的数量 */	
	  while ((stepcnt > 0) && (stepResult == srOKAY))

      { 
		/* 取得程序计数器reg[PC_REG]中当前指令地址 */
		iloc = reg[PC_REG] ;

		/* 根据执行指令追踪标志traceflag,将当前指令地址iloc上指令输出到屏幕 */
        if ( traceflag ) writeInstruction( iloc ) ;

		/* 执行当前指令,结果返回stepResult */
        stepResult = stepTM ();

		/* stepcnt此时用于记录将要执行,输出的指令或数据的数量,自减 */
        stepcnt-- ;
      }
    }
	/* 根据执行结果的枚举值,查执行结果状态表,显示结果状态 */
    //fprintf(listing, "%s\r\n",stepResultTab[stepResult] );
	str1.Format( "%s\r\n",stepResultTab[stepResult]);
	str2+=str1;
  }

    //当输入的命令是c和q时不显示结果对话框:
    if ((myinput.m_input!="c")&&(myinput.m_input!="q"))
	{
		//创建输出对话框,显示执行结果:
  		Cresult myresult ; 
		myresult.m_tEdit.Format(_T("%s"),str2);
		myresult.DoModal();
	}

  return TRUE;
} /* doCommand */


/********************************************/
/* 函数名 tmain								*/
/* 功  能 tm机主执行函数					*/
/* 说  明 函数完成tm机的命令处理,			*/
/*		  并解释执行目标指令				*/
/********************************************/ 
void Ctm::tmain(char * codefile)

{ 
	

/***************从构造函数拷贝,每次调用都要初始化*************/

   	iloc = 0 ;			/* 指令存储计数指针,初始为0 */

	dloc = 0 ;			/* 数据存储计数指针,初始为0 */

	traceflag = FALSE;	/* 指令执行追踪标志,初始为FALSE */

	icountflag = FALSE;	/* 指令执行计数标志,初始为FALSE */

/****************************************************************/

    pgm = fopen(codefile/*pgmName*/,"r");	

  /* 未能成功打开目标代码文件pgmName,输出错误信息 */
  if (pgm == NULL)
  { 
	AfxGetApp()->m_pMainWnd->MessageBox("未找到目标代码文件。");
	return;
  }								

  /* 读入指令:将指令存储区iMem清空并从指定的文件中写入指令序列 */
  if ( ! readInstructions ())
  {
	  AfxGetApp()->m_pMainWnd->MessageBox("不能读取指令!");
	  return;
  }

  /* 准备执行TM虚拟机命令,输出提示信息 */
  //fprintf(listing,"TM  simulation (enter h for help)...\r\n");
   AfxGetApp()->m_pMainWnd->MessageBox("开始解释虚拟机");

   
  
  /* 交互执行,处理用户输入的TM命令,对已经输入到iMem中的指令进行操作 */
   do
   {
	 //输出对话框清空:
	 str1.Empty();
     str2.Empty();

	 //执行一个命令:
	 done = ! doCommand ();	

   }
   while (! done );

  /* 虚拟机命令执行完毕 */
   AfxGetApp()->m_pMainWnd->MessageBox("虚拟机执行完毕!");

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -