📄 tacsupport.cpp
字号:
__2tmpVar(expr);
__valueNOconst(expr, var_type_int);
__2tmpVar(expr2);
__valueNOconst(expr2, var_type_int);
int element_var_type = SymbolListType[expr.var_type].ret_type_id;
int unit_size = __get_sizeof(element_var_type);
TACInstructionListJoin(expr.ins, expr2.ins, expr.ins);
int last = 0;
int now = 0;
while (unit_size != 0)
{
if (unit_size & 1)
{
if (now != last)
{
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_SHL , expr2.res_oprd, expr2.res_oprd, TACNULLOperand);
expr.ins.end->c.oper_type = TAC_oper_type_constint;
expr.ins.end->c.data.cint = (now - last) % 8;
}
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_ADD, expr.res_oprd, expr.res_oprd, expr2.res_oprd);
last = now;
}
unit_size /= 2;
now ++;
}
__varADDptr(expr);
// printf ("After taking %s\n", expr.var_type >= 0 ? IDHash_int2ID(expr.var_type).c_str() : "basic");
// printf ("%d\n", expr.var_type);
}
void TACMakePush (TExpr& expr, TInstructionList& ins)
{
if (__get_sizeof(expr.var_type) == 1)
{
__cond2value(expr);
__valueNOconst(expr, var_type_int);
__valueNOptr(expr);
TACInstructionListJoin(ins, expr.ins, ins);
TACInstructionListBackAddBlank(ins); // Push num
TACInstructionCreate_3var(*ins.end, TAC_OP_PUSH, var_name_NULL, var_name_NULL, var_name_NULL);
ins.end->a = expr.res_oprd;
}
else
{
// printf("OK\n");
int size = __get_sizeof(expr.var_type);
__varADDref(expr);
TACInstructionListJoin(ins, expr.ins, ins);
int v1 = TACNewTempVar(var_type_int);
int v2 = TACNewTempVar(var_type_int);
int v3 = TACNewTempVar(var_type_int);
int L1 = TACNewLabel();
int L2 = TACNewLabel();
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_LET, v1, var_name_NULL, var_name_NULL);
ins.end->b.oper_type = TAC_oper_type_constint;
ins.end->b.data.cint = size;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_ADD, v2, var_name_NULL, v1);
ins.end->b = expr.res_oprd;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_LABEL, L1, var_name_NULL, var_name_NULL);
ins.end->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_JE, v1, var_name_NULL, L2);
ins.end->b.oper_type = TAC_oper_type_constint;
ins.end->b.data.cint = 0;
ins.end->c.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_SUB, v1, v1, var_name_NULL);
ins.end->c.oper_type = TAC_oper_type_constint;
ins.end->c.data.cint = 1;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_SUB, v2, v2, var_name_NULL);
ins.end->c.oper_type = TAC_oper_type_constint;
ins.end->c.data.cint = 1;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_LOAD, v3, v2, var_name_NULL);
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_PUSH, v3, var_name_NULL, var_name_NULL);
ins.end->b.oper_type = TAC_oper_type_constint;
ins.end->b.data.cint = size;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_JMP, L1, var_name_NULL, var_name_NULL);
ins.end->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_LABEL, L2, var_name_NULL, var_name_NULL);
ins.end->a.oper_type = TAC_oper_type_label;
}
}
void TACMakeCallPush(int func_type, list <TExpr>& exprs, TInstructionList& ins)
{
/* list <TSymbolListVariableEntry> :: iterator p_arg = SymbolListType[func_type].field_var.begin();
for (list <TExpr> :: iterator p = exprs.begin(); p != exprs.end(); p++, p_arg++)
{
TACInstructionListJoin(ins, p->ins, ins);
}*/
for (list <TExpr> :: reverse_iterator rp = exprs.rbegin(); rp != exprs.rend(); rp++)
{
TACMakePush(*rp, ins);
}
}
void TACMakeCall(int id, list <TExpr>& exprs, TExpr& expr)
{
expr.ins.clear();
TACMakeCallPush(SymbolListFunction[id].func_type, exprs, expr.ins);
int target_var_type = SymbolListType[SymbolListFunction[id].func_type].ret_type_id;
int tmpvar_name = TACNewTempVar(target_var_type);
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_RCALL, tmpvar_name, id, var_name_NULL);
expr.res_oprd = expr.ins.end->a;
expr.cond = 0;
expr.var_type = target_var_type;
int totalSize = 0;
for (list <TSymbolListVariableEntry> :: iterator p = SymbolListType[SymbolListFunction[id].func_type].field_var.begin();
p != SymbolListType[SymbolListFunction[id].func_type].field_var.end(); p++)
{
totalSize += __get_sizeof(p->var_type);
}
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_POP, var_name_NULL, var_name_NULL, var_name_NULL);
expr.ins.end->a.oper_type = TAC_oper_type_constint;
expr.ins.end->a.data.cint = totalSize;
}
void TACMakeICall(TExpr& expr1, list <TExpr>& exprs, TExpr& expr)
{
expr.ins.clear();
__valueNOptr(expr1);
expr.ptr = 0;
TACInstructionListJoin(expr.ins, expr1.ins, expr.ins);
list <TSymbolListVariableEntry> :: iterator p = SymbolListType[expr1.var_type].field_var.begin();
for (list <TExpr> :: iterator q = exprs.begin(); q != exprs.end(); q ++, p ++)
{
// printf("%d (%d), ", q->ptr, q->var_type);
if (p->var_type >= 0 && q->var_type >= 0 && SymbolListType[p->var_type].type_number == type_number_pointer && SymbolListType[q->var_type].type_number == type_number_array)
{
// printf("ok ");
__varADDref(*q);
}
}
// printf("\n");
TACMakeCallPush(expr1.var_type, exprs, expr.ins);
int target_var_type = SymbolListType[expr1.var_type].ret_type_id;
int tmpvar_name = TACNewTempVar(target_var_type == var_type_void ? var_type_int : target_var_type);
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_RICALL, tmpvar_name, var_name_NULL, var_name_NULL);
expr.ins.end->b = expr1.res_oprd;
expr.res_oprd = expr.ins.end->a;
expr.cond = 0;
expr.var_type = target_var_type;
int totalSize = 0;
for (list <TSymbolListVariableEntry> :: iterator p = SymbolListType[expr1.var_type].field_var.begin();
p != SymbolListType[expr1.var_type].field_var.end(); p++)
{
totalSize += __get_sizeof(p->var_type);
}
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_POP, var_name_NULL, var_name_NULL, var_name_NULL);
expr.ins.end->a.oper_type = TAC_oper_type_constint;
expr.ins.end->a.data.cint = totalSize;
}
void TACMakeMEMCPY(TInstructionList& ins, TExpr& expr1, TExpr& expr2, int var_size)
{
int v1 = TACNewTempVar(var_type_int);
int v2 = TACNewTempVar(var_type_int);
int v3 = TACNewTempVar(var_type_int);
int v4 = TACNewTempVar(var_type_int);
int L1 = TACNewLabel();
int L2 = TACNewLabel();
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_LET, v1, var_name_NULL, var_name_NULL);
ins.end->b.oper_type = TAC_oper_type_constint;
ins.end->b.data.cint = 0;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_LET, v2, var_name_NULL, var_name_NULL);
ins.end->b = expr1.res_oprd;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_LET, v3, var_name_NULL, var_name_NULL);
ins.end->b = expr2.res_oprd;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_LABEL, L1, var_name_NULL, var_name_NULL);
ins.end->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_JGE, v1, var_name_NULL, L2);
ins.end->b.oper_type = TAC_oper_type_constint;
ins.end->b.data.cint = var_size;
ins.end->c.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_LOAD, v4, v3, var_name_NULL);
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_STORE, v2, v4, var_name_NULL);
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_ADD, v1, v1, var_name_NULL);
ins.end->c.oper_type = TAC_oper_type_constint;
ins.end->c.data.cint = 1;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_ADD, v2, v2, var_name_NULL);
ins.end->c.oper_type = TAC_oper_type_constint;
ins.end->c.data.cint = 1;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_ADD, v3, v3, var_name_NULL);
ins.end->c.oper_type = TAC_oper_type_constint;
ins.end->c.data.cint = 1;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_JMP, L1, var_name_NULL, var_name_NULL);
ins.end->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_LABEL, L2, var_name_NULL, var_name_NULL);
ins.end->a.oper_type = TAC_oper_type_label;
}
void TACMakeLET(TExpr& expr1, TExpr& expr2, TExpr& expr)
{
__cond2value(expr2);
if (SymbolListType[expr2.var_type].type_number == type_number_array || SymbolListType[expr2.var_type].type_number == type_number_struct)
{
__varADDref(expr2);
}
if (SymbolListType[expr1.var_type].type_number == type_number_array ||
SymbolListType[expr1.var_type].type_number == type_number_struct)
{
int old_type = expr1.var_type;
int size = SymbolListType[expr1.var_type].total_size;
__varADDref(expr1);
TACInstructionListJoin(expr1.ins, expr2.ins, expr.ins);
TACMakeMEMCPY(expr.ins, expr1, expr2, size);
expr.res_oprd = expr1.res_oprd;
expr.var_type = expr1.var_type;
expr.ptr = expr1.ptr;
// printf ("vartype now : %s <--- %s ptr %d\n", IDHash_int2ID(old_type).c_str(), IDHash_int2ID(expr.var_type).c_str(), expr.ptr);
__varADDptr(expr);
// printf ("vartype now : %s <--- %d ptr %d\n", IDHash_int2ID(old_type).c_str(), expr.var_type, expr.ptr);
expr.var_type = old_type;
return;
}
if (expr1.ptr)
{
__valueNOptr(expr2);
__valueNOconst(expr2, expr1.var_type);
TACInstructionListJoin(expr1.ins, expr2.ins, expr.ins);
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_STORE, expr1.res_oprd, expr2.res_oprd, TACNULLOperand);
expr.res_oprd = expr1.res_oprd;
expr.ptr = expr1.ptr;
}
else
{
__valueNOptr(expr2);
TACInstructionListJoin(expr1.ins, expr2.ins, expr.ins);
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_LET, expr1.res_oprd, expr2.res_oprd, TACNULLOperand);
expr.res_oprd = expr1.res_oprd;
expr.ptr = expr1.ptr;
}
}
void TACMakeFOR(TInstructionList& ins1, TExpr& expr2, TInstructionList& ins3, TInstructionList& ins4, TInstructionList& ins)
{
__value2cond(expr2);
int tmplabel1 = TACNewLabel();
int tmplabel2 = TACNewLabel();
int tmplabel3 = TACNewLabel();
TACInstructionListBackAddBlank(ins1);
TACInstructionCreate_3var(*ins1.end, TAC_OP_LABEL, tmplabel3, var_name_NULL, var_name_NULL);
ins1.end->a.oper_type = TAC_oper_type_label;
TACInstructionListFrontAddBlank(ins4);
TACInstructionCreate_3var(*ins4.begin, TAC_OP_LABEL, tmplabel1, var_name_NULL, var_name_NULL);
ins4.begin->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins3);
TACInstructionCreate_3var(*ins3.end, TAC_OP_JMP, tmplabel3, var_name_NULL, var_name_NULL);
ins3.end->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins3);
TACInstructionCreate_3var(*ins3.end, TAC_OP_LABEL, tmplabel2, var_name_NULL, var_name_NULL);
ins3.end->a.oper_type = TAC_oper_type_label;
TACFillInstructionChain(expr2.YesChain, tmplabel1);
TACFillInstructionChain(expr2.NoChain, tmplabel2);
TACInstructionListJoin(ins1, expr2.ins, ins);
TACInstructionListJoin(ins, ins4, ins);
TACInstructionListJoin(ins, ins3, ins);
TACFillInstructionChain(ins4.BreakChain, tmplabel2);
ins.BreakChain.clear();
}
void TACMakeWHILE(TExpr& expr1, TInstructionList& ins2, TInstructionList& ins)
{
__value2cond(expr1);
int tmplabel1 = TACNewLabel();
int tmplabel2 = TACNewLabel();
int tmplabel3 = TACNewLabel();
TACInstructionListFrontAddBlank(expr1.ins);
TACInstructionCreate_3var(*expr1.ins.begin, TAC_OP_LABEL, tmplabel1, var_name_NULL, var_name_NULL);
expr1.ins.begin->a.oper_type = TAC_oper_type_label;
TACInstructionListFrontAddBlank(ins2);
TACInstructionCreate_3var(*ins2.begin, TAC_OP_LABEL, tmplabel2, var_name_NULL, var_name_NULL);
ins2.begin->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins2);
TACInstructionCreate_3var(*ins2.end, TAC_OP_JMP, tmplabel1, var_name_NULL, var_name_NULL);
ins2.end->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins2);
TACInstructionCreate_3var(*ins2.end, TAC_OP_LABEL, tmplabel3, var_name_NULL, var_name_NULL);
ins2.end->a.oper_type = TAC_oper_type_label;
TACFillInstructionChain(expr1.YesChain, tmplabel2);
TACFillInstructionChain(expr1.NoChain, tmplabel3);
TACInstructionListJoin(expr1.ins, ins2, ins);
TACFillInstructionChain(ins2.BreakChain, tmplabel3);
ins.BreakChain.clear();
}
void TACMakeSingleIF(TExpr& expr1, TInstructionList& ins2, TInstructionList& ins)
{
__value2cond(expr1);
int tmplabel1 = TACNewLabel();
int tmplabel2 = TACNewLabel();
TACInstructionListFrontAddBlank(ins2);
TACInstructionCreate_3var(*ins2.begin, TAC_OP_LABEL, tmplabel1, var_name_NULL, var_name_NULL);
ins2.begin->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins2);
TACInstructionCreate_3var(*ins2.end, TAC_OP_LABEL, tmplabel2, var_name_NULL, var_name_NULL);
ins2.end->a.oper_type = TAC_oper_type_label;
TACFillInstructionChain(expr1.YesChain, tmplabel1);
TACFillInstructionChain(expr1.NoChain, tmplabel2);
TACInstructionListJoin(expr1.ins, ins2, ins);
}
void TACMakeIFELSE(TExpr& expr1, TInstructionList& ins2, TInstructionList& ins3, TInstructionList& ins)
{
__value2cond(expr1);
int tmplabel1 = TACNewLabel();
int tmplabel2 = TACNewLabel();
int tmplabel3 = TACNewLabel();
TACInstructionListFrontAddBlank(ins2);
TACInstructionCreate_3var(*ins2.begin, TAC_OP_LABEL, tmplabel1, var_name_NULL, var_name_NULL);
ins2.begin->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins2);
TACInstructionCreate_3var(*ins2.end, TAC_OP_JMP, tmplabel3, var_name_NULL, var_name_NULL);
ins2.end->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins2);
TACInstructionCreate_3var(*ins2.end, TAC_OP_LABEL, tmplabel2, var_name_NULL, var_name_NULL);
ins2.end->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(ins3);
TACInstructionCreate_3var(*ins3.end, TAC_OP_LABEL, tmplabel3, var_name_NULL, var_name_NULL);
ins3.end->a.oper_type = TAC_oper_type_label;
TACFillInstructionChain(expr1.YesChain, tmplabel1);
TACFillInstructionChain(expr1.NoChain, tmplabel2);
TACInstructionListJoin(expr1.ins, ins2, ins);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -