📄 typesets.c
字号:
if (isconst(e2->Type))
EiC_castconst(e2, e1, 0);
else
EiC_castvar(e2, e1, 0);
EiC_output(e2);
} else if (!EiC_compatibletypes(e1->Type, e2->Type))
EiC_error("Mixed pointer operation");
EiC_output(e2);
switch (oper) {
case '-':
EiC_generate(&e2->Code, subptr, &e2->Val, 0);
VAL.ival = EiC_get_sizeof(nextType(e1->Type));
if (VAL.ival > 1) {
int size = VAL.ival;
VAL.ival = 1;
EiC_generate(&e2->Code, bump, &VAL, 0);
VAL.ival = size;
EiC_generate(&e2->Code, pushint, &VAL, 0);
EiC_generate(&e2->Code, divint, &VAL, 0);
}
break;
case LT:
EiC_generate(&e2->Code, ltptr, &e2->Val, 0);
break;
case LE:
EiC_generate(&e2->Code, leptr, &e2->Val, 0);
break;
case EQ:
EiC_generate(&e2->Code, eqptr, &e2->Val, 0);
break;
case NE:
EiC_generate(&e2->Code, neptr, &e2->Val, 0);
break;
case GT:
EiC_generate(&e2->Code, gtptr, &e2->Val, 0);
break;
case GE:
EiC_generate(&e2->Code, geptr, &e2->Val, 0);
break;
}
EiC_output(e1);
EiC_freetype(e1->Type);
e1->Type = EiC_addtype(t_int, NULL);
}
#undef ConstPval
void (*compatable(LRset_t S[],
unsigned n, unsigned left,
unsigned right)) ()
{
static int i, m;
if(left > 32 || right > 32)
return NULL;
for (i = 0; i < n; i++)
if (ismem(S[i].Lset, left) && ismem(S[i].Rset, right)) {
m = left > right ? left : right;
return BINFUN[m];
}
return NULL;
}
int EiC_bin_validate(unsigned oper, token_t * e1, token_t * e2)
{
int i, left, right;
void (*f) (int op, token_t * e1, token_t * e2);
if(sizeof(int) == sizeof(long)) {
if(EiC_gettype(e1->Type) == t_uint)
EiC_exchtype(t_ulong,e1->Type);
if(EiC_gettype(e2->Type) == t_uint)
EiC_exchtype(t_ulong,e2->Type);
}
if(isconst(e1->Type) || isconst(e2->Type)) {
binhconst(oper,e1,e2);
return 1;
}
left = EiC_gettype(e1->Type);
right = EiC_gettype(e2->Type);
for (i = 0; i < sizeof(BINSET) / sizeof(Binset); i++)
if (oper == BINSET[i].oper) {
f = compatable(BINSET[i].LRset,
BINSET[i].N,
left, right);
if (f != NULL) {
(*f) (oper, e1, e2);
return 1;
} else
EiC_error("Incompatible types");
}
return 0;
}
void EiC_cast2comm(token_t * e1, token_t * e2)
{
/* cast e1 and e2 to a common type */
unsigned t1, t2;
t1 = EiC_gettype(e1->Type);
t2 = EiC_gettype(e2->Type);
if(isconst(e1->Type)) {
if(t1 > t2) {
if(isconst(e2->Type))
EiC_castconst(e2, e1, 0);
else
EiC_castvar(e2, e1, 0);
} else
EiC_castconst(e1, e2, 0);
return;
}
switch (t1) {
CASE_NUM:
if(t2 == t_array || t2 == t_pointer ||
t2 == t_pointer)
EiC_error("Illegal cast operation");
else {
if(t1 > t2) {
if(isconst(e2->Type))
EiC_castconst(e2,e1,0);
else
EiC_castvar(e2,e1,0);
} else
EiC_castvar(e1,e2,0);
}
break;
case t_pointer:
if (!EiC_sametypes(e1->Type, e2->Type)) {
if (isconst(e2->Type))
EiC_castconst(e2, e1, 0);
}
break;
case t_array:
if (EiC_gettype(e2->Type) == t_pointer) {
if (!EiC_sametypes(nextType(e1->Type), nextType(e2->Type)))
EiC_warningerror("Suspicious pointer conversion");
EiC_exchtype(t_pointer, e1->Type);
} else
EiC_error("Illegal cast operation");
break;
case t_union:
case t_struct:
if(EiC_sametypes(e1->Type,e2->Type))
break;
default:
if(!EiC_sametypes(e1->Type,e2->Type))
EiC_error("Illegal cast operation");
}
}
int EiC_unaryop(token_t * e1, int op)
{
void derefConst(token_t * e1);
int t;
if (!isconst(e1->Type) && op != INC && op != DEC)
EiC_output(e1);
if(!e1->Pflag && isconst(e1->Type)) {
switch(op) {
case '-':
switch (EiC_gettype(e1->Type)) {
CASE_INT:
e1->Val.ival = -e1->Val.ival;
break;
CASE_UINT:
e1->Val.uival = -e1->Val.uival;
break;
CASE_LONG:
e1->Val.lval = -e1->Val.lval;
break;
case t_ulong:
e1->Val.lval = -e1->Val.ulval;
break;
CASE_FLOAT:
e1->Val.dval = -e1->Val.dval;
break;
default:
EiC_error("Illegal operand");
}
break;
case '~':
switch (EiC_gettype(e1->Type)) {
CASE_INT:
e1->Val.ival = ~e1->Val.ival; break;
CASE_UINT:
e1->Val.uival = ~e1->Val.uival;
EiC_exchtype(t_uint,e1->Type);
setConst(e1->Type);
break;
CASE_LONG:
e1->Val.lval = ~e1->Val.lval; break;
case t_ulong:
e1->Val.ulval = ~e1->Val.ulval;
EiC_exchtype(t_ulong,e1->Type);
setConst(e1->Type);
break;
default:
EiC_error("Illegal operand");
}
break;
case NOT:
switch (EiC_gettype(e1->Type)) {
CASE_INT: CASE_UINT:
e1->Val.ival = !e1->Val.ival;
break;
CASE_LONG:
case t_ulong:
e1->Val.ival = !e1->Val.lval;
break;
CASE_FLOAT:e1->Val.ival = !e1->Val.dval;
break;
case t_pointer:
e1->Val.ival = !e1->Val.p.p;
break;
default:
EiC_error("Illegal operand");
}
e1->Type = EiC_addtype(t_int, EiC_freetype(e1->Type));
setConst(e1->Type);
return 1;
case '*':
derefConst(e1);
break;
case '+':
break;
default:
EiC_error("Illegal unary opertion");
}
return 1;
}
switch (op) {
case '+':
break;
case '-':
switch ((t =EiC_gettype(e1->Type))) {
case t_char:
case t_uchar:
case t_short:
case t_ushort:
case t_int:
if(t != t_int)
EiC_exchtype(t_int,e1->Type);
EiC_generate(&e1->Code, negint, &e1->Val, 0);
break;
case t_uint:
EiC_generate(&e1->Code, neguint, &e1->Val, 0);
break;
CASE_LONG:
EiC_generate(&e1->Code, neglong, &e1->Val, 0);
break;
case t_ulong:
EiC_generate(&e1->Code, negulong, &e1->Val, 0);
break;
CASE_FLOAT:
EiC_generate(&e1->Code, negdouble, &e1->Val, 0);
break;
default:
EiC_error("Illegal operand");
}
break;
case '~':
switch ((t=EiC_gettype(e1->Type))) {
CASE_INT: CASE_UINT:
if(t < t_uint)
EiC_exchtype(t_uint,e1->Type);
EiC_generate(&e1->Code, compint, &e1->Val, 0);
break;
CASE_LONG:
case t_ulong:
EiC_generate(&e1->Code, compulong, &e1->Val, 0);
EiC_exchtype(t_ulong,e1->Type);
break;
default:
EiC_error("Illegal operand");
}
break;
case NOT:
switch (EiC_gettype(e1->Type)) {
CASE_INT: CASE_UINT:
EiC_generate(&e1->Code, notint, &e1->Val, 0);
break;
CASE_LONG:
case t_ulong:
EiC_generate(&e1->Code, notlong, &e1->Val, 0);
break;
CASE_FLOAT:EiC_generate(&e1->Code, notdouble, &e1->Val, 0);
break;
case t_lval:
t = EiC_gettype(e1->Type);
e1->Type = EiC_succType(e1->Type);
EiC_unaryop(e1, op);
e1->Type = EiC_addtype(t, e1->Type);
break;
case t_pointer:
EiC_generate(&e1->Code, notptr, &e1->Val, 0);
break;
default:
EiC_error("Illegal operand");
}
e1->Type = EiC_addtype(t_int, EiC_freetype(e1->Type));
break;
case INC:
case DEC:
if(isconstp(e1->Type) || isconst(e1->Type)) {
if(op == INC)
EiC_error("increment of read-only variable %s",e1->Sym->id);
else
EiC_error("decrement of read-only variable %s",e1->Sym->id);
}
EiC_do_inc_dec(e1, op);
e1->Pflag = 0;
EiC_do_stooutput(e1);
break;
case '*':
if((t = EiC_gettype(e1->Type)) == t_pointer || t == t_array) {
e1->Pflag = 0;
EiC_exchtype(t_lval, e1->Type);
if(nextType(e1->Type) && (!isconstp(nextType(e1->Type)) ||
!isconst(nextType(e1->Type))))
unsetConst(e1->Type);
} else if(t != t_lval)
EiC_error("Must have pointer");
return 1;
default:
EiC_error(" Invalid unary assignment");
break;
}
return 1;
}
int do_binaryop(token_t * e1, token_t * e2, int op)
{
int t1 = EiC_gettype(e1->Type);
int t2 = EiC_gettype(e2->Type);
if(t1 == t_pointer || t2 == t_pointer) {
if(!(op >= LT && op <= GE)) {
EiC_binhlval(op,e1,e2);
return 1;
}
}
if (t1 > t2)
EiC_castconst(e2, e1, 0);
else
EiC_castconst(e1, e2, 0);
switch (EiC_gettype(e1->Type)) {
CASE_FLOAT:
switch (op) {
case '*':
e1->Val.dval *= e2->Val.dval;
break;
case '/':
e1->Val.dval /= e2->Val.dval;
break;
case '+':
e1->Val.dval += e2->Val.dval;
break;
case '-':
e1->Val.dval -= e2->Val.dval;
break;
default:
EiC_set_bastype(t_int, e1->Type);
switch (op) {
case LT:
e1->Val.ival = e1->Val.dval < e2->Val.dval;
break;
case LE:
e1->Val.ival = e1->Val.dval <= e2->Val.dval;
break;
case EQ:
e1->Val.ival = e1->Val.dval == e2->Val.dval;
break;
case NE:
e1->Val.ival = e1->Val.dval != e2->Val.dval;
break;
case GT:
e1->Val.ival = e1->Val.dval > e2->Val.dval;
break;
case GE:
e1->Val.ival = e1->Val.dval >= e2->Val.dval;
break;
default: EiC_error("illegal binary operation to `%c'", op);
}
break;
}
break;
CASE_INT:
switch (op) {
case '*':
e1->Val.ival *= e2->Val.ival;
break;
case '/':
e1->Val.ival /= e2->Val.ival;
break;
case '+':
e1->Val.ival += e2->Val.ival;
break;
case '-':
e1->Val.ival -= e2->Val.ival;
break;
case '%':
e1->Val.ival %= e2->Val.ival;
break;
case LSHT:
e1->Val.ival <<= e2->Val.ival;
break;
case RSHT:
e1->Val.ival >>= e2->Val.ival;
break;
case AND:
e1->Val.ival = e1->Val.ival & e2->Val.ival;
break;
case BOR:
e1->Val.ival = e1->Val.ival | e2->Val.ival;
break;
case XOR:
e1->Val.ival = e1->Val.ival ^ e2->Val.ival;
break;
case LT:
e1->Val.ival = e1->Val.ival < e2->Val.ival;
break;
case LE:
e1->Val.ival = e1->Val.ival <= e2->Val.ival;
break;
case EQ:
e1->Val.ival = e1->Val.ival == e2->Val.ival;
break;
case NE:
e1->Val.ival = e1->Val.ival != e2->Val.ival;
break;
case GT:
e1->Val.ival = e1->Val.ival > e2->Val.ival;
break;
case GE:
e1->Val.ival = e1->Val.ival >= e2->Val.ival;
break;
}
break;
CASE_UINT:
switch (op) {
case '*':
e1->Val.uival *= e2->Val.uival;
break;
case '/':
e1->Val.uival /= e2->Val.uival;
break;
case '+':
e1->Val.uival += e2->Val.uival;
break;
case '-':
e1->Val.uival -= e2->Val.uival;
break;
case '%':
e1->Val.uival %= e2->Val.uival;
break;
case LSHT:
e1->Val.uival <<= e2->Val.uival;
break;
case RSHT:
e1->Val.uival >>= e2->Val.uival;
break;
case AND:
e1->Val.uival = e1->Val.uival & e2->Val.uival;
break;
case BOR:
e1->Val.uival = e1->Val.uival | e2->Val.uival;
break;
case XOR:
e1->Val.uival = e1->Val.uival ^ e2->Val.uival;
break;
default:
EiC_set_bastype(t_int, e1->Type);
switch (op) {
case LT:
e1->Val.ival = e1->Val.uival < e2->Val.uival;
break;
case LE:
e1->Val.ival = e1->Val.uival <= e2->Val.uival;
break;
case EQ:
e1->Val.ival = e1->Val.uival == e2->Val.uival;
break;
case NE:
e1->Val.ival = e1->Val.uival != e2->Val.uival;
break;
case GT:
e1->Val.ival = e1->Val.uival > e2->Val.uival;
break;
case GE:
e1->Val.ival = e1->Val.uival >= e2->Val.uival;
break;
}
break;
}
break;
CASE_LONG:
switch (op) {
case '*':
e1->Val.lval *= e2->Val.lval;
break;
case '/':
e1->Val.lval /= e2->Val.lval;
break;
case '+':
e1->Val.lval += e2->Val.lval;
break;
case '-':
e1->Val.lval -= e2->Val.lval;
break;
case '%':
e1->Val.lval %= e2->Val.lval;
break;
case LSHT:
e1->Val.lval <<= e2->Val.lval;
break;
case RSHT:
e1->Val.lval >>= e2->Val.lval;
break;
case AND:
e1->Val.lval = e1->Val.lval & e2->Val.lval;
break;
case BOR:
e1->Val.lval = e1->Val.lval | e2->Val.lval;
break;
case XOR:
e1->Val.lval = e1->Val.lval ^ e2->Val.lval;
break;
default:
EiC_set_bastype(t_int, e1->Type);
switch (op) {
case LT:
e1->Val.ival = e1->Val.lval < e2->Val.lval;
break;
case LE:
e1->Val.ival = e1->Val.lval <= e2->Val.lval;
break;
case EQ:
e1->Val.ival = e1->Val.lval == e2->Val.lval;
break;
case NE:
e1->Val.ival = e1->Val.lval != e2->Val.lval;
break;
case GT:
e1->Val.ival = e1->Val.lval > e2->Val.lval;
break;
case GE:
e1->Val.ival = e1->Val.lval >= e2->Val.lval;
break;
}
break;
}
break;
case t_ulong:
switch (op) {
case '*':
e1->Val.ulval *= e2->Val.ulval;
break;
case '/':
e1->Val.ulval /= e2->Val.ulval;
break;
case '+':
e1->Val.ulval += e2->Val.ulval;
break;
case '-':
e1->Val.ulval -= e2->Val.ulval;
break;
case '%':
e1->Val.ulval %= e2->Val.ulval;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -