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

📄 tacsupport.cpp

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

	__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 + -