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

📄 tacsupport.cpp

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