📄 syntax.c
字号:
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 + -