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

📄 syntax.c

📁 用C++编写的一个编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
			generror(ERR_TYPE_CONFLICT, NULL);
			break;
		}

		res->datatype =  exp->datatype;
		if(exp->exptype == exp_const)
		{
			res->exptype = exp_const;
			if(exp->datatype->basic_type == bt_double)
				res->val.f = -exp->val.f;
			else 
				res->val.i = -exp->val.i;
		}
		else 
		{
			res->val.opd[1] = exp;
		}
		break;
		
	case exp_lnot:
	
		if(!is_real(exp->datatype->basic_type)
			&& !(exp->datatype->basic_type == bt_pointer 
			&& exp->datatype->array_vol == 0))
		{	
			generror(ERR_TYPE_CONFLICT, NULL);
			break;
		}
		
		res->datatype = newType(NULL, bt_long, NULL);
		
		if(exp->exptype == exp_const)
		{
			res->exptype = exp_const;
			if(exp->val.f == 0)
				res->val.i = 0;
			else 
				res->val.i = 1;
		}
		else
			res->val.opd[1] = exp;
		

		break;
	case exp_rvs:
		if(!is_integer(exp->datatype->basic_type))
		{	
			generror(ERR_TYPE_CONFLICT, NULL);
			break;
		}
		
		res->datatype = exp->datatype;
		
		if(exp->exptype == exp_const)
		{
			res->exptype = exp_const;
			res->val.i = ~res->val.i;
		}
		else
			res->val.opd[1] = exp;
		break;
	}
	return res;
}
double get_float(int bt, void * value)
{
	if(bt == bt_long )
		return *((long*)value);
	else if(bt == bt_unsignedlong)
		return *((unsigned long*)value);
	else if(bt == bt_double)
		return *((double*)value);
	else 
		generror(ERR_TYPE_CONFLICT, NULL);
	return 1;
}
//the type promotion in C
//here we just take care of int to float
 
struct _expnode *promote_type(
	struct _expnode *exp
)
{
	ExpNode *res;
	if(is_integer(exp->datatype->basic_type))
	{
		res = newInitExp(exp_itof);
		res->datatype = newType(NULL, bt_double, NULL);
		res->val.opd[1] = exp;
		return res;
	}
	else if(!is_float(exp->datatype->basic_type))
 		generror(ERR_TYPE_CONFLICT, NULL);
	return exp;
}
int toUnsigned(int exptype)
{
	switch(exptype)
	{
	case exp_mul:
		return exp_umul;
	case exp_div:
		return exp_udiv;
	case exp_mod:
		return exp_umod;
	case exp_les:
		return exp_ules;
	case exp_leq:
		return exp_uleq;
	case exp_gtr:
		return exp_ugtr;
	case exp_geq:
		return exp_ugeq;
	default:
		return exptype;
	}
}
struct _expnode *evaluate_binary_exp(
	int exptype,
	struct _expnode *left,
	struct _expnode *right
)
{
	ExpNode *res = newInitExp(exptype), *tmpexp;
	bool float_flag = false, pointer_flag = false;
	double l, r;
	struct _expnode *pointer, *offset;
	
	if((exptype == exp_mod || exptype == exp_lsh || exptype == exp_rsh)
	 && !is_integer(left->datatype->basic_type) 
	 && !is_integer(right->datatype->basic_type))
	{
	 	generror(ERR_TYPE_CONFLICT, NULL);
		return res;
	}
	else if((exptype == exp_mul || exptype == exp_div)
	 &&	!is_real(left->datatype->basic_type) 
	 && !is_real(right->datatype->basic_type))
	{	
		generror(ERR_TYPE_CONFLICT, NULL);
		return res;
	}
	else if(!(is_real(left->datatype->basic_type)||left->datatype->basic_type == bt_pointer)
	 && !(is_real(left->datatype->basic_type) ||right->datatype->basic_type == bt_pointer))
	{
		generror(ERR_TYPE_CONFLICT, NULL);
		return res;
	}
	else if(left->datatype->basic_type == bt_pointer
	 && right->datatype->basic_type == bt_pointer) 
	{
		generror(ERR_TYPE_CONFLICT, NULL);
		return res;
	}
	

	float_flag = (is_float(left->datatype->basic_type)
		||is_float(right->datatype->basic_type));

	if(left->datatype->basic_type == bt_pointer)
	{
		pointer_flag = true;
		pointer=left;
		offset=right;
	}
	else if(right->datatype->basic_type == bt_pointer)
	{
		pointer_flag = true;
		pointer=right;
		offset=left;
	}
	if(pointer_flag)
	{
		if(pointer->datatype->subtype->size == UNKNOWN)
		{
			generror(ERR_UNKNOWN_SIZE, "type pointed");
			return res;
		}
		else if(pointer->datatype->subtype->size == 0)
		{
			generror(ERR_ZERO_SIZE, "type pointed");
			return res;
		}
	}

	if(left->exptype==exp_const && right->exptype == exp_const)
	{
		res->exptype = exp_const;
		if(float_flag)
		{
			res->datatype = newType(NULL, bt_double, NULL);
			l = get_float(left->datatype->basic_type, &left->val);
			r = get_float(right->datatype->basic_type, &right->val);
			switch(exptype)
			{
			case exp_mul:
				res->val.f= l*r;
				break;
			case exp_div:
				res->val.f= l/r;
				break;
			case exp_add:
				res->val.f= l+r;
				break;
			case exp_sub:
				res->val.f = l-r;
				break;	
			}
		}
		else if(pointer_flag)
		{
			res->datatype = pointer->datatype;
			res->val.addr = pointer->val.addr;
			if(exptype == exp_add)
				res->val.addr.offset += pointer->datatype->subtype->size
					*offset->val.i;
			else
				res->val.addr.offset -= pointer->datatype->subtype->size
					*offset->val.i;

		}
		else
		{
			res->datatype = newType(NULL, bt_long, NULL);
			switch(exptype)
			{
			case exp_mul:
				res->val.i = left->val.i*right->val.i;
				break;
			case exp_div:
				res->val.i = left->val.i/right->val.i;
				break;
			case exp_mod:
				res->val.i = left->val.i%right->val.i;
				break;
			case exp_add:
				res->val.i = left->val.i+right->val.i;
				break;
			case exp_sub:
				res->val.i = left->val.i-right->val.i;
				break;
			case exp_lsh:
				res->val.i = left->val.i<<right->val.i;
				break;
			case exp_rsh:
				res->val.i = left->val.i>>right->val.i;
				break;
			}
		}
	}
	else
	{
		if(float_flag)
		{
			res->datatype = newType(NULL, bt_double, NULL);
			res->val.opd[0] = promote_type(left);
			res->val.opd[1] = promote_type(right);
		}
		else if(pointer_flag)
		{
			res->datatype = pointer->datatype;
			res->val.opd[0]=pointer;//so pointer are always on the left
			if(pointer->datatype->subtype->size>1)
			{
				tmpexp = evaluate_const_exp(bt_long, &(pointer->datatype->subtype->size));
				res->val.opd[1]=evaluate_binary_exp(exp_mul, tmpexp, offset);
			}
			else
				res->val.opd[1]=offset;
		}
		else 
		{
			res->datatype = newType(NULL, bt_long, NULL);
			res->val.opd[0] = left;
			res->val.opd[1] = right;
			if(is_unsigned(left->datatype->basic_type)
				||is_unsigned(right->datatype->basic_type))
			{
				res->datatype->basic_type = bt_unsignedlong;
				res->exptype = toUnsigned(res->exptype);
			}
		}
	}
	return res;
}

struct _expnode *evaluate_cmp_exp(
	int exptype,
	struct _expnode *left,
	struct _expnode *right
)
{
	ExpNode *res = newInitExp(exptype);
	bool float_flag;
	double l, r;
	if(!is_real(left->datatype->basic_type) 
	 && !is_real(right->datatype->basic_type))
	{	
		generror(ERR_TYPE_CONFLICT, NULL);
		return res;
	}
	
	float_flag = (is_float(left->datatype->basic_type)
		||is_float(right->datatype->basic_type));
	res->datatype = newType(NULL, bt_long, NULL);
	if(left->exptype==exp_const && right->exptype == exp_const)
	{
		res->exptype = exp_const;
		l = get_float(left->datatype->basic_type, &left->val);
		r = get_float(right->datatype->basic_type, &right->val);
		switch(exptype)
		{
		case exp_eq:
			res->val.i = l == r;
			break;
		case exp_ueq:
			res->val.i = l != r;
			break;
		case exp_gtr:
			res->val.i = l > r;
			break;
		case exp_geq:
			res->val.i = l >= r;
			break;
		case exp_les:
			res->val.i = l < r;
			break;
		case exp_leq:
			res->val.i = l <= r;
			break;
		}
	}
	else
	{
		if(float_flag)
		{
			res->val.opd[0] = promote_type(left);
			res->val.opd[1] = promote_type(right);
		}
		else 
		{
			res->val.opd[0] = left;
			res->val.opd[1] = right;
			if(is_unsigned(left->datatype->basic_type)
				||is_unsigned(right->datatype->basic_type))
				res->exptype = toUnsigned(res->exptype);
		}
	}
	return res;
}

struct _expnode *evaluate_bit_exp(
	int exptype,
	struct _expnode *left,
	struct _expnode *right
)
{
	ExpNode *res = newInitExp(exptype);

	if(!is_integer(left->datatype->basic_type) 
	 && !is_integer(right->datatype->basic_type))
	{	
		generror(ERR_TYPE_CONFLICT, NULL);
		return res;
	}

	res->datatype = newType(NULL, bt_long, NULL);
	if(left->exptype==exp_const && right->exptype == exp_const)
	{
		res->exptype = exp_const;
		switch(exptype)
		{
		case exp_and:
			res->val.i = left->val.i & right->val.i;
			break;
		case exp_xor:
			res->val.i = left->val.i ^ right->val.i;
			break;
		case exp_or:
			res->val.i = left->val.i | right->val.i;
			break;
		}
	}
	else
	{
		res->val.opd[0] = left;
		res->val.opd[1] = right;
	}
	return res;
}

struct _expnode *evaluate_logic_exp(
	int exptype,
	struct _expnode *left,
	struct _expnode *right
)
{
	ExpNode *res = newInitExp(exptype);

	if(!is_real(left->datatype->basic_type)
		&& !(left->datatype->basic_type == bt_pointer 
		&& left->datatype->array_vol == 0))
	{	
		generror(ERR_TYPE_CONFLICT, NULL);
		return res;
	}
	if(!is_real(right->datatype->basic_type)
		&& !(right->datatype->basic_type == bt_pointer 
		&& right->datatype->array_vol == 0))
	{	
		generror(ERR_TYPE_CONFLICT, NULL);
		return res;
	}

	res->datatype = newType(NULL, bt_long, NULL);
	if(left->exptype==exp_const && right->exptype == exp_const)
	{
		res->exptype = exp_const;
		switch(exptype)
		{
		case exp_land:
			res->val.i = left->val.f && right->val.f;
			break;
		case exp_lor:
			res->val.i = left->val.f || right->val.f;
			break;
		}
	}
	else
	{
		res->val.opd[0] = left;
		res->val.opd[1] = right;
	}
	return res;
}

struct _expnode *evaluate_trinary_exp(
	struct _expnode *judge,
	struct _expnode *left,
	struct _expnode *right
)
{
	//????
	ExpNode *res = newInitExp(exp_trinary);
	if(checkTypeSame(left->datatype, right->datatype)>1)
	{
		generror(ERR_TYPE_CONFLICT, "the two optional expression");
		return NULL;
	}
	res->datatype=left->datatype;
	res->val.opd[0]=judge;
	res->val.opd[1]=newInitExp(exp_lor);
	res->val.opd[1]->val.opd[0]=left;
	res->val.opd[1]->val.opd[1]=right;
	return res;
}

struct _expnode *evaluate_assign_exp(
	int exptype,
	struct _expnode *left,
	struct _expnode *right
)
{
	ExpNode *res = newInitExp(exptype);
	res->datatype = left->datatype;
	res->val.opd[0] = left;
	res->val.opd[1] = right;
	
	//just simple assignment here, no time to support lots 
	if(checkTypeSame(left->datatype, right->datatype)>1)
		generror(ERR_TYPE_CONFLICT, NULL);
	//???????type promote
	return res;
}

⌨️ 快捷键说明

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