📄 midcode.cpp
字号:
ArgRecord *sizeArg= ARGValue(size);
/*产生三个临时变量*/
ArgRecord *temp1= NewTemp(dir);
ArgRecord *temp2= NewTemp(dir);
/*注:表示复杂变量的临时变量属于间接访问*/
ArgRecord *temp3= NewTemp(indir);
/*生成中间代码*/
GenCode(SUB, Earg, lowArg ,temp1);
GenCode(MULT,temp1,sizeArg,temp2);
GenCode(AADD,V1arg,temp2, temp3);
return (temp3);
}
/****************************************************/
/* 函数名 GenArray */
/* 功 能 域变量处理函数 */
/* 说 明 由函数GenVar调用 */
/****************************************************/
ArgRecord *GenField(ArgRecord *V1arg,TreeNode *t ,fieldChain *head )
{
ArgRecord *FieldV = NULL;
/*t1指向当前域成员*/
TreeNode *t1 = t->child[0];
fieldChain *Entry2 = NULL ;
FindField(t1->name[0],head ,&Entry2);
/*域名在域表中的偏移*/
int off = Entry2->off;
ArgRecord *offArg = ARGValue(off);
/*注:表示复杂变量的临时变量属于间接访问*/
ArgRecord *temp1 = NewTemp( indir);
GenCode(AADD , V1arg, offArg , temp1);
/*域是数组变量*/
if (t1->attr.ExpAttr.varkind==ArrayMembV)
{ int low = Entry2->UnitType->More.ArrayAttr.low;
int size= Entry2->UnitType->More.ArrayAttr.elemTy->size;
FieldV = GenArray(temp1, t1,low,size );
}
else /*域是标识符变量*/
FieldV = temp1;
return(FieldV);
}
/****************************************************/
/* 函数名 GenExpr */
/* 功 能 表达式处理函数 */
/* 说 明 */
/****************************************************/
ArgRecord *GenExpr(TreeNode *t)
{
ArgRecord *arg = NULL;
ArgRecord *Larg = NULL;
ArgRecord *Rarg = NULL;
ArgRecord *temp = NULL;
switch( t->kind.exp)
{ case VariK:
arg = GenVar(t);
break ;
case ConstK:
/*得到值的ARG结构*/
arg = ARGValue(t->attr.ExpAttr.val);
break;
case OpK:
/*处理左部和右部*/
Larg = GenExpr(t->child[0]);
Rarg = GenExpr(t->child[1]);
/*,根据操作符类别,得到中间代码的类别*/
CodeKind op;
switch(t->attr.ExpAttr.op)
{ case LT: op = LTC ; break;
case EQ: op = EQC ; break;
case PLUS: op = ADD ; break;
case MINUS: op = SUB ; break;
case TIMES: op = MULT; break;
case OVER : op = DIV ; break;
default : break;
}
/*产生一个新的临时变量*/
temp = NewTemp(dir);
/*生成中间代码*/
GenCode (op, Larg ,Rarg , temp );
arg = temp ;
break;
default : break;
}
return (arg);
}
/****************************************************/
/* 函数名 GenCall */
/* 功 能 过程调用处理函数 */
/* 说 明 分别调用表达式处理函数处理各个实参,并 */
/* 生成相应的形实参结合中间代码;从符号表中 */
/* 过程标识符属性中,查到入口标号,产生过程 */
/* 调用中间代码 */
/****************************************************/
void GenCallS(TreeNode *t )
{
/*取得过程标志符在符号表中的地址*/
SymbTable *Entry = t->child[0]->table[0];
ParamTable *param = Entry->attrIR.More.ProcAttr.param;
/*调用表达式处理函数处理各个实参,
并生成相应的形实参结合中间代码*/
TreeNode *t1 = t->child[1];
ArgRecord *Earg = NULL;
while (t1!=NULL)
{ Earg = GenExpr( t1);
/*记录参数的偏移*/
int paramOff = param->entry->attrIR.More.VarAttr.off;
ArgRecord *OffArg = ARGValue(paramOff);
/*形实参结合中间代码*/
if (param->entry->attrIR.More.VarAttr.access==dir)
/*值参结合中间代码*/
GenCode(VALACT, Earg ,OffArg,NULL);
else /*变参结合中间代码*/
GenCode(VARACT, Earg ,OffArg,NULL);
t1 = t1->sibling;
param = param->next;
}
/*过程入口标号及其ARG结构*/
int label = Entry->attrIR.More.ProcAttr.codeEntry;
ArgRecord *labelarg = ARGLabel(label);
/*过程的display表的偏移量*/
int Noff = Entry->attrIR.More.ProcAttr.nOff;
ArgRecord *Noffarg = ARGValue(Noff);
/*生成过程调用中间代码*/
GenCode (CALL,labelarg, NULL,Noffarg);
}
/****************************************************/
/* 函数名 GenReadS */
/* 功 能 读语句处理函数 */
/* 说 明 得到读入变量的ARG结构,生成读语句中间代码*/
/****************************************************/
void GenReadS(TreeNode *t )
{
SymbTable *Entry = t->table[0];
ArgRecord *Varg = ARGAddr(t->name[0],
Entry->attrIR.More.VarAttr.level,
Entry->attrIR.More.VarAttr.off,
Entry->attrIR.More.VarAttr.access);
/*生成读语句中间代码*/
GenCode(READC,Varg,NULL,NULL);
}
/****************************************************/
/* 函数名 GenWrite */
/* 功 能 写语句处理函数 */
/* 说 明 调用表达式的中间代码生成函数,并产生写 */
/* 语句的中间代码 */
/****************************************************/
void GenWriteS(TreeNode *t)
{ /*调用表达式的处理*/
ArgRecord *Earg = GenExpr(t->child[0]);
/*生成写语句中间代码*/
GenCode(WRITEC,Earg ,NULL ,NULL);
}
/****************************************************/
/* 函数名 GenIfs */
/* 功 能 条件语句处理函数 */
/* 说 明 */
/****************************************************/
void GenIfS(TreeNode *t)
{
/*生成else部分入口标号,及其ARG结构*/
int elseL = NewLabel( );
ArgRecord *ElseLarg =ARGLabel(elseL );
/*生成if语句出口标号,及其ARG结构*/
int outL = NewLabel( );
ArgRecord *OutLarg = ARGLabel(outL);
/*条件表达式的中间代码生成*/
ArgRecord *Earg = GenExpr(t->child[0]);
/*若表达式为假,跳转至else入口标号*/
GenCode(JUMP0, Earg, ElseLarg ,NULL);
/*then部分中间代码生成*/
GenBody(t->child[1]);
/*跳到if出口*/
GenCode(JUMP, OutLarg ,NULL ,NULL );
/*else部分入口标号声明*/
GenCode(LABEL,ElseLarg,NULL,NULL);
/*else部分中间代码生成*/
GenBody(t->child[2]);
/*if语句出口标号声明*/
GenCode(LABEL,OutLarg,NULL,NULL);
}
/****************************************************/
/* 函数名 GenWhileS */
/* 功 能 循环语句处理函数 */
/* 说 明 将循环入口和出口用不同的中间代码标志,是 */
/* 为了循环不变式外提的需要 */
/****************************************************/
void GenWhileS(TreeNode *t )
{
/*生成while语句入口标号,及其ARG结构*/
int inL = NewLabel() ;
ArgRecord *InLarg = ARGLabel(inL);
/*生成while语句出口标号,及其ARG结构*/
int outL = NewLabel( );
ArgRecord *OutLarg = ARGLabel(outL);
/*while语句入口标号声明*/
GenCode(WHILESTART ,InLarg,NULL,NULL);
/*条件表达式的中间代码生成*/
ArgRecord *Earg = GenExpr(t->child[0]);
/*若表达式为假,跳转至while语句出口*/
GenCode(JUMP0, Earg, OutLarg ,NULL);
/*循环体中间代码生成*/
GenBody(t->child[1]);
/*跳到while入口*/
GenCode(JUMP, InLarg ,NULL ,NULL );
/*while出口标号声明*/
GenCode(ENDWHILE,OutLarg, NULL,NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -