📄 tacsupport.cpp
字号:
#ifndef __TACSUPPORT_CPP__
#define __TACSUPPORT_CPP__
#include <vector>
#include <list>
#include "common.cpp"
#include "symtable.cpp"
#include "IDHash.cpp"
#include "TACConst.cpp"
extern int PROGRAM_RANGECHECK;
extern int PROGRAM_POINTERCHECK;
extern int PROGRAM_FOREXE;
extern int PROGRAM_LineNumber;
extern int BelongingStruct;
using namespace std;
union TOperandUnion {
int id;
int cint;
double cdouble;
};
const int var_name_NULL = -1000;
struct TOperand {
int oper_type; /*
-1: NULL
0 : variable
1 : label
2 : constant of int
3 : constant of double
*/
TOperandUnion data;
TOperand() { oper_type = TAC_oper_type_NULL; }
};
struct TInstruction {
TOperand a, b, c;
int op;
int source_line_number;
int belonging_scope;
TInstruction* next;
};
struct TInstructionList {
TInstruction* begin;
TInstruction* end;
list <TInstruction*> BreakChain;
TInstructionList()
{
begin = end = NULL;
}
void clear()
{
begin = end = NULL;
}
};
struct TExpr {
int cond;
int ptr;
int var_type;
TOperand res_oprd;
list <TInstruction*> YesChain;
list <TInstruction*> NoChain;
TInstructionList ins;
TExpr()
{
cond = ptr = 0;
}
};
struct TTempVar_TAC {
int var_name;
int var_type;
int temp_sign;
int global_sign;
};
TTempVar_TAC TempVar_TAC_Allocate[Limit_TempVar];
list <TTempVar_TAC> TAC_TempVar_Define[Limit_ID];
TInstructionList TAC_Program_Instruction[Limit_ID];
int TACTotalTempVar = 0;
int TACTotalLabel = 0;
TOperand TACNULLOperand;
int TACNewTempVar(int var_type);
int TACAllocateVar(int var_type);
int TACNewLabel();
void TACFillInstructionChain(const list <TInstruction*> & chain, int label_id);
inline int __op_chk_relational(int op_type);
inline int __op_chk_logical(int op_type);
inline int __op_chk_calculational(int op_type);
inline int __oprd_chk_constant(int oper_type);
void TACInstructionListFrontAddBlank(TInstructionList& ins, int blankline);
void TACInstructionListBackAddBlank(TInstructionList& ins, int blankline);
void TACInstructionCreate_3var(TInstruction& inst, int TAC_op_name, int var_name1, int var_name2, int var_name3);
void TACInstructionCreate_3struct(TInstruction& inst, int TAC_op_name, const TOperand op1, const TOperand op2, const TOperand op3);
void __valueNOptr(TExpr& expr, int compulsory_var_type);
void __varADDref(TExpr& expr);
void __varADDptr(TExpr& expr);
void __2tmpVar(TExpr& expr);
void __cond2value(TExpr& expr);
void __value2cond(TExpr& expr);
void __valueNOconst(TExpr& expr, int target_var_type);
inline int __op_src2tac(int op_type);
void TACInstructionListJoin(const TInstructionList ins1, const TInstructionList ins2, TInstructionList& ins);
inline int __constant_relation_i(int oprd1, int oprd2, int op_type);
inline int __constant_calculation_i(int oprd1, int oprd2, int op_type);
void TACCondExprCombine(TExpr& expr1, TExpr& expr2, int op_type, TExpr& expr);
void TACCondExprUnary(TExpr& expr1, int op_type, TExpr& expr);
void TACExprCombine(TExpr& expr1, TExpr& expr2, int op_type, TExpr& expr);
void TACExprUnary(TExpr& expr1, int op_type, TExpr& expr);
void TACPtrMakeConstOffset(TExpr& expr, int offset);
void TACPtrMakeExprOffset(TExpr& expr, TExpr& offset, int unit_size, int backward = 0);
void TACFindArrayAddr(TExpr& expr1, TExpr& expr2, TExpr& expr);
void TACMakePush (TExpr& expr, TInstructionList& ins);
void TACMakeCallPush(int id, list <TExpr>& exprs, TInstructionList& ins);
void TACMakeCall(int id, list <TExpr>& exprs, TExpr& expr);
void TACMakeICall(TExpr& expr1, list <TExpr>& exprs, TExpr& expr);
void TACMakeLET(TExpr& expr1, TExpr& expr2, TExpr& expr);
void TACMakeFOR(TInstructionList& ins1, TExpr& expr2, TInstructionList& ins3, TInstructionList& ins4, TInstructionList& ins);
void TACMakeWHILE(TExpr& expr1, TInstructionList& ins2, TInstructionList& ins);
void TACMakeSingleIF(TExpr& expr1, TInstructionList& ins2, TInstructionList& ins);
void TACMakeIFELSE(TExpr& expr1, TInstructionList& ins2, TInstructionList& ins3, TInstructionList& ins);
void TACMakeConstString(const string& str, TExpr& expr);
void TACMakeBreak(TInstructionList& ins);
void TACAddVariableDecls(int var_type, list <int> var_name);
void TACAddConstVariable(int var_type, int var_name, int val);
void TACMakeConstantIntExpr(TExpr& expr, int intval, int var_type);
void TACMakeEXIT(TInstructionList& ins);
void TACMakeRETURN(TExpr& expr, TInstructionList& ins);
void TACFindField(TExpr& expr1, int id, TExpr& expr);
void TACIdentToExpr(int id, TExpr& expr);
void TACAddVarDeclsToStruct(TSymbolListTypeEntry& Tentry, int var_type, list <int>& var_name);
void TACAddFunctionDecl(int ret_type, int id, list <TSymbolListVariableEntry>& Ventry);
void TACFunctionInsAddEXIT(TInstructionList& ins);
void TACExprSelfAction(TExpr& expr1, int op_type, TExpr& expr);
void TACRegOperation(int op_type, string reg_str, int id, TInstructionList& ins);
void TACBinaryASM(int code, TInstructionList& ins);
void TACASM(TInstructionList& ins, int paramcount, string op_name, string op1 = "\"__(null)\"", string op2 = "\"__(null)\"", string op3 = "\"__(null)\"");
int TACNewTempVar(int var_type)
{
TempVar_TAC_Allocate[TACTotalTempVar].var_name = TACTotalTempVar;
TempVar_TAC_Allocate[TACTotalTempVar].var_type = var_type;
TempVar_TAC_Allocate[TACTotalTempVar].temp_sign = 1;
TempVar_TAC_Allocate[TACTotalTempVar].global_sign = 0;
return TACTotalTempVar ++;
}
int TACAllocateVar(int var_type)
{
TempVar_TAC_Allocate[TACTotalTempVar].var_name = TACTotalTempVar;
TempVar_TAC_Allocate[TACTotalTempVar].var_type = var_type;
TempVar_TAC_Allocate[TACTotalTempVar].temp_sign = 0;
TempVar_TAC_Allocate[TACTotalTempVar].global_sign = 0;
return TACTotalTempVar ++;
}
int TACNewLabel()
{
return TACTotalLabel ++;
}
void TACFillInstructionChain(const list <TInstruction*> & chain, int label_id)
{
for (list <TInstruction*> :: const_iterator p = chain.begin(); p != chain.end(); p++)
{
if ((*p)->op == TAC_OP_JMP)
{
(*p)->a.oper_type = TAC_oper_type_label;
(*p)->a.data.id = label_id;
}
else
{
(*p)->c.oper_type = TAC_oper_type_label;
(*p)->c.data.id = label_id;
}
}
}
inline int __op_chk_relational(int op_type)
{
return (op_type >= TAC_SRC_relational_LES && op_type <= TAC_SRC_relational_NEQ);
}
inline int __op_chk_logical(int op_type)
{
return (op_type >= TAC_SRC_logical_NOT && op_type <= TAC_SRC_logical_OR);
}
inline int __op_chk_calculational(int op_type)
{
return (op_type >= TAC_SRC_calculational_ADD && op_type <= TAC_SRC_calculational_SHR || op_type == TAC_SRC_calculational_NOT);
}
inline int __oprd_chk_constant(int oper_type)
{
return (oper_type == TAC_oper_type_constint || oper_type == TAC_oper_type_constdouble);
}
void TACInstructionListFrontAddBlank(TInstructionList& ins, int blankline = 0)
{
TInstruction* p;
p = new(TInstruction);
p->next = ins.begin;
if (blankline)
{
p->source_line_number = PROGRAM_BlankLineNumber;
}
else
{
p->source_line_number = PROGRAM_LineNumber;
}
p->belonging_scope = SymbolListScopeStack[SymbolListScopeStackTOP - 1];
if (ins.begin == NULL)
{
ins.begin = p;
ins.end = p;
}
else
{
ins.begin = p;
}
}
void TACInstructionListBackAddBlank(TInstructionList& ins, int blankline = 0)
{
TInstruction* p;
p = new(TInstruction);
p->next = NULL;
if (blankline)
{
p->source_line_number = PROGRAM_BlankLineNumber;
}
else
{
p->source_line_number = PROGRAM_LineNumber;
}
p->belonging_scope = SymbolListScopeStack[SymbolListScopeStackTOP - 1];
if (ins.begin == NULL)
{
ins.begin = p;
ins.end = p;
}
else
{
ins.end->next = p;
ins.end = p;
}
}
void TACInstructionCreate_3var(TInstruction& inst, int TAC_op_name, int var_name1, int var_name2, int var_name3)
{
if (var_name1 != var_name_NULL)
{
inst.a.oper_type = TAC_oper_type_variable;
inst.a.data.id = var_name1;
}
if (var_name2 != var_name_NULL)
{
inst.b.oper_type = TAC_oper_type_variable;
inst.b.data.id = var_name2;
}
if (var_name3 != var_name_NULL)
{
inst.c.oper_type = TAC_oper_type_variable;
inst.c.data.id = var_name3;
}
inst.op = TAC_op_name;
}
void TACInstructionCreate_3struct(TInstruction& inst, int TAC_op_name, const TOperand op1, const TOperand op2, const TOperand op3)
{
inst.a = op1;
inst.b = op2;
inst.c = op3;
inst.op = TAC_op_name;
}
void __valueNOptr(TExpr& expr, int compulsory_var_type = var_type_notfound)
{
if (!expr.cond && expr.ptr)
{
expr.ptr = 0;
int target_var_type;
if (compulsory_var_type != var_type_notfound)
{
target_var_type = compulsory_var_type;
}
else
{
target_var_type = expr.var_type;
}
int tmpvar_name = TACNewTempVar(target_var_type);
TACInstructionListBackAddBlank(expr.ins, 1);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LOAD, tmpvar_name, var_name_NULL, var_name_NULL);
expr.ins.end->b = expr.res_oprd;
expr.res_oprd = expr.ins.end->a;
}
}
void __varADDref(TExpr& expr)
{
if (expr.ptr)
{
expr.ptr = 0;
}
else
{
expr.ptr = 0;
int tmpvar_name = TACNewTempVar(var_type_int);
TACInstructionListBackAddBlank(expr.ins, 1);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LEA, tmpvar_name, var_name_NULL, var_name_NULL);
expr.ins.end->b = expr.res_oprd;
expr.res_oprd = expr.ins.end->a;
}
if (!__chk_basic_type(expr.var_type) && SymbolListType[expr.var_type].type_number == type_number_array)
{
expr.var_type = SymbolListTypeADDStar (SymbolListType[expr.var_type].ret_type_id);
}
else
{
expr.var_type = SymbolListTypeADDStar (expr.var_type);
}
}
void __varADDptr(TExpr& expr)
{
if (!expr.ptr)
{
expr.ptr = 1;
}
else
{
expr.ptr = 1;
int tmpvar_name = TACNewTempVar(SymbolListType[expr.var_type].ret_type_id);
TACInstructionListBackAddBlank(expr.ins, 1);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LOAD, tmpvar_name, var_name_NULL, var_name_NULL);
expr.ins.end->b = expr.res_oprd;
expr.res_oprd = expr.ins.end->a;
}
expr.var_type = SymbolListTypeDELStar (expr.var_type);
}
void __2tmpVar(TExpr& expr)
{
if (!__oprd_chk_constant(expr.res_oprd.oper_type))
{
if (TempVar_TAC_Allocate[expr.res_oprd.data.id].temp_sign) return;
int tmpvar_name = TACNewTempVar(TempVar_TAC_Allocate[expr.res_oprd.data.id].var_type);
TACInstructionListBackAddBlank(expr.ins, 1);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LET, tmpvar_name, var_name_NULL, var_name_NULL);
expr.ins.end->b = expr.res_oprd;
expr.res_oprd = expr.ins.end->a;
}
}
void __cond2value(TExpr& expr)
{
if (expr.cond)
{
int tmpvar_name = TACNewTempVar(var_type_int);
if (expr.YesChain.empty() || expr.NoChain.empty()) // Boolean Constant
{
expr.ins.clear();
/* TACInstructionListBackAddBlank(expr.ins, 1);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LET, tmpvar_name, var_name_NULL, var_name_NULL);
expr.ins.end->b.oper_type = TAC_oper_type_constint; */
expr.res_oprd.oper_type = TAC_oper_type_constint;
if (expr.YesChain.empty())
{
expr.res_oprd.data.cint = 0;
}
else
{
expr.res_oprd.data.cint = 1;
}
expr.cond = 0;
return;
}
else
{
int tmplabel1 = TACNewLabel();
int tmplabel2 = TACNewLabel();
int tmplabel3 = TACNewLabel();
TACInstructionListBackAddBlank(expr.ins, 1); // Label 1 (No Chain)
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LABEL, tmplabel1, var_name_NULL, var_name_NULL);
expr.ins.end->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(expr.ins, 1); // Let res = 0
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LET, tmpvar_name, var_name_NULL, var_name_NULL);
expr.ins.end->b.oper_type = TAC_oper_type_constint;
expr.ins.end->b.data.cint = 0;
TACInstructionListBackAddBlank(expr.ins, 1); // Jump to Label 3
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_JMP, tmplabel3, var_name_NULL, var_name_NULL);
expr.ins.end->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(expr.ins, 1); // Label 2 (Yes Chain)
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LABEL, tmplabel2, var_name_NULL, var_name_NULL);
expr.ins.end->a.oper_type = TAC_oper_type_label;
TACInstructionListBackAddBlank(expr.ins, 1); // Let res = 1
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LET, tmpvar_name, var_name_NULL, var_name_NULL);
expr.ins.end->b.oper_type = TAC_oper_type_constint;
expr.ins.end->b.data.cint = 1;
TACInstructionListBackAddBlank(expr.ins, 1); // Label 3
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LABEL, tmplabel3, var_name_NULL, var_name_NULL);
expr.ins.end->a.oper_type = TAC_oper_type_label;
TACFillInstructionChain(expr.YesChain, tmplabel2);
TACFillInstructionChain(expr.NoChain, tmplabel1);
}
expr.cond = 0;
expr.res_oprd.oper_type = TAC_oper_type_variable;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -