📄 treetodemi.txt
字号:
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 + -