📄 expr.c
字号:
case openpa: /* function reference */
/* this SHOULD have been handled in nameref rather than here. However
* there are some weird cases like putting function names in parenthesis
* or in hook expressions, so this has to be here too.
*/
flag = 1;
if (isstring)
generror(ERR_INVALIDSTRING,0,0);
if( tptr->type != bt_func &&
tptr->type != bt_ifunc && tptr->type != bt_ptrfunc) {
gensymerrorexp(ERR_NOFUNC,nm);
expskim(skm_closepa);
}
else {
#ifdef CPLUSPLUS
if (prm_cplusplus && !strcmp(nm,"main"))
generror(ERR_NOMAIN,0,0);
#endif
if (!sp && tptr->sname)
sp=gsearch(tptr->sname);
if (tptr->type == bt_ptrfunc)
tptr = deref(&pnode,tptr);
getsym();
tp1 =gatherparms(&qnode);
parmlist(&qnode,tp1,tptr);
rnode = makenode(en_icon,(char *)tptr->btp->size,0);
pnode = makenode(en_void,pnode,qnode);
tptr = tptr->btp;
if (sp && sp->intflag)
pnode = makenode(en_intcall,rnode,pnode);
else
if (tptr->type == bt_union || tptr->type == bt_struct) {
if (lastsym && lastsym->pascaldefn)
pnode = makenode(en_pfcallb,rnode,pnode);
else
pnode = makenode(en_fcallb,rnode,pnode);
pnode->size = tptr->size;
}
else
if (lastsym && lastsym->pascaldefn)
pnode = makenode(en_pfcall,rnode,pnode);
else
pnode = makenode(en_fcall,rnode,pnode);
if (tptr)
pnode->cflags = tptr->cflags;
}
goodcode |= GF_ASSIGN;
break;
default:
goto fini;
}
}
fini: *node = pnode;
/* symbol level error checking */
if (!flag && !isstring && !(goodcode & GF_AND) && lastsym && tptr->type != bt_func && tptr->type != bt_ifunc
&&!tptr->val_flag && lastsym->storage_class != sc_type
&& lastsym->storage_class != sc_static && lastsym->storage_class != sc_global
&& lastsym->storage_class != sc_external && lastsym->storage_class != sc_externalfunc) {
if (!(lastsym->tp->uflags & UF_DEFINED) && lastst != assign
&&lastst != asplus && lastst != asminus && lastst != astimes
&& lastst!= asdivide && lastst != asmodop && lastst != asrshift
&& lastst != aslshift && lastst != asor && lastst != asxor && lastst != asand) {
gensymerror(ERR_SYMUNDEF,lastsym->name);
lastsym->tp->uflags |= UF_DEFINED;
}
lastsym->tp->uflags &= ~UF_ASSIGNED;
}
return tptr;
}
int castvalue(ENODE *node)
/*
* See if this is a cast operator */
{
switch(node->nodetype) {
case en_cb: case en_cub: case en_bits:
case en_cw: case en_cuw:
case en_cl: case en_cul:
case en_cf: case en_cd: case en_cp: case en_cld:
return 1;
}
return 0;
}
int lvalue(ENODE *node)
/* See if this is an lvalue; that is has it been dereferenced?
*/
{
if (!prm_cplusplus) {
while (castvalue(node))
node = node->v.p[0];
}
switch( node->nodetype ) {
case en_b_ref:
case en_w_ref:
case en_l_ref:
case en_ub_ref:
case en_uw_ref:
case en_ul_ref:
case en_floatref:
case en_doubleref:
case en_longdoubleref:
return 1;
case en_bits:
return lvalue(node->v.p[0]);
}
return 0;
}
TYP *unary(ENODE **node)
/*
* unary evaluates unary expressions and returns the type of the
* expression evaluated. unary expressions are any of:
*
* primary
* ++unary
* --unary
* !unary
* ~unary
* &unary
* -unary
* *unary
* sizeof(typecast)
*
*/
{ TYP *tp,*tp1;
ENODE *ep1, *ep2;
int flag, i,gdf;
flag = 0;
switch( lastst ) {
case autodec:
flag = 1;
/* fall through to common increment */
case autoinc:
getsym();
gdf = globaldref;
globaldref = 0;
tp = unary(&ep1);
globaldref = gdf;
if( tp == 0 ) {
generror(ERR_IDEXPECT,0,0);
return 0;
}
goodcode |= GF_ASSIGN;
if( lvalue(ep1)) {
if( tp->type == bt_pointer ) {
if (tp->btp->size == 0)
generror(ERR_ZEROPTR,0,0);
ep2 = makenode(en_icon,(char *)tp->btp->size,0);
}
else
ep2 = makenode(en_icon,(char *)1,0);
if (ep1->cflags & DF_CONST)
generror(ERR_MODCONS,0,0);
ep1 = makenode(flag ? en_assub : en_asadd,ep1,ep2);
}
else {
generror(ERR_LVALUE,0,0);
return(0);
}
break;
case minus:
case plus: {
int stt = lastst;
getsym();
gdf = globaldref;
globaldref = 0;
tp = unary(&ep1);
globaldref = gdf;
goodcode &= ~GF_ASSIGN;
if( tp == 0 ) {
generror(ERR_IDEXPECT,0,0);
return 0;
}
if (stt == minus)
ep1 = makenode(en_uminus,ep1,0);
}
break;
case not:
getsym();
gdf = globaldref;
globaldref = 0;
tp = unary(&ep1);
globaldref = gdf;
goodcode &= ~GF_ASSIGN;
if( tp == 0 ) {
generror(ERR_IDEXPECT,0,0);
return 0;
}
ep1 = makenode(en_not,ep1,0);
break;
case compl:
getsym();
gdf = globaldref;
globaldref = 0;
tp = unary(&ep1);
globaldref = gdf;
goodcode &= ~GF_ASSIGN;
if( tp == 0 ) {
generror(ERR_IDEXPECT,0,0);
return 0;
}
floatcheck(ep1);
ep1 = makenode(en_compl,ep1,0);
break;
case star:
getsym();
gdf = globaldref;
globaldref = 0;
tp = unary(&ep1);
globaldref = gdf;
goodcode &= ~GF_ASSIGN;
if( tp == 0 ) {
generror(ERR_IDEXPECT,0,0);
return 0;
}
if( tp->btp == 0 ) {
generror(ERR_DEREF,0,0);
}
else
if (tp->btp->type != bt_void)
tp = tp->btp;
ep1->cflags = tp->cflags;
if( tp->val_flag == 0 )
tp = deref(&ep1,tp);
break;
case and:
getsym();
if (!(goodcode & GF_INFUNCPARMS))
goodcode |= GF_AND;
gdf = globaldref;
globaldref = 0;
tp = unary(&ep1);
globaldref = gdf;
goodcode &= ~GF_AND;
goodcode &= ~GF_ASSIGN;
if( tp == 0 ) {
generror(ERR_IDEXPECT,0,0);
return 0;
}
else
if (tp->startbit != -1)
generror(ERR_BFADDR,0,0);
else if (tp->cflags & DF_AUTOREG)
gensymerror(ERR_NOANDREG,tp->sname);
else if (tp->type == bt_pointer && tp->val_flag && !(goodcode & GF_SUPERAND))
generror(ERR_SUPERAND,0,0);
if( lvalue(ep1)) {
ep1 = ep1->v.p[0];
if (ep1->nodetype == en_regref)
gensymerror(ERR_NOANDREG,tp->sname);
}
tp1 = xalloc(sizeof(TYP));
tp1->size = 4;
tp1->type = bt_pointer;
tp1->btp = tp;
tp1->val_flag = 0;
tp1->lst.head = 0;
tp1->sname = 0;
tp = tp1;
break;
case kw_sizeof:
getsym();
needpunc(openpa,0);
if (castbegin(lastst)) {
sizeof_cast:
decl(0);
decl1();
}
else if (lastst == id) {
SYM *sp = gsearch(lastid);
if (!sp)
sp = search(lastid,&lsyms);
if (sp) {
goto sizeof_primary;
}
if ((sp = search(nm,&tagtable)) != 0) {
head = sp->tp;
getsym();
}
else {
generror(ERR_SIZE,0,0);
head = 0;
}
}
else if (lastst == kw_enum) {
getsym();
if (lastst == id) {
SYM *sp;
if ((sp = search(nm,&tagtable)) != 0) {
head = sp->tp;
getsym();
}
else goto sizeof_primary;
}
}
else {
ENODE *node = 0;
sizeof_primary:
head = unary(&node);
}
if( head != 0 ) {
if (head->size == 0)
generror(ERR_SIZE,0,0);
ep1 = makenode(en_icon,(char *)head->size,0);
}
else {
generror(ERR_IDEXPECT,0,0);
ep1 = makenode(en_icon,(char *)0,0);
}
goodcode &= ~GF_ASSIGN;
tp = &stdint;
needpunc(closepa,0);
break;
default:
tp = primary(&ep1);
break;
}
/* Dereference if necessary */
if (globaldref) {
globaldref = 0;
if (tp->type != bt_ptrfunc) {
if( tp == 0 ) {
generror(ERR_IDEXPECT,0,0);
return 0;
}
if( tp->btp == 0 ) {
generror(ERR_DEREF,0,0);
}
else
if (tp->btp->type != bt_void)
tp = tp->btp;
ep1->cflags = tp->cflags;
if( tp->val_flag == 0 )
tp = deref(&ep1,tp);
}
}
*node = ep1;
return tp;
}
TYP *maxsize(TYP *tp1, TYP *tp2)
/*
* return the type that has the maximum size
*/
{
if (tp1->type > tp2->type)
return tp1;
return tp2;
}
TYP *forcefit(ENODE **node1,TYP *tp1,ENODE **node2,TYP *tp2, int max, int allowpointers)
/*
* compare two types and determine if they are compatible for purposes
* of the current operation. Return an appropriate type. Also checks for
* dangerous pointer conversions...
*/
{ int error = ERR_MISMATCH;
TYP *tp3;
switch( tp1->type ) {
case bt_void:
if (tp2->type != bt_void && tp2->type != bt_matchall)
break;
return tp1;
case bt_long:
if (isintconst((*node2)->nodetype)) {
if (isscalar(tp2) || (!prm_cplusplus && (tp2->type == bt_pointer || tp2 ->type == bt_ptrfunc)))
return tp2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -