📄 expr.c
字号:
{
switch (typ->type) {
case bt_char:
*node = makenode(en_cb,*node,0);
break;
case bt_unsignedchar:
*node = makenode(en_cub,*node,0);
break;
case bt_enum:
case bt_short:
*node = makenode(en_cw,*node,0);
break;
case bt_unsignedshort:
*node = makenode(en_cuw,*node,0);
break;
case bt_long:
*node = makenode(en_cl,*node,0);
break;
case bt_unsigned:
*node = makenode(en_cul,*node,0);
break;
case bt_float:
*node = makenode(en_cf,*node,0);
break;
case bt_double:
*node = makenode(en_cd,*node,0);
break;
case bt_longdouble:
*node = makenode(en_cld,*node,0);
break;
default:
*node = makenode(en_cp,*node,0);
break;
}
(*node)->cflags = typ->cflags;
}
TYP *gatherparms( ENODE **node)
/*
* create a type tree and primary parameter list for a function
*
* At this point the parameter list is backwards from what codegen
* needs!
*/
{
ENODE *ep1 = 0,*ep2=0,**ep3 = &ep1;
TABLE tbl;
SYM **t = &tbl.head,*newt;
TYP *tp;
int ogc = goodcode;
tbl.tail = tbl.head = 0;
goodcode |= DF_FUNCPARMS;
if (lastst == closepa) {
#ifdef CPLUSPLUS
if (prm_cplusplus)
tbl.head=tbl.tail=(SYM *)-1;
else
#endif
tbl.head=tbl.tail = 0;
}
else if (lastst == kw_void)
tbl.head = tbl.tail = (SYM *)-1;
else
while (lastst != closepa) {
tp = exprnc(&ep2);
if (!tp) {
generror(ERR_EXPREXPECT,0,0);
break;
}
ep2->cflags = tp->cflags;
newt = xalloc(sizeof(SYM));
newt->tp = tp;
newt->next = 0;
newt->name = 0;
*t = newt;
t = &newt->next;
tbl.tail = newt;
*ep3 = makenode(en_void,ep2,0);
ep3 = &(*ep3)->v.p[1];
if (lastst == comma)
getsym();
}
needpunc(closepa,skm_closepa);
tp = maketype(bt_func,0);
tp->btp = &stdint;
tp->lst = tbl;
tp->bits = -1;
tp->startbit = -1;
tp->uflags = UF_DEFINED | UF_USED;
goodcode = ogc;
*node = ep1;
return tp;
}
void checkparmconst(TYP *tp, TYP *tpi)
/*
* Check the CONST flags for parameters
*/
{
if (tpi->type != bt_pointer && tpi->type != bt_ref)
return;
while ((tp->type == bt_pointer || tp->type == bt_ref)&& !tp->val_flag && (!tpi || tpi->type == bt_pointer || tpi->type == bt_ref)) {
if ((tp->cflags & DF_CONST) && (!tpi || !(tpi->cflags & DF_CONST)))
generror(ERR_MODCONS,0,0);
tp = tp->btp;
tpi = tpi->btp;
}
if ((tp->cflags & DF_CONST) && (!tpi || !(tpi->cflags & DF_CONST)))
generror(ERR_MODCONS,0,0);
}
void parmlist(ENODE **node, TYP *tpi, TYP *tp)
/*
* take the primary type and node trees, the function argument expectations,
* and check for type mismatch errors
*
* also reverse the primary node tree so the parms will be ready for
* code generation
*/
{ ENODE *ep1=0,*ep2=0,*ep3=*node;
SYM *spi=tpi->lst.head,*sp=0;
TYP *tp2;
int matching = FALSE;
if (tp)
sp=tp->lst.head;
if (tp && !sp)
gensymerror(ERR_NOPROTO,tpi->sname);
if (!prm_cplusplus && sp && sp != (SYM *)-1 && sp->tp->type != bt_ellipse)
matching = TRUE;
while (TRUE) {
if (!spi || spi == (SYM *)-1){
if (sp == (SYM *) -1)
break;
if (sp && sp->tp->type != bt_ellipse)
if (!sp->defalt)
genfuncerror(ERR_CALLLENSHORT,tpi->sname,0);
else
while (sp && sp != (SYM *)-1) {
if (sp->tp->val_flag && (sp->tp->type == bt_struct || sp->tp->type == bt_union)) {
ep1 = makenode(en_stackblock,sp->defalt,ep1);
sp->defalt->size = sp->tp->size;
}
else
ep1 = makenode(en_void,sp->defalt,ep1);
sp = sp->next;
}
break;
}
else {
ep2 = ep3->v.p[0];
ep3 = ep3->v.p[1];
if (matching) {
if (!sp || sp == (SYM *)-1) {
genfuncerror(ERR_CALLLENLONG,tpi->sname,0);
break;
}
else {
checkparmconst(spi->tp,sp->tp);
if (!checktype(spi->tp,sp->tp))
if (isscalar(sp->tp) && isscalar(spi->tp))
promote_type(sp->tp,&ep2);
else
if (sp->tp->type == bt_pointer) {
if (isintconst(ep2->nodetype)) {
if (ep2->v.i != 0)
generror(ERR_NONPORT,0,0);
}
else if (spi->tp->type != bt_pointer)
genfuncerror(ERR_CALLMISMATCH,tpi->sname,sp->name);
}
else genfuncerror(ERR_CALLMISMATCH,tpi->sname,sp->name);
}
}
}
if (sp && sp->tp->type == bt_ref) {
if (lvalue(ep2)) {
while (castvalue(ep2))
ep2 = ep2->v.p[0];
ep2 = ep2->v.p[0];
}
else {
ENODE *x;
tp2 = sp->tp->btp;
genfuncerror(ERR_TEMPUSED,tpi->sname,sp->name);
ep2 = makenode(en_refassign,dummyvar(tp2->size,tp2),ep2);
}
}
if (spi && spi != (SYM *) -1 && spi->tp->val_flag && (spi->tp->type == bt_struct || spi->tp->type == bt_union)) {
ep1 = makenode(en_stackblock,ep2,ep1);
ep2->size = sp->tp->size;
}
else
ep1 = makenode(en_void,ep2,ep1);
spi = spi->next;
if (sp && sp != (SYM *)-1) {
sp = sp->next;
if (sp && sp->tp->type == bt_ellipse)
matching = FALSE;
}
}
if (tp)
promote_type(tp->btp,&ep1);
else
promote_type(tpi->btp,&ep1);
*node = ep1;
}
int floatrecurse(ENODE *node)
/*
* Go through a node and see if it will be promoted to type FLOAT
*/
{
if (!node)
return 0;
switch (node->nodetype) {
case en_rcon:
case en_lrcon:
case en_fcon:
case en_doubleref:
case en_longdoubleref:
case en_floatref:
case en_cld:
case en_cd:
case en_cf:
return 1;
case en_labcon: case en_trapcall:
case en_nacon: case en_autocon: case en_autoreg: case en_nalabcon:
case en_l_ref: case en_tempref: case en_napccon: case en_absacon:
case en_cl: case en_regref:
case en_ul_ref:
case en_cul:
case en_cp:
case en_icon:
case en_lcon: case en_iucon: case en_lucon: case en_ccon:
case en_bits:
case en_ub_ref:
case en_cub:
case en_b_ref:
case en_cb:
case en_uw_ref:
case en_cuw:
case en_cw:
case en_w_ref:
case en_eq: case en_ne:
case en_lt: case en_le:
case en_gt: case en_ge:
case en_ugt: case en_uge: case en_ult: case en_ule:
return 0;
case en_fcall: case en_pfcall:
case en_fcallb: case en_pfcallb:
case en_callblock:
return(floatrecurse(node->v.p[1]));
case en_not: case en_compl:
case en_uminus:
case en_ainc: case en_adec:
case en_moveblock: case en_stackblock:
return floatrecurse(node->v.p[0]);
case en_refassign: case en_assign:
case en_add: case en_sub:
case en_umul: case en_udiv: case en_umod: case en_pmul:
case en_mul: case en_div:
case en_mod: case en_and:
case en_or: case en_xor:
case en_asalsh: case en_asarsh: case en_alsh: case en_arsh:
case en_lsh: case en_rsh:
case en_land: case en_lor:
case en_asadd: case en_assub:
case en_asmul: case en_asdiv:
case en_asmod: case en_asand:
case en_asumod: case en_asudiv: case en_asumul:
case en_asor: case en_aslsh: case en_asxor:
case en_asrsh:
return(floatrecurse(node->v.p[0]) || floatrecurse(node->v.p[1]));
case en_void: case en_cond:
return floatrecurse(node->v.p[1]);
}
return(0);
}
void floatcheck(ENODE *node)
/*
* Error if node will be promoted to type float
*/
{
if (floatrecurse(node))
generror(ERR_INVFLOAT,0,0);
}
int castbegin(int st)
/*
* return 1 if st in set of [ kw_char, kw_short, kw_long, kw_int,
* kw_float, kw_double, kw_struct, kw_union, kw_float, or is typedef ]
*/
{
SYM *sp;
switch(st) {
case kw_void:
case kw_char: case kw_short: case kw_int: case kw_long:
case kw_float: case kw_double:
case kw_struct: case kw_union: case kw_signed:
case kw_unsigned: case kw_volatile: case kw_const:
return 1;
default:
if (st != id)
return 0;
}
nm = lastid;
sp = gsearch(lastid);
if (!sp)
sp = search(lastid,&lsyms);
if (sp && sp->storage_class == sc_type)
return 1 ;
return 0;
}
int tostring()
{
short string[2048];
int st = lastst;
string[0] = 0;
while (lastst == st) {
if (st == lsconst) {
if (pstrlen(string) +pstrlen(laststr) > 2040)
generror(ERR_STRINGTOOBIG,0,0);
else
pstrcat(string,laststr);
}
else {
if (strlen(string) +strlen(laststr) > 4090)
generror(ERR_STRINGTOOBIG,0,0);
else
strcat(string,laststr);
}
getsym();
}
return(stringlit(string,st == lsconst));
}
TYP *primary(ENODE **node)
/*
* primary will parse a primary expression and set the node pointer
* returning the type of the expression parsed. primary expressions
* are any of:
* id
* constant
* string
* ( expression )
* primary++
* primary--
* primary[ expression ]
* primary.id
* primary->id
* primary( parameter list )
* (* expression)( parameter list )
* (typecast)primary
* (typecast)(unary)
*/
{ ENODE *pnode, *qnode, *rnode;
SYM *sp=0;
TYP *tptr,*tp1,*tp2;
int flag = 0;
int gcode,gdf;
int isstring = FALSE;
switch( lastst ) {
/* This trap thing should be in stmt.c */
case kw__trap:
getsym();
if (needpunc(openpa,0)) {
long num = intexpr(0);
if (num > 15 || num < 0)
generror(ERR_INVTRAP,0,0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -