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

📄 tacsupport.cpp

📁 一个用C++实现的C的Compiler。 代码风格良好。 原作者自己写了这个编译器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		expr.res_oprd.data.id = tmpvar_name;
		expr.var_type = var_type_bool;
	}
}

void __value2cond(TExpr& expr)
{
	if (!expr.cond)
	{
		__valueNOptr(expr);
		expr.cond = 1;
		expr.YesChain.clear();
		expr.NoChain.clear();

		if (__oprd_chk_constant(expr.res_oprd.oper_type))								// Boolean Constant
		{
			TACInstructionListBackAddBlank(expr.ins, 1);														// Jump to XXX
			TACInstructionCreate_3var(*expr.ins.end, TAC_OP_JMP, var_name_NULL, var_name_NULL, var_name_NULL);

			if (expr.res_oprd.oper_type == TAC_oper_type_constint && expr.res_oprd.data.cint == 0 ||
				expr.res_oprd.oper_type == TAC_oper_type_constdouble && expr.res_oprd.data.cdouble == 0)
			{
				expr.NoChain.push_back(expr.ins.end);
			}
			else
			{
				expr.YesChain.push_back(expr.ins.end);
			}
		}
		else
		{
			TACInstructionListBackAddBlank(expr.ins, 1);														// IF (res == 0) Jump to XXX
			TACInstructionCreate_3var(*expr.ins.end, TAC_OP_JE, expr.res_oprd.data.id, var_name_NULL, var_name_NULL);
			expr.ins.end->b.oper_type = TAC_oper_type_constint;
			expr.ins.end->b.data.cint = 0;
			expr.NoChain.push_back(expr.ins.end);

			TACInstructionListBackAddBlank(expr.ins, 1);														// Jump to XXX
			TACInstructionCreate_3var(*expr.ins.end, TAC_OP_JMP, var_name_NULL, var_name_NULL, var_name_NULL);
			expr.YesChain.push_back(expr.ins.end);
		}
	}
}

void __valueNOconst(TExpr& expr, int target_var_type)
{
	if (!expr.cond && __oprd_chk_constant(expr.res_oprd.oper_type))
	{
		int tmpvar_name = TACNewTempVar(target_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;
	}
}

inline int __op_src2tac(int op_type)
{
	if (op_type == TAC_SRC_relational_EQL) return TAC_OP_JE;
	if (op_type == TAC_SRC_relational_NEQ) return TAC_OP_JNE;
	if (op_type == TAC_SRC_relational_LES) return TAC_OP_JL;
	if (op_type == TAC_SRC_relational_LEQ) return TAC_OP_JLE;
	if (op_type == TAC_SRC_relational_GTR) return TAC_OP_JG;
	if (op_type == TAC_SRC_relational_GEQ) return TAC_OP_JGE;

	if (op_type == TAC_SRC_calculational_ADD) return TAC_OP_ADD;
	if (op_type == TAC_SRC_calculational_MINUS) return TAC_OP_SUB;
	if (op_type == TAC_SRC_calculational_MUL) return TAC_OP_MUL;
	if (op_type == TAC_SRC_calculational_DIV) return TAC_OP_DIV;
	if (op_type == TAC_SRC_calculational_MOD) return TAC_OP_MOD;

	if (op_type == TAC_SRC_calculational_AND) return TAC_OP_AND;
	if (op_type == TAC_SRC_calculational_OR) return TAC_OP_OR;
	if (op_type == TAC_SRC_calculational_NOT) return TAC_OP_NOT;
	if (op_type == TAC_SRC_calculational_XOR) return TAC_OP_XOR;
	if (op_type == TAC_SRC_calculational_SHL) return TAC_OP_SHL;
	if (op_type == TAC_SRC_calculational_SHR) return TAC_OP_SHR;

	return -1;
}

void TACInstructionListJoin(const TInstructionList ins1, const TInstructionList ins2, TInstructionList& ins)
{
	if (ins1.begin == NULL)
	{
		ins = ins2;
	}
	else
	{
		ins = ins1;
		if (ins2.begin != NULL)
		{
			ins.end->next = ins2.begin;
			ins.end = ins2.end;
		}
	}
	ins.BreakChain = ins1.BreakChain;
	ins.BreakChain.insert(ins.BreakChain.end(), ins2.BreakChain.begin(), ins2.BreakChain.end());
}

inline int __constant_relation_i(int oprd1, int oprd2, int op_type)
{
	if (op_type == TAC_SRC_relational_LES) return oprd1 < oprd2;
	if (op_type == TAC_SRC_relational_LEQ) return oprd1 <= oprd2;
	if (op_type == TAC_SRC_relational_GTR) return oprd1 > oprd2;
	if (op_type == TAC_SRC_relational_GEQ) return oprd1 >= oprd2;
	if (op_type == TAC_SRC_relational_EQL) return oprd1 == oprd2;
	if (op_type == TAC_SRC_relational_NEQ) return oprd1 != oprd2;
	return -1;
}

inline int __constant_calculation_i(int oprd1, int oprd2, int op_type)
{
	if (op_type == TAC_SRC_calculational_ADD) return oprd1 + oprd2;
	if (op_type == TAC_SRC_calculational_MINUS) return oprd1 - oprd2;
	if (op_type == TAC_SRC_calculational_MUL) return oprd1 * oprd2;
	if (op_type == TAC_SRC_calculational_DIV) return oprd1 / oprd2;
	if (op_type == TAC_SRC_calculational_MOD) return oprd1 % oprd2;
	if (op_type == TAC_SRC_calculational_AND) return oprd1 & oprd2;
	if (op_type == TAC_SRC_calculational_OR) return oprd1 | oprd2;
	if (op_type == TAC_SRC_calculational_XOR) return oprd1 ^ oprd2;
	if (op_type == TAC_SRC_calculational_SHL) return oprd1 << oprd2;
	if (op_type == TAC_SRC_calculational_SHR) return oprd1 >> oprd2;
	return 0;
}

void TACCondExprCombine(TExpr& expr1, TExpr& expr2, int op_type, TExpr& expr)
{
	expr.cond = 1;
	expr.YesChain.clear();
	expr.NoChain.clear();
	expr.ins.clear();

	if (__op_chk_relational(op_type))
	{
		__cond2value(expr1);
		__cond2value(expr2);

		__valueNOptr(expr1);
		__valueNOptr(expr2);

		if (__oprd_chk_constant(expr1.res_oprd.oper_type) && __oprd_chk_constant(expr2.res_oprd.oper_type))			// Constant Folding
		{
			int tmpres;
			tmpres = __constant_relation_i(expr1.res_oprd.data.cint, expr2.res_oprd.data.cint, op_type);
			TACInstructionListBackAddBlank(expr.ins);
			TACInstructionCreate_3var(*expr.ins.end, TAC_OP_JMP, var_name_NULL, var_name_NULL, var_name_NULL);
			if (tmpres)
			{
				expr.YesChain.push_back(expr.ins.end);
			}
			else
			{
				expr.NoChain.push_back(expr.ins.end);
			}
			return;
		}
		
		TACInstructionListJoin(expr1.ins, expr2.ins, expr.ins);

		int TAC_op_type = __op_src2tac(op_type);

		TACInstructionListBackAddBlank(expr.ins);															// IF (res1 relational_op res2) Jump to XXX
		TACInstructionCreate_3struct(*expr.ins.end, TAC_op_type, expr1.res_oprd, expr2.res_oprd, TACNULLOperand);
		expr.YesChain.push_back(expr.ins.end);

		TACInstructionListBackAddBlank(expr.ins);															// Jump to XXX
		TACInstructionCreate_3var(*expr.ins.end, TAC_OP_JMP, var_name_NULL, var_name_NULL, var_name_NULL);
		expr.NoChain.push_back(expr.ins.end);

 		return;
	}

	if (__op_chk_logical(op_type))
	{
		__value2cond(expr1);
		__value2cond(expr2);

		if (op_type == TAC_SRC_logical_AND)
		{
			int tmplabel = TACNewLabel();

			TACInstructionListFrontAddBlank(expr2.ins);
			TACInstructionCreate_3var(*expr2.ins.begin, TAC_OP_LABEL, tmplabel, var_name_NULL, var_name_NULL);
			expr2.ins.begin->a.oper_type = TAC_oper_type_label;

			TACFillInstructionChain(expr1.YesChain, tmplabel);															// IF (res1) Jump to RES2
			TACInstructionListJoin(expr1.ins, expr2.ins, expr.ins);

			expr.YesChain = expr2.YesChain;																				// if (res2) FINAL TRUE
			expr.NoChain = expr1.NoChain;
			expr.NoChain.insert(expr.NoChain.end(), expr2.NoChain.begin(), expr2.NoChain.end());						// Jump Outs
			return;
		}

		if (op_type == TAC_SRC_logical_OR)
		{
			int tmplabel = TACNewLabel();

			TACInstructionListFrontAddBlank(expr2.ins);
			TACInstructionCreate_3var(*expr2.ins.begin, TAC_OP_LABEL, tmplabel, var_name_NULL, var_name_NULL);
			expr2.ins.begin->a.oper_type = TAC_oper_type_label;

			TACFillInstructionChain(expr1.NoChain, tmplabel);															// IF (!res1) Jump to RES2
			TACInstructionListJoin(expr1.ins, expr2.ins, expr.ins);

			expr.YesChain = expr1.YesChain;
			expr.YesChain.insert(expr.YesChain.end(), expr2.YesChain.begin(), expr2.YesChain.end());					// Jump Outs
			expr.NoChain = expr2.NoChain;																				// if (!res2) FINAL FALSE
			return;
		}
	}
}

void TACCondExprUnary(TExpr& expr1, int op_type, TExpr& expr)
{
	__value2cond(expr1);

	expr.cond = 1;
	if (op_type == TAC_SRC_logical_NOT)
	{
		expr.ins = expr1.ins;
		expr.NoChain = expr1.YesChain;
		expr.YesChain = expr1.NoChain;
		return;
	}
}

void TACExprCombine(TExpr& expr1, TExpr& expr2, int op_type, TExpr& expr)
{
	if (SymbolListType[expr1.var_type].type_number == type_number_array)
	{
		__varADDref(expr1);
	}
	if (SymbolListType[expr1.var_type].type_number == type_number_pointer)
	{
		if (op_type == TAC_SRC_calculational_ADD)
		{
			TACPtrMakeExprOffset(expr1, expr2, __get_sizeof(SymbolListType[expr1.var_type].ret_type_id));
			expr = expr1;
		}
		else if (op_type == TAC_SRC_calculational_MINUS)
		{
			TACPtrMakeExprOffset(expr1, expr2, __get_sizeof(SymbolListType[expr1.var_type].ret_type_id), 1);
			expr = expr1;
		}
		return;
	}

	__cond2value(expr1);
	__cond2value(expr2);
	__valueNOptr(expr1);
	__valueNOptr(expr2);

	expr.cond = 0;
	expr.ins.clear();
	expr.var_type = expr1.var_type;
	expr.ptr = 0;

	if (__oprd_chk_constant(expr1.res_oprd.oper_type) && __oprd_chk_constant(expr2.res_oprd.oper_type))			// Constant Folding
	{
		expr.res_oprd.oper_type = TAC_oper_type_constint;
		expr.res_oprd.data.cint = __constant_calculation_i(expr1.res_oprd.data.cint, expr2.res_oprd.data.cint, op_type);
		return;
	}

	int TAC_op_type = __op_src2tac(op_type);
	TOperand res_oprd;

	if (expr1.res_oprd.oper_type == TAC_oper_type_variable 
			&& TempVar_TAC_Allocate[expr1.res_oprd.data.id].temp_sign)
	{
		res_oprd = expr1.res_oprd;
	}
	else
	{
		if (expr2.res_oprd.oper_type == TAC_oper_type_variable
				&& TempVar_TAC_Allocate[expr2.res_oprd.data.id].temp_sign)
		{
			res_oprd = expr2.res_oprd;
		}
		else
		{
			res_oprd.oper_type = TAC_oper_type_variable;
			res_oprd.data.id = TACNewTempVar(var_type_int);
		}
	}

	TACInstructionListJoin(expr1.ins, expr2.ins, expr.ins);

	TACInstructionListBackAddBlank(expr.ins);
	TACInstructionCreate_3struct(*expr.ins.end, TAC_op_type, res_oprd, expr1.res_oprd, expr2.res_oprd);
	expr.res_oprd = res_oprd;
}

void TACExprUnary(TExpr& expr1, int op_type, TExpr& expr)
{
	__cond2value(expr1);
	__valueNOptr(expr1);

	expr.cond = 0;
	expr.ptr = 0;
	expr.var_type = expr1.var_type;
	expr.ins.clear();

	if (op_type == TAC_SRC_calculational_MINUS)
	{
		if (__oprd_chk_constant(expr1.res_oprd.oper_type))											// Constant Folding
		{
			expr.res_oprd = expr1.res_oprd;
			expr.res_oprd.data.cint = -expr.res_oprd.data.cint;
			return;
		}

		expr.ins = expr1.ins;

		TOperand firstoprd;
		firstoprd.oper_type = TAC_oper_type_constint;
		firstoprd.data.cint = 0;

		if (!TempVar_TAC_Allocate[expr1.res_oprd.data.id].temp_sign)
		{
			expr.res_oprd.oper_type = TAC_oper_type_variable;
			expr.res_oprd.data.id = TACNewTempVar(var_type_int);
		}
		else
		{
			expr.res_oprd = expr1.res_oprd;
		}

		TACInstructionListBackAddBlank(expr.ins);
		TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_SUB, expr.res_oprd, firstoprd, expr1.res_oprd);

		return;
	}
	else if (op_type == TAC_SRC_calculational_NOT)
	{
		if (__oprd_chk_constant(expr1.res_oprd.oper_type))											// Constant Folding
		{
			expr.res_oprd = expr1.res_oprd;
			expr.res_oprd.data.cint = ~expr.res_oprd.data.cint;
			return;
		}

		expr.ins = expr1.ins;

		if (!TempVar_TAC_Allocate[expr1.res_oprd.data.id].temp_sign)
		{
			expr.res_oprd.oper_type = TAC_oper_type_variable;
			expr.res_oprd.data.id = TACNewTempVar(var_type_int);
		}
		else
		{
			expr.res_oprd = expr1.res_oprd;
		}

		TACInstructionListBackAddBlank(expr.ins);
		TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_NOT, expr.res_oprd, expr1.res_oprd, TACNULLOperand);

		return;
	} 
}

void TACPtrMakeConstOffset(TExpr& expr, int offset)
{
	__2tmpVar(expr);
	__valueNOconst(expr, var_type_int);
	TACInstructionListBackAddBlank(expr.ins);
	if (offset >= 0)
	{
		TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_ADD, expr.res_oprd, expr.res_oprd, TACNULLOperand);
	}
	else
	{
		TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_SUB, expr.res_oprd, expr.res_oprd, TACNULLOperand);
	}
	expr.ins.end->c.oper_type = TAC_oper_type_constint;
	if (offset >= 0)
	{
		expr.ins.end->c.data.cint = offset;
	}
	else
	{
		expr.ins.end->c.data.cint = -offset;
	}
}

void TACPtrMakeExprOffset(TExpr& expr, TExpr& offset, int unit_size, int backward)
{
	__cond2value(offset);
	__2tmpVar(expr);
	__valueNOconst(expr, var_type_int);

	__2tmpVar(offset);
	__valueNOconst(offset, var_type_int);

	int last = 0;
	int now = 0;

	TACInstructionListJoin(expr.ins, offset.ins, expr.ins);

	while (unit_size != 0)
	{
		if (unit_size & 1)
		{
			if (now != last)
			{
				TACInstructionListBackAddBlank(expr.ins);
				TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_SHL , offset.res_oprd, offset.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, backward ? TAC_OP_SUB : TAC_OP_ADD, expr.res_oprd, expr.res_oprd, offset.res_oprd);

			last = now;
		}
		unit_size /= 2;
		now ++;
	}
}

void TACFindArrayAddr(TExpr& expr1, TExpr& expr2, TExpr& expr)
{
	__cond2value(expr2);
	__valueNOptr(expr2);

	expr = expr1;
	if (SymbolListType[expr.var_type].type_number == type_number_array)
	{
		__varADDref(expr);
	}
	else
	{
		__valueNOptr(expr);
	}
//	printf ("Take arraysub, to %s\n", expr.var_type >= 0 ? IDHash_int2ID(expr.var_type).c_str() : "basic");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -