📄 expr.c
字号:
if (tp2->type != bt_matchall)
break;
}
case bt_matchall:
if( tp2->type == bt_matchall)
return(&stdint);
else if( tp2->type == bt_pointer)
return tp2;
else if (allowpointers && (tp2->type == bt_pointer || tp2->type == bt_ptrfunc))
return &stdint;
else if (isscalar(tp2))
if (max)
return(maxsize(tp1,tp2));
else
return(tp1);
break;
case bt_pointer:
if (!prm_cplusplus && !max && (tp2->type == bt_short || tp2->type == bt_unsignedshort
|| tp2->type == bt_char || tp2->type == bt_unsignedchar)) {
error = ERR_SHORTPOINTER;
break;
}
if( tp2->type == bt_pointer ||tp2->type == bt_ptrfunc) {
if (allowpointers) {
while (tp1->type == bt_pointer && tp2->type == bt_pointer) {
tp1 = tp1->btp;
tp2 = tp2->btp;
}
if (tp1->type != tp2 ->type || tp1->size != tp2->size)
if (tp1->type != bt_void && tp2->type != bt_void)
generror(ERR_SUSPICIOUS,0,0);
return &stdint;
}
else
return tp1;
}
if (!prm_cplusplus && isscalar(tp2))
if (max)
return(maxsize(tp1,tp2));
else
return(tp1);
break;
case bt_enum:
case bt_unsignedshort:
case bt_short:
if (isintconst((*node2)->nodetype)) {
if (!max && ((*node2)->v.i < -65536L || ((*node2)->v.i > 65535L))) {
error = ERR_LOSTCONV;
break;
}
return tp1;
}
else
if (!max && (tp2->type == bt_long || tp2->type == bt_unsigned || (!prm_cplusplus && (tp2->type == bt_pointer) || tp2->type == bt_ptrfunc))) {
error = ERR_LOSTCONV;
break;
}
if (allowpointers && tp2->type == bt_pointer)
return &stdint;
else if (isscalar(tp2))
if (max)
return(maxsize(tp1,tp2));
else
return(tp1);
break;
case bt_char:
case bt_unsignedchar:
if (isintconst((*node2)->nodetype)) {
if (!max && ((*node2)->v.i < -256 || ((*node2)->v.i > 255))) {
error = ERR_LOSTCONV;
break;
}
return tp1;
}
else
if (!max && (tp2->type == bt_long || tp2->type == bt_unsigned || ( !prm_cplusplus && tp2->type == bt_pointer)
|| tp2->type == bt_short || tp2->type == bt_unsignedshort)) {
error = ERR_LOSTCONV;
break;
}
if (allowpointers && (tp2->type == bt_pointer || tp2->type == bt_ptrfunc))
return &stdint;
else if (isscalar(tp2))
if (max)
return(maxsize(tp1,tp2));
else
return(tp1);
break;
case bt_float:
case bt_double:
case bt_longdouble:
if (isscalar(tp2))
return(tp1);
break;
case bt_unsigned:
if (isintconst((*node1)->nodetype)) {
if (isscalar(tp2) || (!prm_cplusplus && tp2->type == bt_pointer))
return tp2;
break;
}
if( !prm_cplusplus && (tp2->type == bt_pointer || tp2->type == bt_ptrfunc))
if (allowpointers)
return &stdint;
else
return tp2;
if (isscalar(tp2))
return tp2;
break;
case bt_ptrfunc:
if (!prm_cplusplus && (tp2->type == bt_short || tp2->type == bt_unsignedshort
|| tp2->type == bt_char || tp2->type == bt_unsignedchar)) {
error = ERR_SHORTPOINTER;
break;
}
if (tp2->type == bt_pointer)
tp3 = tp2->btp;
else
tp3 = tp2;
if (tp3->type == bt_func || tp3->type == bt_ifunc || tp3->type == bt_ptrfunc
|| (!prm_cplusplus && tp2->type == bt_pointer))
if (allowpointers)
return &stdint;
else
return tp1;
break;
case bt_func:
case bt_ifunc:
if (tp2->type == bt_func || tp2->type == bt_ifunc)
return tp1;
break;
}
#ifdef CPLUSPLUS
if (error == ERR_MISMATCH && prm_cplusplus)
genmismatcherror(tp2,tp1);
else
#endif
generror( error,0,0 );
return tp1;
}
int isscalar(TYP *tp)
/*
* this is misnamed... it checks for ANY basic numeric type
*/
{ return tp->type == bt_char || tp->type == bt_unsignedchar ||
tp->type == bt_short || tp->type == bt_unsignedshort ||
tp->type == bt_long || tp->type == bt_unsigned || tp->type == bt_enum
|| tp->type == bt_float || tp->type == bt_double || tp->type == bt_longdouble;
}
void checknp(TYP *tp1,TYP*tp2,ENODE *ep1, ENODE *ep2)
/*
* look for non-portable pointer conversions
*/
{
#ifdef CPLUSPLUS
if (prm_cplusplus)
return;
#endif
if (tp1->type == bt_pointer || tp2->type == bt_pointer)
if (tp1->type != tp2->type)
if ((!isintconst(ep1->nodetype) || ep1->v.i != 0) && (!isintconst(ep2->nodetype) || ep2->v.i != 0))
generror(ERR_NONPORT,0,0);
}
TYP *multops(ENODE **node)
/*
* multops parses the multiply priority operators. the syntax of
* this group is:
*
* unary
* multop * unary
* multop / unary
* multop % unary
*/
{ ENODE *ep1, *ep2;
TYP *tp1, *tp2;
int oper;
tp1 = unary(&ep1);
if( tp1 == 0 )
return 0;
while( lastst == star || lastst == divide || lastst == modop ) {
oper = lastst;
getsym(); /* move on to next unary op */
tp2 = unary(&ep2);
goodcode &= ~GF_ASSIGN;
if( tp2 == 0 ) {
generror(ERR_IDEXPECT,0,0);
*node = ep1;
return tp1;
}
tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,FALSE);
switch( oper ) {
case star:
if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
ep1 = makenode(en_umul,ep1,ep2);
else
ep1 = makenode(en_mul,ep1,ep2);
break;
case divide:
if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
ep1 = makenode(en_udiv,ep1,ep2);
else
ep1 = makenode(en_div,ep1,ep2);
break;
case modop:
if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
ep1 = makenode(en_umod,ep1,ep2);
else
ep1 = makenode(en_mod,ep1,ep2);
floatcheck(ep1);
break;
}
}
*node = ep1;
return tp1;
}
TYP *addops(ENODE **node)
/*
* addops handles the addition and subtraction operators.
*/
{ ENODE *ep1, *ep2, *ep3;
TYP *tp1, *tp2;
int oper;
tp1 = multops(&ep1);
if( tp1 == 0 )
return 0;
while( lastst == plus || lastst == minus ) {
oper = (lastst == plus);
getsym();
tp2 = multops(&ep2);
goodcode &= ~GF_ASSIGN;
if( tp2 == 0 ) {
generror(ERR_IDEXPECT,0,0);
*node = ep1;
return tp1;
}
if( tp1->type == bt_pointer ) {
if (tp2->type == bt_pointer) {
forcefit(&ep1,tp1,&ep2,tp2,TRUE,FALSE);
ep1 = makenode( oper ? en_add : en_sub,ep1,ep2);
ep1->cflags = ep1->v.p[0]->cflags | ep2->cflags;
if (tp1->btp->size == 0)
generror(ERR_ZEROPTR,0,0);
else
if (tp1->btp->size > 1)
ep1 = makenode(en_pdiv,ep1,makenode(en_icon,(char *)tp1->btp->size,0));
ep1->cflags = ep1->v.p[0]->cflags;
tp1 = &stdint;
continue;
}
else {
tp2 = forcefit(0,&stdint,&ep2,tp2,TRUE,FALSE);
if (tp1->btp->size == 0)
generror(ERR_ZEROPTR,0,0);
ep3 = makenode(en_icon,(char *)tp1->btp->size,0);
ep2 = makenode(en_pmul,ep3,ep2);
ep2->cflags = ep2->v.p[1]->cflags;
}
}
else if( tp2->type == bt_pointer ) {
tp1 = forcefit(0,&stdint,&ep1,tp1,TRUE,FALSE);
if (tp2->btp->size == 0)
generror(ERR_ZEROPTR,0,0);
ep3 = makenode(en_icon,(char *)tp2->btp->size,0);
ep1 = makenode(en_pmul,ep3,ep1);
ep1->cflags = ep1->v.p[1]->cflags;
}
tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,FALSE);
ep1 = makenode( oper ? en_add : en_sub,ep1,ep2);
ep1->cflags = ep1->v.p[1]->cflags | ep2->cflags;
}
exit:
*node = ep1;
return tp1;
}
TYP *shiftop(ENODE **node)
/*
* shiftop handles the shift operators << and >>.
*/
{ ENODE *ep1, *ep2;
TYP *tp1, *tp2;
int oper;
tp1 = addops(&ep1);
if( tp1 == 0)
return 0;
while( lastst == lshift || lastst == rshift) {
oper = (lastst == lshift);
getsym();
tp2 = addops(&ep2);
goodcode &= ~GF_ASSIGN;
if( tp2 == 0 )
generror(ERR_IDEXPECT,0,0);
else {
tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,FALSE);
if (tp1->type == bt_unsigned ||
tp1->type == bt_unsignedchar ||
tp1->type == bt_unsignedshort)
ep1 = makenode(oper ? en_lsh : en_rsh,ep1,ep2);
else
ep1 = makenode(oper ? en_alsh : en_arsh,ep1,ep2);
}
floatcheck(ep1);
}
*node = ep1;
return tp1;
}
TYP *relation(ENODE **node)
/*
* relation handles the relational operators < <= > and >=.
*/
{ ENODE *ep1, *ep2;
TYP *tp1, *tp2;
int nt;
tp1 = shiftop(&ep1);
if( tp1 == 0 )
return 0;
for(;;) {
switch( lastst ) {
case lt:
if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
nt = en_ult;
else
nt = en_lt;
break;
case gt:
if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
nt = en_ugt;
else
nt = en_gt;
break;
case leq:
if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
nt = en_ule;
else
nt = en_le;
break;
case geq:
if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
nt = en_uge;
else
nt = en_ge;
break;
default:
goto fini;
}
getsym();
tp2 = shiftop(&ep2);
goodcode &= ~GF_ASSIGN;
if( tp2 == 0 )
generror(ERR_IDEXPECT,0,0);
else {
checknp(tp1,tp2,ep1,ep2);
tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,TRUE);
ep1 = makenode(nt,ep1,ep2);
}
}
fini: *node = ep1;
return tp1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -