📄 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 ConstPvalvoid (*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 + -