📄 tacsupport.cpp
字号:
TACInstructionListJoin(ins, ins3, ins);
}
void TACMakeConstString(const string& str, TExpr& expr)
{
expr.ins.clear();
TSymbolListConstStringEntry CSentry;
CSentry.data.clear();
for (unsigned int i = 1; i < str.size() - 1; i++)
{
if (str[i] == '\\')
{
i++;
switch (str[i])
{
case 'n' : CSentry.data.push_back(10);
break;
case 't' : CSentry.data.push_back(9);
break;
case 'b' : CSentry.data.push_back(8);
break;
case 'r' : CSentry.data.push_back(13);
break;
case '0' : CSentry.data.push_back(0);
break;
default : CSentry.data.push_back((unsigned char)(str[i]));
}
}
else
{
CSentry.data.push_back((unsigned char)(str[i]));
}
}
CSentry.data.push_back(0);
for (int i = 0; i < SymbolListConstStringCNT; i ++)
{
int ok = 1;
list <int> :: iterator p = SymbolListConstString[i].data.begin();
list <int> :: iterator q = CSentry.data.begin();
while (q != CSentry.data.end())
{
if (p == SymbolListConstString[i].data.end() || *p != *q)
{
ok = 0;
break;
}
p ++; q ++;
}
if (ok)
{
expr.var_type = SymbolListConstString[i].Ventry.var_type;
expr.res_oprd.oper_type = TAC_oper_type_variable;
expr.res_oprd.data.id = SymbolListConstString[i].Ventry.var_name_TAC;
return;
}
}
CSentry.Ventry.level = 0;
CSentry.Ventry.var_type = SymbolListTypeADDStar(var_type_char);
CSentry.Ventry.var_name_TAC = TACAllocateVar(CSentry.Ventry.var_type);
char buf[10];
sprintf(buf, "#%d", SymbolListConstStringCNT);
int id = IDHash_ID2int(string(buf));
SymbolListAddConstStringEntry(id, CSentry);
expr.var_type = CSentry.Ventry.var_type;
expr.res_oprd.oper_type = TAC_oper_type_variable;
expr.res_oprd.data.id = CSentry.Ventry.var_name_TAC;
}
void TACMakeBreak(TInstructionList& ins)
{
ins.clear();
ins.BreakChain.clear();
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_JMP, var_name_NULL, var_name_NULL, var_name_NULL);
ins.BreakChain.push_back(ins.end);
}
void TACAddVariableDecls(int var_type, list <int> var_name)
{
TSymbolListVariableEntry Ventry;
Ventry.var_type = var_type;
Ventry.level = SymbolListNowLevel;
Ventry.const_sign = 0;
// printf("Add var TYPE : %s @ level %d, ", var_type >= 0 ? IDHash_int2ID(var_type).c_str() : "basic", Ventry.level);
for (list <int> :: iterator p = var_name.begin(); p != var_name.end(); p ++)
{
// printf("%s, ", IDHash_int2ID(*p).c_str());
Ventry.var_name_TAC = TACAllocateVar(var_type);
SymbolListAddVariableEntry(*p, Ventry);
}
// printf("\n");
}
void TACAddConstVariable(int var_type, int var_name, int val)
{
TSymbolListVariableEntry Ventry;
Ventry.var_type = var_type;
Ventry.level = SymbolListNowLevel;
Ventry.const_sign = 1;
Ventry.const_val = val;
// printf("Add const var TYPE : %s @ level %d, ", var_type >= 0 ? IDHash_int2ID(var_type).c_str() : "basic", Ventry.level);
// printf("%s, ", IDHash_int2ID(var_name).c_str());
SymbolListAddVariableEntry(var_name, Ventry);
// printf(" = %d\n", val);
}
void TACMakeConstantIntExpr(TExpr& expr, int intval, int var_type)
{
expr.ins.clear();
expr.cond = 0;
expr.res_oprd.oper_type = TAC_oper_type_constint;
expr.res_oprd.data.cint = intval;
expr.var_type = var_type;
}
void TACMakeEXIT(TInstructionList& ins)
{
ins.clear();
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_EXIT, var_name_NULL, var_name_NULL, var_name_NULL);
}
void TACMakeRETURN(TExpr& expr, TInstructionList& ins)
{
__cond2value(expr);
__valueNOptr(expr);
ins = expr.ins;
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3struct(*ins.end, TAC_OP_RET, expr.res_oprd, TACNULLOperand, TACNULLOperand);
}
void TACIdentToExpr(int id, TExpr& expr)
{
expr.cond = 0;
expr.ptr = 0;
if (!SymbolListVariable[id].empty())
{
expr.ins.clear();
expr.var_type = SymbolListVariable[id].begin()->var_type;
if (SymbolListVariable[id].begin()->const_sign)
{
// printf("ID : %s, TYPE : %s (const) = %d \n", IDHash_int2ID(id).c_str(), expr.var_type >= 0 ? IDHash_int2ID(expr.var_type).c_str() : "basic", SymbolListVariable[id].begin()->const_val);
expr.res_oprd.oper_type = TAC_oper_type_constint;
expr.res_oprd.data.cint = SymbolListVariable[id].begin()->const_val;
}
else
{
// printf("ID : %s, TYPE : %s\n", IDHash_int2ID(id).c_str(), expr.var_type >= 0 ? IDHash_int2ID(expr.var_type).c_str() : "basic");
expr.res_oprd.oper_type = TAC_oper_type_variable;
expr.res_oprd.data.cint = SymbolListVariable[id].begin()->var_name_TAC;
}
}
else if (SymbolListFunction[id].func_type != type_undefined)
{
expr.ins.clear();
expr.var_type = SymbolListFunction[id].func_type;
int tmpvar_name = TACNewTempVar(expr.var_type);
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LEAFUNC, tmpvar_name, var_name_NULL, var_name_NULL);
expr.ins.end->b.oper_type = TAC_oper_type_constint;
expr.ins.end->b.data.cint = id;
expr.res_oprd = expr.ins.end->a;
}
}
void TACFindField(TExpr& expr1, int id, TExpr& expr)
{
int offset = 0;
int var_type = expr1.var_type, target_var_type;
__varADDref(expr1);
expr = expr1;
// printf ("Finding %s\n", IDHash_int2ID(var_type).c_str());
for (list <TSymbolListVariableEntry> :: iterator p = SymbolListType[var_type].field_var.begin();
p != SymbolListType[var_type].field_var.end(); p++)
{
// printf ("%d @ %d\n", p->id, p->var_type);
if (p->id == id)
{
target_var_type = p->var_type;
break;
}
offset += __get_sizeof(p->var_type);
}
TACPtrMakeConstOffset(expr, offset);
__varADDptr(expr);
expr.var_type = target_var_type;
// printf ("%d\n", target_var_type);
}
void TACAddVarDeclsToStruct(TSymbolListTypeEntry& Tentry, int var_type, list <int>& var_name)
{
TSymbolListVariableEntry Ventry;
Ventry.var_type = var_type;
Ventry.level = 0;
for (list <int> :: iterator p = var_name.begin(); p != var_name.end(); p ++)
{
Ventry.id = *p;
Tentry.field_var.push_back(Ventry);
Tentry.total_size += __get_sizeof(var_type);
}
}
void TACAddFunctionDecl(int ret_type, int id, list <TSymbolListVariableEntry>& Ventry)
{
TSymbolListFunctionEntry Fentry;
Fentry.id = id;
Fentry.func_type = SymbolListMakeFunctionType(ret_type, Ventry);
Fentry.arg_list.clear();
SymbolListAddFunctionEntry(id, Fentry);
}
void TACFunctionInsAddEXIT(TInstructionList& ins)
{
if (ins.end == NULL || ins.end->op != TAC_OP_RET && ins.end->op != TAC_OP_EXIT)
{
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_EXIT, var_name_NULL, var_name_NULL, var_name_NULL);
}
}
void TACExprSelfAction(TExpr& expr1, int op_type, TExpr& expr)
{
int size = __get_sizeof(var_type_int);
if (SymbolListType[expr1.var_type].type_number == type_number_pointer)
{
size = __get_sizeof(SymbolListType[expr1.var_type].ret_type_id);
}
expr.ins.clear();
if (expr1.ptr)
{
expr.var_type = expr1.var_type;
expr.cond = 0;
expr.ptr = 0;
int v1 = TACNewTempVar(var_type_int);
int v2 = TACNewTempVar(var_type_int);
int v3 = TACNewTempVar(var_type_int);
TACInstructionListBackAddBlank(expr1.ins);
TACInstructionCreate_3var(*expr1.ins.end, TAC_OP_LET, v1, var_name_NULL, var_name_NULL);
expr1.ins.end->b = expr1.res_oprd;
__valueNOptr(expr1);
TACInstructionListJoin(expr1.ins, expr.ins, expr.ins);
expr.res_oprd = expr1.res_oprd;
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LET, v3, var_name_NULL, var_name_NULL);
expr.ins.end->b = expr.res_oprd;
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_ADD, v2, var_name_NULL, var_name_NULL);
expr.ins.end->b = expr.res_oprd;
expr.ins.end->c.oper_type = TAC_oper_type_constint;
if (op_type == TAC_SRC_calculational_ADD)
{
expr.ins.end->c.data.cint = size;
}
else
{
expr.ins.end->c.data.cint = -size;
}
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_STORE, v1, v2, var_name_NULL);
expr.res_oprd.oper_type = TAC_oper_type_variable;
expr.res_oprd.data.cint = v3;
}
else
{
expr.var_type = expr1.var_type;
expr.cond = 0;
expr.ptr = 0;
int v2 = TACNewTempVar(var_type_int);
TACInstructionListJoin(expr1.ins, expr.ins, expr.ins);
expr.res_oprd = expr1.res_oprd;
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LET, v2, var_name_NULL, var_name_NULL);
expr.ins.end->b = expr.res_oprd;
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_ADD, var_name_NULL, var_name_NULL, var_name_NULL);
expr.ins.end->a = expr.res_oprd;
expr.ins.end->b = expr.res_oprd;
expr.ins.end->c.oper_type = TAC_oper_type_constint;
if (op_type == TAC_SRC_calculational_ADD)
{
expr.ins.end->c.data.cint = size;
}
else
{
expr.ins.end->c.data.cint = -size;
}
expr.res_oprd.oper_type = TAC_oper_type_variable;
expr.res_oprd.data.cint = v2;
}
}
void TACRegOperation(int op_type, string reg_str, int id, TInstructionList& ins)
{
ins.clear();
int reg_num;
reg_str = reg_str.substr(1, reg_str.length() - 2);
sscanf(reg_str.c_str(), "r%d", ®_num);
if (op_type == REG_OP_READ)
{
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_RREAD, var_name_NULL, SymbolListVariable[id].begin()->var_name_TAC, var_name_NULL);
ins.end->a.oper_type = TAC_oper_type_constint;
ins.end->a.data.cint = reg_num;
}
else
{
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_RWRITE, var_name_NULL, SymbolListVariable[id].begin()->var_name_TAC, var_name_NULL);
ins.end->a.oper_type = TAC_oper_type_constint;
ins.end->a.data.cint = reg_num;
}
}
void TACBinaryASM(int code, TInstructionList& ins)
{
ins.clear();
TACInstructionListBackAddBlank(ins);
TACInstructionCreate_3var(*ins.end, TAC_OP_ASM, var_name_NULL, var_name_NULL, var_name_NULL);
ins.end->a.oper_type = TAC_oper_type_constint;
ins.end->a.data.cint = code;
}
void TACASM(TInstructionList& ins, int paramcount, string op_name, string op1, string op2, string op3)
{
int j, total_op;
total_op = sizeof(ASMops) / sizeof(TASMop);
op_name = op_name.substr(1, op_name.length() - 2);
for (j = 0; j < total_op; j ++)
{
if (op_name == ASMops[j].op_name) break;
}
string operands[3];
operands[0] = op1.substr(1, op1.length() - 2);
operands[1] = op2.substr(1, op2.length() - 2);
operands[2] = op3.substr(1, op3.length() - 2);
int nums[3];
for (int i = 0; i < paramcount; i ++)
{
if (operands[i].length() >= 1 && operands[i][0] == 'r')
{
sscanf(operands[i].c_str(), "r%d", nums + i);
}
else
{
if (operands[i].length() >= 2 && operands[i][0] == '0' && operands[i][1] == 'x')
{
sscanf(operands[i].c_str(), "%x", nums + i);
}
else
{
sscanf(operands[i].c_str(), "%d", nums + i);
}
}
}
int count[3];
int rescode = 0;
memset(count, 0, sizeof(count));
int p = 0;
for (int i = strlen(ASMops[j].code) - 1; i >= 0; i --, p ++)
{
if (ASMops[j].code[i] == '0') ;
else if (ASMops[j].code[i] == '1') rescode |= (1 << p);
else if (ASMops[j].code[i] == 'x' || ASMops[j].code[i] == 'X') rescode |= (((nums[0] >> count[0] ++) & 1) << p);
else if (ASMops[j].code[i] == 'y' || ASMops[j].code[i] == 'Y') rescode |= (((nums[1] >> count[1] ++) & 1) << p);
else if (ASMops[j].code[i] == 'z' || ASMops[j].code[i] == 'Z') rescode |= (((nums[2] >> count[2] ++) & 1) << p);
}
TACBinaryASM(rescode, ins);
}
void TACKMakeConstantIntblock(list <int>& ints, TExpr& expr)
{
expr.ins.clear();
TSymbolListConstStringEntry CSentry;
CSentry.data.clear();
for (list <int> :: iterator p = ints.begin(); p != ints.end(); p ++)
{
CSentry.data.push_back(*p);
}
CSentry.Ventry.level = 0;
CSentry.Ventry.var_type = SymbolListTypeADDStar(var_type_int);
CSentry.Ventry.var_name_TAC = TACAllocateVar(CSentry.Ventry.var_type);
char buf[10];
sprintf(buf, "#%d", SymbolListConstStringCNT);
int id = IDHash_ID2int(string(buf));
SymbolListAddConstStringEntry(id, CSentry);
expr.var_type = CSentry.Ventry.var_type;
expr.res_oprd.oper_type = TAC_oper_type_variable;
expr.res_oprd.data.id = CSentry.Ventry.var_name_TAC;
}
#endif // __TACSUPPORT_CPP__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -