⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tacsupport.cpp

📁 一个用C++实现的C的Compiler。 代码风格良好。 原作者自己写了这个编译器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#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 + -