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

📄 treetodemi.txt

📁 SNL语言的编译器
💻 TXT
📖 第 1 页 / 共 4 页
字号:
				emitRM("ST",ac2,0,ac1," var read : store value");
			}
			break;

		/* 处理write语句类型 */
		case WriteK:

			p0 = t->child[0];
			cGen(p0);             /*处理write语句部分的表达式部分*/

			emitRO("OUT",ac,0,0,"write ac");
			break;

		/* 处理过程调用语句 */
		case CallK:
			
		    p0 = t->child[0];    /*过程名*/
			p1 = t->child[1];    /*过程的实参*/

			pp = p0;
			if(TraceCode)  emitComment("->procedure call");

			/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*
			 *@@@@@@           参数传递          @@@@@@@@*/
			
			/*curParam是指向该过程形参表的指针*/
			curParam = p0->table[0]->attrIR.More.ProcAttr.param;
			
			while ((curParam!=NULL)&&(p1!=NULL))/*p1是实参*/
			{
				
				/*该形参的偏移*/
				FormParam = curParam->entry->attrIR.More.VarAttr.off;
				
				/*形参是变参时有三种情况*/
				if(curParam->entry->attrIR.More.VarAttr.access==indir)
				//{
				    /*实参是非形参,第一种*/
					//if(!p1->table[0]->attrIR.More.VarAttr.isParam)
					//{
						/*计算该实参的绝对地址*/
					//	FindAdd(p1);
						/*ac中现在存放的是实参的绝对地址*/
			
						/*将实参地址送入currentAR的行参单元中*/

						/*参数传递*/
					//	emitRM("ST",ac,FormParam,top," store actParam");
					//}
					/*实参是形参,分为两种情况:dir,indir处理*/
					//else
					//{
						/*实参是值参*/
						if(p1->table[0]->attrIR.More.VarAttr.access==dir)
						{
							FindAdd(p1);
							/*ac中为实参的绝对地址*/
							/*将实参地址入currentAR的行参单元中*/
							
							/*参数传递*/
							emitRM("ST",ac,FormParam,top," store actParam");

						}
						/*实参是变参*/
						else
						{
							/*此时将实参的单元内容传送入currentAR的行参单元中*/
							FindAdd(p1);
							/*ac中为p1的绝对偏移*/

							/******ac中存的是实参单元地址******/
							emitRM("LD",ac,0,ac," ActParam value");
							/******ac中存的是实参单元内容******/
						
							/*参数传递*/
							emitRM("ST",ac,FormParam,top," formal and act link ");

						}
					//}
				//}
				/*形参是值参时有四种情况*/
				else
				{
					switch(p1->kind.exp)
					{
					/*第一种,数值或表达式,直接送值*/
					case OpK:
					case ConstK:
						/*ac中存有表达式的值*/
						genExp(p1);
						emitRM("ST",ac,FormParam,top," formal and act link");
						break;
					
					case VariK:
						/*该函数使ac中存储为实参的绝对地址*/
						FindAdd(p1);
						
						/*该形参的偏移*/
						FormParam = curParam->entry->attrIR.More.VarAttr.off;
						
						/*该实参是形参,不能是a.b或a[b]的形式*/
						//if(p1->table[0]->attrIR.More.VarAttr.isParam)
						//{
							/*第二种,值参,送值*/
							if(p1->table[0]->attrIR.More.VarAttr.access==dir)
							{
								/*以ac中的值作为绝对地址,找出其对应的存储单元,*
								 *取出其内容,作为实参                       */
								emitRM("LD",ac2,0,ac,"");
								/*ac2中存放的是该变量内容*/
								emitRM("ST",ac2,FormParam,top," Act and Formal link");
						
							}
							/*第三种,变参,取内容作为地址,再取内容送入*/
							else
							{
								/*以ac中的内容作为绝对地址*/
								emitRM("LD",ac2,0,ac,"");
								/*以ac2中的内容作为绝对地址*/
								emitRM("LD",ac2,0,ac2,"");
								/*以ac2中的内容作为实参*/
								emitRM("ST",ac2,FormParam,top," Act and Formal link");
							}
						//}
						/*该实参是普通变量*/
						//else
						//{	
							/*以ac中的值作为绝对地址*/
						//	emitRM("LD",ac2,0,ac,"");
							/*以ac2的内容作为实参*/
						//	emitRM("ST",ac2,FormParam,top," Act and Formal link");
						//}
						break;
					}
				}
				curParam = curParam->next;
				p1 = p1->sibling;
			
			}/*while循环结束*/
			
			
			/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
			/*@@@@@@@@@@     进入子程序入口   @@@@@@@@@@@@@*/
			
			/*保存当前sp*/
			emitRM("ST",sp,0,top," save old sp");

			/*保存寄存器0,1,2,4*/
			emitRM("ST",ac,3,top," save ac");
			emitRM("ST",ac1,4,top," save ac1");
			emitRM("ST",ac2,5,top," save ac2");
			emitRM("ST",displayOff,6,top," save nOff");
			/*新的displayOff的值*/
			emitRM("LDC",displayOff,pp->table[0]->attrIR.More.ProcAttr.nOff,0," new displayOff");

			/*返回值*/
			//emitRM("LDC",ac,0,0,"");
			//emitRM("ST",ac,7,top,"return value");
			
			/*保存返回地址*/
			savedLoc1 = emitSkip(2);
			

			/*过程层数*/
			emitRM("LDC",ac1,pp->table[0]->attrIR.More.ProcAttr.level,0," save procedure level");
			emitRM("ST",ac1,2,top,"");

			/*移display表*/
			for(ss = 0;ss<(pp->table[0]->attrIR.More.ProcAttr.level);ss++)
			{
				/*取原displayOff,存入ac2中*/
				emitRM("LD",ac2,6,top," fetch old display Off");
				/*ss要加上当前nOff才是对于sp的偏移*/
				emitRM("LDA",ac2,ss,ac2," old display item");
				/*ac2中为绝对地址*/
				emitRO("ADD",ac2,ac2,sp,"");
				/*取当前AR中display表的的第ss项,存入ac1中*/
				emitRM("LD",ac1,0,ac2," fetch display table item");
				
				/*当前AR的displayOff*/
				emitRM("LDA",ac2,ss,displayOff," current display item");
				/*ac2中为绝对地址*/
				emitRO("ADD",ac2,ac2,top,"");
				/*将ac1中的内容送入ac2所指地址中*/
				emitRM("ST",ac1,0,ac2," send display table item");
			}
			/*在display表中的最上层填写本层的sp*/
			/*ac2中存储的为display表最上层的相对off*/
			emitRM("LDA",ac2,pp->table[0]->attrIR.More.ProcAttr.level,displayOff," current sp in display");
			emitRO("ADD",ac2,top,ac2," absolute off");
			emitRM("ST",top,0,ac2," input value" );
			
			/*修改sp和top*/
			emitRM("LDA",sp,0,top," new sp value");
			emitRM("LDA",top,pp->table[0]->attrIR.More.ProcAttr.mOff,top," new top value");
			
		    /*回填返回地址*/
			currentLoc = emitSkip(0)+1;
			emitBackup(savedLoc1);
			emitRM("LDC",ac1,currentLoc,0," save return address");
			emitRM("ST",ac1,1,top,"");
			emitRestore();
			
            /*转向子程序*/
			emitRM("LDC",pc,pp->table[0]->attrIR.More.ProcAttr.procEntry,0," procedure entry ");

			/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
			/*@@@@@@@@@@     子程序出口处     @@@@@@@@@@@@@*/
			
			/*恢复寄存器值*/
			emitRM("LD",ac,3,sp," resume ac");
			emitRM("LD",ac1,4,sp," resume ac1");
			emitRM("LD",ac2,5,sp," resume ac2");
			emitRM("LD",displayOff,6,sp," resume nOff");

			/*恢复sp和top值*/
			emitRM("LDA",top,0,sp," resume top");
			emitRM("LD",sp,0,sp," resume sp");

			/*读函数值入ac中*/
			//emitRM("LD",ac,7,top," procedure return value");
			
			break;
			
		/*处理return返回语句,主程序中没有return语句*/
		case ReturnK:
			/*REG[sp]+1地址中存放的是函数的返回地址*/
			//emitRM("LD",ac2,1,sp,"");
			//emitRM("LDA",pc,0,ac2," return address");
			break;
		default:
			break;
	}
}


/************************************************/
/* 函数名 genExp								*/
/* 功  能 表达式类型语法树节点代码生成函数		*/
/* 说  明 该函数根据表达式类型分类处理,			*/
/*		  生成目标代码和注释					*/
/************************************************/
void Ctreetodemi::genExp(TreeNode * t)

{ 
  /* 语法树节点各个子节点 */
  TreeNode * p1, * p2;

  /* 对语法树节点的表达式类型细分处理 */
  switch (t->kind.exp) 
  {

	/* 语法树节点tree为ConstK表达式类型 */
    case ConstK :

	  /* 如果代码生成追踪标志TraceCode为TRUE,写入注释,常数部分开始 */
      if (TraceCode) emitComment("-> Const") ;

      /* 生成载入常量指令,载入常量到累加器ac */
	  emitRM("LDC",ac,t->attr.ExpAttr.val,0,"load const");
	  
	  /* 如果代码生成追踪标志TraceCode为TRUE,写入注释,常数部分结束 */
      if (TraceCode)  emitComment("<- Const") ;
      break; 

	 
	/* 语法树节点tree为IdK表达式类型 */
    case VariK :
	  /* 如果代码生成追踪标志TraceCode为TRUE,写入注释,标注标识符开始 */
      if (TraceCode) emitComment("-> Id") ;
	  
	  FindAdd(t);
	  /*其中ac返回的是基本类型变量、域变量或下标变量的绝对偏移*/
	  
	  if(t->table[0]->attrIR.More.VarAttr.access==indir)
	  {
	 	/*地址*/
		/*取值,作为地址*/
		emitRM("LD",ac1,0,ac,"indir load id value");
		/*ac1中为地址值*/
		
		/*按地址取单元内容*/
		emitRM("LD",ac,0,ac1,"");
	  }
	  else
	  {
		/*值*/

⌨️ 快捷键说明

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