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

📄 tm.cpp

📁 上课时老师用过的SNL编译器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// tm.cpp: implementation of the Ctm class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "face.h"
#include "tm.h"
#include "indialog.h"
#include "inNum.h"
#include "result.h"
#include "comhelp.h"

#include "stdio.h"

#include "MainFrm.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Ctm::Ctm()
{

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

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

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

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

}
Ctm::~Ctm()
{

}


/****************************************************/
/* 函数名 opClass									*/
/* 功  能 指令寻址模式分类函数						*/
/* 说  明 该函数对给定的指令操作码枚举值c进行分类	*/
/*        返回指令所属寻址模式						*/
/****************************************************/
int Ctm::opClass( int c )

{ 
  /* 如果枚举值c小于opRRLim,则指令为寄存器寻址模式指令类型 */
  if      ( c <= opRRLim) return ( opclRR );

  /* 如果枚举值c小于opRMLim,则指令为寄存器-内存寻址模式指令类型 */
  else if ( c <= opRMLim) return ( opclRM );

  /* 为寄存器-立即数寻址模式指令类型 */
  else                    return ( opclRA );

} 

/********************************************************/
/* 函数名 writeInstruction								*/
/* 功  能 指令输出函数									*/
/* 说  明 该函数将指令存储区中指令以指定格式输出到屏幕	*/
/********************************************************/
void Ctm::writeInstruction ( int loc )

{  
  /* loc为所要输出的指令在指令存储区中地址,输出到屏幕 */
  //fprintf(listing, "%5d: ", loc) ;
	str1.Format( "%5d: ", loc) ;
	str2+=str1;
  /* 输出指令地址loc在0-1023有效的指令存储区地址范围之内 */
  if ( (loc >= 0) && (loc < IADDR_SIZE) )

  { 
    /* 输出地址为loc上的指令操作码值iMem[loc].iop和第一操作数iMem[loc].iarg1 */
	//fprintf(listing,"%6s%3d,", opCodeTab[iMem[loc].iop], iMem[loc].iarg1);
	str1.Format("%6s%3d,", opCodeTab[iMem[loc].iop], iMem[loc].iarg1);
	str2+=str1;

	/* 根据指令的寻址模式分类处理 */
    switch ( opClass(iMem[loc].iop) )

    { 
      /* 输出指令为寄存器寻址模式指令,以给定形式输出操作数2,操作数3 */
	  case opclRR: 
		  //fprintf(listing,"%1d,%1d", iMem[loc].iarg2, iMem[loc].iarg3);
          str1.Format(  "%1d,%1d", iMem[loc].iarg2, iMem[loc].iarg3);
		  str2+= str1;

		  break;		

      /* 输出指令为寄存器-立即数寻址模式指令,和寄存器-内存寻址模式指令	*
	   * 以给定形式输出操作数2,操作数3									*/
      case opclRM: 
      case opclRA:
		  //fprintf(listing,"%3d(%1d)", iMem[loc].iarg2, iMem[loc].iarg3);
          str1.Format("%3d(%1d)", iMem[loc].iarg2, iMem[loc].iarg3);  
		  str2+=str1;
		  break;	
    }
   	/* 向屏幕输出换行符 */
	//fprintf(listing,"\r\n") ;
	str2+="\r\n";
  }
} /* writeInstruction */

/****************************************************/
/* 函数名 getCh										*/
/* 功  能 字符获取函数								*/
/* 说  明 如果当前行中字符未读完,则函数返回当前字符	*/
/*		  否则,函数返回空格字符						*/
/****************************************************/
void Ctm::getCh ()

{ 
  /* 在当前代码行in_Line中,当前字符列数inCol未超过代码行实际长度lineLen *
   * 取得当前行中当前位置的字符,送入ch									*/
  if (++inCol < lineLen)
  ch = in_Line[inCol] ;

  /* 如果inCol超出当前代码行长度范围,则ch赋为空格 */
  else ch = ' ' ;

} /* getCh */



/********************************************************/
/* 函数名 nonBlank										*/
/* 功  能 非空字符获取函数								*/
/* 说  明 如果成功从当前行中取得非空字符,函数返回TRUE	*/
/*		  否则,函数返回FALSE							*/
/********************************************************/
int Ctm::nonBlank ()

{ 
  /* 在当前代码行in_Line中,当前字符位置inCol中为空格字符	*  
   * 在当前代码行in_Line中,当前字符位置inCol下移,略过空格	*/
  while ((inCol < lineLen)
         && (in_Line[inCol] == ' ') )
		 inCol++ ;

  /* 在当前代码行in_Line中,遇到非空字符 */
  if (inCol < lineLen)

  { 
    /* 取当前字符位置inCol中的字符送入ch,		*
	 * 函数返回TRUE(已定义为1),ch中得到非空字符	*/
	ch = in_Line[inCol] ;
    return TRUE ; }

  /* 当前代码行已经读完,将当前字符ch 赋为空格,	*
   * 函数返回FALSE(已定义为0),ch中为空格字符	*/
  else
  { ch = ' ' ;
    return FALSE ; }
} /* nonBlank */


/****************************************************************/
/* 函数名 getNum												*/
/* 功  能 数值获取函数											*/
/* 说  明 将代码行中连续出现的有加减运算的数term合并计数,		*/
/*        所的数值送入为num.如果成功得到数值,则函数返回TRUE;	*/
/*        否则,函数返回FALSE									*/
/****************************************************************/
int Ctm::getNum ()

{ int sign;				/* 符号因子 */

  int term;				/* 用于记录当前录入的局部数值 */

  int temp = FALSE;		/* 记录函数返回值,初始为假 */

  num = 0 ;				/* 用于记录所有加减运算后的最终数值结果 */

  do
  { sign = 1;			/* 符号因子初始为1 */

    /* 调用函数nonBlank()略过当前位置的空格后,			*
     * 所得到的当前非空字符ch为+或-.(+/-的连续出现处理)	*/
    while ( nonBlank() && ((ch == '+') || (ch == '-')) )

    { temp = FALSE ;

	  /* 当前字符ch为"-"时,符号因子sign设为-1 */
	  if (ch == '-')  sign = - sign ;

	  /* 取当前代码行中下一字符到当前字符ch中 */
      getCh();
    }

    term = 0 ;		/* 当前录入的局部数值初始为0 */

    nonBlank();		/* 略过当前位置上的空格 */

	/* 当前字符ch为数字,局部数值的循环处理 */
    while (isdigit(ch))				

    { temp = TRUE ;		/* 函数返回值设为TRUE,成功得到数字 */

	  /* 将字符序列转化为数值形式,进行进位累加 */
      term = term * 10 + ( ch - '0' ) ;

      getCh();			/* 取当前代码行中下一字符到当前字符ch中 */

    }
	/* 将局部数值带符号累加,得到最终数值num */
    num = num + (term * sign) ;

  } while ( (nonBlank()) && ((ch == '+') || (ch == '-')) ) ;
  return temp;
} /* getNum */


/****************************************************/
/* 函数名 getWord									*/
/* 功  能 单词获取函数								*/
/* 说  明 函数从当前代码行中获取单词.如果得到字符,	*/
/*		  则函数返回TRUE;否则,函数返回FALSE			*/
/****************************************************/
int Ctm::getWord ()

{ 
	
  int temp = FALSE;			/* 函数返回值初始为FALSE */

  int length = 0;			/* 单词长度初始为0 */

  /* 在当前代码行中成功获取非空字符ch */
  if (nonBlank ())

  {
    /* 当前非空字符ch为字母或数字 */
	while (isalnum(ch))

    {
      /* 当前单词word未超过规定字长WORDSIZE-1(为单词结束字符留一空位)	*
	   * 将当前字符ch读入到单词末尾										*/
	  if (length < WORDSIZE-1) word [length++] =  ch ;

      getCh() ;			/* 取当前代码行中下一字符 */
    }

	/* 给当前单词word加入结束字符 */
    word[length] = '\0';

	/* 设置函数返回值,当读入字word非空的时候为TRUE */
    temp = (length != 0);

  }
  return temp;
} /* getWord */


/************************************************************/
/* 函数名 skipCh											*/
/* 功  能 字符空过函数										*/
/* 说  明 如果当前位置上字符为函数指定的字符,则空过该字符,	*/
/*		  函数返回TRUE;否则函数返回FALSE					*/
/************************************************************/
int Ctm::skipCh ( char c  )

{ int temp = FALSE;

  /* 当前位置上字符为函数指定字符c */
  if ( nonBlank() && (ch == c) )

  { getCh();		/* 空过当前字符c,取下一字符 */

    temp = TRUE;	/* 空过指定字符c,函数返回TRUE */
  }
  return temp;
} /* skipCh */


/************************************/
/* 函数名 atEOL						*/
/* 功  能 行结束判断函数			*/
/* 说  明 当前行是否结束的判断函数	*/
/************************************/	
int Ctm::atEOL()

{ return ( ! nonBlank ());	/* 如果当前行中没有非空字符,则函数返回TRUE */
} /* atEOL */


/****************************************************/
/* 函数名 error										*/
/* 功  能 错误处理函数								*/
/* 说  明 函数输出错误行号,指令地址标号和错误信息	*/
/****************************************************/
int Ctm::error( char * msg, int lineNo, int instNo)

{ 

  AfxGetApp()->m_pMainWnd->MessageBox(msg);

  /* 输出错误出现位置行号lineNo */
  //fprintf(listing,"Line %d",lineNo);
  str1.Format("Line %d",lineNo);
  str2+=str1;

  /* 输出错误指令地址标号instNo */
  if (instNo >= 0) 
	  //fprintf(listing," (Instruction %d)",instNo);
      str1.Format(" (Instruction %d)",instNo);
	  str2+= str1;

  /* 输出错误信息msg */
	// fprintf(listing,"   %s\r\n",msg);
   str1.Format("   %s\r\n",msg);
   str2+=str1;

  return FALSE;
} /* error */


/********************************************************/
/* 函数名 readInstructions								*/
/* 功  能 指令文件读入函数								*/
/* 说  明 将指令文件中的指令逐条读入到指令存储区iMem	*/
/********************************************************/
int Ctm::readInstructions ()

{ 
  OPCODE op;				/* 当前指令操作码 */

  int arg1, arg2, arg3;		/* 当前指令操作数 */

  int loc, regNo, lineNo;

  /* 将8个寄存器内容初始化为0 */
  for (regNo = 0 ; regNo < NO_REGS ; regNo++)
      reg[regNo] = 0 ;						

  /* dMem为数据存储区,0地址单元dMem[0]的值赋为数据存储区高端地址1023	*
   * 此数值将在目标程序运行时由程序的先驱指令读入到mp寄存器中			*/
  dMem[0] = DADDR_SIZE - 1 ;				

  /* 将数据存储数区内除0地址单元外的各单元初始化为0 */
  for (loc = 1 ; loc < DADDR_SIZE ; loc++)
      dMem[loc] = 0 ;

  /* 将指令存储区中各单元初始化为指令;HALT 0,0,0 */
  for (loc = 0 ; loc < IADDR_SIZE ; loc++)
  { iMem[loc].iop = opHALT ;

⌨️ 快捷键说明

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