📄 treetodemi.txt
字号:
// treetodemi.cpp: implementation of the Ctreetodemi class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "face.h"
#include "treetodemi.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Ctreetodemi::Ctreetodemi()
{
tmpOffset = 0; /*临时变量区的偏移*/
/* TM指令当前生成代码写入地址 */
emitLoc = 0 ;
/* 用于在函数emitSkip,emitBackup,emitRestore *
* 中作为当前最高生成代码写入地址,初始为0 */
highEmitLoc = 0;
}
Ctreetodemi::~Ctreetodemi()
{
}
/*******************实用函数******************/
/***********************************************************/
/* 函数名 FindAdd */
/* 功 能 计算基本类型变量、下标变量和域变量的绝对地址 */
/* 说 明 将绝对地址存入ac中 */
/***********************************************************/
void Ctreetodemi::FindAdd(TreeNode * t)
{
int Loc;
int varLevel;
fieldChain * fieldMem = NULL;
if(t!=NULL)
{
/*得到该变量在符号表中的地址*/
Loc = t->table[0]->attrIR.More.VarAttr.off;
/*记录该变量所在层*/
varLevel = t->table[0]->attrIR.More.VarAttr.level;
/*可能是下标类型或者域类型或者是基本变量类型,把地址取出送入ac*/
/*普通变量*/
if(t->child[0] == NULL)
{
emitRM("LDC",ac,Loc,0," base type var relative address");
}
/*数组类型变量*/
else if(t->attr.ExpAttr.varkind==ArrayMembV)
{
/*将数组下标值送入ac中*/
cGen(t->child[0]);
/*数组下届存入ac1中*//*attr.ArrayAttr.low*/
emitRM("LDC",ac1,t->table[0]->attrIR.idtype->More.ArrayAttr.low,0,"array low bound");
/*要用ac减去数组下届*/
emitRO("SUB",ac,ac,ac1,"");
/*求出该数组变量的偏移*/
emitRM("LDA",ac,Loc,ac," array type var relative address");
}
/*记录类型变量*/
else if(t->attr.ExpAttr.varkind==FieldMembV)
{
/*处理域变量的偏移*/
fieldMem = t->table[0]->attrIR.idtype->More.body;
/*在域表中查找该域变量*/
while(fieldMem != NULL)
{
int result = strcmp(t->child[0]->name[0],fieldMem->id);
/*如果相等*/
if(result==FALSE)
break;
else
fieldMem = fieldMem->Next;
}
/*域变量为基本类型变量*/
if(t->child[0]->child[0]==NULL)
{
emitRM("LDC",ac,Loc,0,"");
emitRM("LDA",ac,fieldMem->off,ac,"field type var relative address");
/*此时ac中存放的是相对偏移*/
}
/*域变量是数组变量的情况*/
else
{
genExp(t->child[0]->child[0]);
emitRM("LDC",ac1,t->child[0]->attr.ArrayAttr.low,0,"array low");
/*数组下标减去下届*/
emitRO("SUB",ac,ac,ac1,"");
emitRM("LDA",ac,fieldMem->off,ac,"");
emitRM("LDA",ac,Loc,ac,"");
}/*ac中存储的是域变量的在当前AR的偏移*/
}
/*计算该变量的sp*/
findSp(varLevel);
/******找到sp*****************/
/* 计算绝对偏移 */
emitRO("ADD",ac,ac,ac1," var absolute off");
}
}
/***********************************************************/
/* 函数名 FindSp */
/* 功 能 找到该变量所在AR的sp */
/* 说 明 */
/***********************************************************/
void Ctreetodemi::findSp(int varlevel)
{
/*先求该变量层数在AR中的位置,其中varLevel表示变量所在层*/
emitRM("LDA",ac1,varlevel,displayOff," var process");
/*绝对地址*/
emitRO("ADD",ac1,ac1,sp," var sp relative address");
/*该变量所在AR的sp地址存在ac1中*/
emitRM("LD",ac1,0,ac1," var sp");
}
/****************************************************************/
/* 函数名 emitComment */
/* 功 能 注释生成函数 */
/* 说 明 该函数将函数参数c指定的注释内容写入代码文件code */
/****************************************************************/
void Ctreetodemi::emitComment( char * c )
/* 如果代码生成追踪标志TraceCode为TRUE,将注释写入目标代码文件code */
{
if (TraceCode)
{
fprintf(code,"* %s\n",c);
}
}
/********************************************************/
/* 函数名 emitRO */
/* 功 能 寄存器地址模式指令生成函数 */
/* 说 明 该函数产生一条只用寄存器操作数的TM指令 */
/* op 为操作码; */
/* r 为目标寄存器; */
/* s 第一源寄存器; */
/* t 第二源寄存器; */
/* c 为将写入代码文件code的注释内容 */
/********************************************************/
void Ctreetodemi::emitRO( char *op, int r, int s, int t, char *c)
{
/* 将TM指令格式化写入代码文件code,当前生成代码写入地址emitLoc加1 */
fprintf(code,"%3d: %5s %d,%d,%d ",emitLoc++,op,r,s,t);
/* 如果代码生成追踪标志TraceCode为TRUE,将注释c写入代码文件code */
if (TraceCode)
{
fprintf(code,"\t*%s",c);
}
/* 一条代码指令写完,加入代码行结束标志 */
fprintf(code,"\n");
/* 当前生成代码写入地址若超出最高生成代码写入地址 *
* 改变最高生成代码写入地址highEmitLoc为当前生成代码写入地址emitLoc */
if (highEmitLoc < emitLoc) highEmitLoc = emitLoc ;
}
/********************************************************/
/* 函数名 emitRM */
/* 功 能 变址地址模式指令生成函数 */
/* 说 明 该函数产生一条寄存器-内存操作数TM指令 */
/* op 操作码; */
/* r 目标寄存器; */
/* d 为偏移值; */
/* s 为基地址寄存器; */
/* c 为将写入代码文件code的注释内容 */
/********************************************************/
void Ctreetodemi::emitRM( char * op, int r, int d, int s, char *c)
{
/* 将TM指令格式化写入代码文件code,当前生成代码写入地址emitLoc加1 */
fprintf(code,"%3d: %5s %d,%d(%d) ",emitLoc++,op,r,d,s);
/* 如果代码生成追踪标志TraceCode为TRUE,将注释c写入代码文件code */
if (TraceCode)
{
fprintf(code,"\t*%s",c);
}
/* 写完一条代码指令,加入指令行结束标志 */
fprintf(code,"\n");
/* 若当前生成代码写入地址emitLoc超过最高生成代码写入地址highEmitLoc *
* 更新最高生成代码写入地址highEmitLoc */
if (highEmitLoc < emitLoc) highEmitLoc = emitLoc ;
}
/****************************************************/
/* 函数名 emitSkip */
/* 功 能 空过生成函数 */
/* 说 明 该函数空过howMany指定数量的写入代码位置, */
/* 返回当前生成代码写入地址 */
/****************************************************/
int Ctreetodemi::emitSkip( int howMany)
{
/* 当前生成代码写入地址emitLoc赋给变量i */
int i = emitLoc;
/* 新的当前生成代码写入地址emitLoc略过howMany指定数量的写入指令位置 */
emitLoc += howMany ;
/* 若当前生成代码写入地址emitLoc超过最高生成代码写入地址highEmitLoc *
* 更新最高生成代码写入地址highEmitLoc */
if (highEmitLoc < emitLoc) highEmitLoc = emitLoc ;
/* 函数返回旧的当前生成代码写入地址i */
return i;
}
/********************************************************/
/* 函数名 emitBackup */
/* 功 能 地址回退函数 */
/* 说 明 该函数退回到以前被空过的生成代码写入地址loc */
/********************************************************/
void Ctreetodemi::emitBackup( int loc)
{
/* 如果要退回的地址loc比当前最高地址highEmitLoc还高 *
* 报退回错误,将错误信息作为注释写入代码文件code */
if (loc > highEmitLoc) emitComment("BUG in emitBackup");
/* 更新当前生成代码写入地址emitLoc为函数参数loc,完成退回动作 */
emitLoc = loc ;
}
/********************************************************/
/* 函数名 emitRestore */
/* 功 能 地址恢复函数 */
/* 说 明 该函数将当前生成代码写入地址emitLoc恢复为 */
/* 当前未写入指令的最高地址highEmitLoc */
/********************************************************/
void Ctreetodemi::emitRestore(void)
{ emitLoc = highEmitLoc;}
/************************************************/
/* 函数名 emitRM_Abs */
/* 功 能 地址转换函数 */
/* 说 明 该函数在产生一条寄存器-内存TM指令时, */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -