IR 代码中 符号代码( label )沿用不变
int 调用 T_Const(int i )
Tree 模块:
1. patchList:真值/假值 回填表
这里是 patchList 的生成, 至于具体怎么回填后面才会讲
struct patchList_ {
Temp_label *head;
patchList tail
};
// 生成 stm
stm = T_Cjump(T_ge, unEx(left), unEx(right), NULL, NULL);
or
stm = T_Cjump(T_eq, callEq, T_Const(1), NULL, NULL);
// 通过 stm 生成 真/假值 回填表
patchList tlist;
patchList rList;
tlist = PatchList(&stm->u.CJUMP.true, NULL);
flist = PatchList(&stm->u.CJUMP.false, NULL);
// 最后通过 stm, 真/假值 回填表 生成 Tr_Exp
Tr_Exp e = Tr_Cx(tlist, flist, stm);
Frame 模块:
1. 片段相关的代码
都在 Frame 模块中, translate 调用 Frame 模块获取
struct F_frag ;
struct F_fragList ;
F_frag F_StringFrag(Temp_label, string); // 字符串片段
F_frag F_ProcFrag(T_stm, F_frame); // 流程片段: 栈帧+函数体
static F_frag* extendFragList(); // 扫描到新的元素,扩容并返回全局片段表
F_fragList F_getFragList(void); // 获取全局片段表
*2. static F_frag extendFragList(); **
扫描到新的元素,扩容并返回全局片段表
// 重置全局片段表, 返回 head
static F_frag* extendFragList(){
// 创建指针变量
if (fragList == NULL){
fragList = (F_fragList*) checked_malloc(sizeof(F_fragList*));
}
// 指针变量赋值为一个 fragList 对象
*fragList = (F_fragList) checked_malloc(sizeof (struct F_fragList_));
if (fragList_head == NULL){
fragList_head = *fragList;
}
// 把全局片段表的 head 拿出来返回,然后全局片段片更新为 NULL
F_frag *curf = &((*fragList)->head);
// 除了 head 外剩于的片段表设为 NULL
fragList = &((*fragList)->tail);
*fragList = NULL;
return curf;
}
3. 字符串片段
void F_String(Temp_label label, string str){
// 先获取当前片段
F_frag *currentFrag = extendFragList();
// 再更新片段
*currentFrag = F_StringFrag(label, str);
}
4. F_Exp(F_access acc, T_exp framePtr);
在栈帧 framePtr 中 找到 access 对应的地址: frame 地址 + offset 地址
// 生成 access 的*访问地址*
T_exp F_Exp(F_access acc, T_exp framePtr){
// 判断目标 access 在栈帧中 / 寄存器中
if (acc->kind == inFrame){
// 地址 = 栈帧地址 + offset(位移)
return T_Mem(T_Binop(T_plus, framePtr, T_Const(acc->u.offset)));
}else{
// 寄存器
return T_Temp(acc->u.reg);
}
}
Translate 模块
1. 沿静态链往上找变量
Tr_exp Tr_simpleVar(Tr_access acc, Tr_level level){
debug("Tr_simpleVar");
T_exp texp;
F_access access = acc->access;
// 判断当前 level 是否和 变量访问的level (acc->level) 一致,一致就直接用, 不一致就沿着***静态连*** 找
if (level != acc->level){
// 沿着静态链往上找对应的 level
texp = F_Exp(F_staticLink(), T_Temp(F_FP()));
level = level->parent;
while (level != acc->level){
// 静态链是一个指向其**外部函数**栈帧的指针链
// ... todo ...
texp = F_Exp(F_staticLink(),texp);
// level 没有找到,再往上找父level
level = level->parent;
}
texp = F_Exp(acc->access,texp);
}else{
texp = F_Exp(acc->access, T_Temp(F_FP()))
}
}