📄 expr.c
字号:
//-------------------------------------------------------------------------
void promote_type(TYP *typ, ENODE **node)
/*
* Type promotion for casts and function args
*/
{
if (typ->type == bt_ref)
typ = typ->btp;
switch (typ->type)
{
case bt_bool:
*node = makenode(en_cbool, *node, 0);
break;
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_int:
*node = makenode(en_ci, *node, 0);
break;
case bt_long:
*node = makenode(en_cl, *node, 0);
break;
case bt_unsigned:
*node = makenode(en_cui, *node, 0);
break;
case bt_unsignedlong:
*node = makenode(en_cul, *node, 0);
break;
case bt_float:
*node = makenode(en_cf, *node, 0);
break;
case bt_fcomplex:
*node = makenode(en_cfc, *node, 0);
break;
case bt_rcomplex:
*node = makenode(en_crc, *node, 0);
break;
case bt_lrcomplex:
*node = makenode(en_clrc, *node, 0);
break;
case bt_fimaginary:
*node = makenode(en_cfi, *node, 0);
break;
case bt_rimaginary:
*node = makenode(en_cri, *node, 0);
break;
case bt_lrimaginary:
*node = makenode(en_clri, *node, 0);
break;
case bt_double:
*node = makenode(en_cd, *node, 0);
break;
case bt_longdouble:
*node = makenode(en_cld, *node, 0);
break;
case bt_longlong:
*node = makenode(en_cll, *node, 0);
break;
case bt_unsignedlonglong:
*node = makenode(en_cull, *node, 0);
break;
case bt_farpointer:
*node = makenode(en_cfp, *node, 0);
break;
case bt_segpointer:
*node = makenode(en_csp, *node, 0);
break;
default:
*node = makenode(en_cp, *node, 0);
break;
}
(*node)->cflags = typ->cflags;
}
//-------------------------------------------------------------------------
TYP *gatherparms(ENODE **node, int isvoid)
/*
* 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;
int odf = global_deref;
SYM **t = &tbl.head, *newt;
TYP *tp;
char buf[256];
int ogc = goodcode;
parsing_params = TRUE;
parm_ns_counts[parm_ns_level] = 0;
tbl.tail = tbl.head = 0;
goodcode |= DF_FUNCPARMS;
goodcode &= ~GF_INIF;
global_deref = 0;
strcpy(buf, declid);
if (lastst == closepa || isvoid)
{
if (prm_cplusplus)
tbl.head = tbl.tail = (SYM*) - 1;
else
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);
tp = &stdint;
ep2 = makenode(en_icon, 0, 0);
} else
opt4(&ep2);
ep2->cflags = tp->cflags;
if (tp->bits != - 1)
{
ep2 = makenode(en_bits, ep2, 0);
ep2->bits = tp->bits;
ep2->startbit = tp->startbit;
}
newt = makesym(sc_auto);
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();
else
break;
}
if (!isvoid)
needpunc(closepa, skm_closepa);
tp = maketype(bt_func, 0);
tp->val_flag = NORMARRAY;
tp->btp = &stdint;
tp->lst = tbl;
tp->bits = - 1;
tp->startbit = - 1;
tp->uflags = UF_DEFINED | UF_USED;
goodcode = ogc;
*node = ep1;
global_deref = odf;
strcpy(declid, buf);
parsing_params = FALSE;
parm_ns_level++;
return tp;
}
//-------------------------------------------------------------------------
int checkparmconst(TYP *tp /*right*/, TYP *tpi /*left*/)
/*
* Check the CONST flags for parameters
*/
{
if (tpi->type != bt_pointer && tpi->type != bt_farpointer && tpi->type !=
bt_ref)
return 0;
tpi = tpi->btp;
if (tp->type == bt_pointer || tp->type == bt_farpointer || tp->type ==
bt_ref)
tp = tp->btp;
while ((tp->type == bt_pointer || tp->type == bt_farpointer || tp->type ==
bt_ref) && !tp->val_flag && (!tpi || tpi->type == bt_pointer || tpi
->type == bt_farpointer))
{
if ((tp->cflags &DF_CONST) && (!tpi || !(tpi->cflags &DF_CONST)))
{
if (prm_cplusplus)
generror(ERR_MODCONS, 0, 0);
else
generror(ERR_SUSPICIOUSCONST, 0, 0);
return 1;
}
tp = tp->btp;
if (tpi)
tpi = tpi->btp;
}
#ifdef XXXXX
if ((tp->cflags &DF_CONST) && (!tpi || !(tpi->cflags &DF_CONST)))
{
if (prm_cplusplus)
generror(ERR_MODCONS, 0, 0);
else
generror(ERR_SUSPICIOUSCONST, 0, 0);
return 1;
}
#endif
return 0;
}
//-------------------------------------------------------------------------
ENODE *copynode(ENODE *node)
/*
* copy the node passed into a new enode so it wont get
* corrupted during substitution.
*/
{
ENODE *temp;
if (node == 0)
return 0;
temp = xalloc(sizeof(ENODE));
temp->cflags = node->cflags;
temp->nodetype = node->nodetype;
temp->v.p[0] = node->v.p[0];
temp->v.p[1] = node->v.p[1];
return temp;
}
//-------------------------------------------------------------------------
ENODE *copy_enode(ENODE *node)
{
/*
* routine takes an enode tree and replaces it with a copy of itself.
* Used because we have to munge the block_nesting field (value.i) of each
* sp in an inline function to force allocation of the variables
*/
ENODE *temp;
if (node == 0)
return 0;
temp = xalloc(sizeof(ENODE));
memcpy(temp, node, sizeof(ENODE));
switch (temp->nodetype)
{
case en_structret:
case en_tempref:
break;
case en_autoreg:
case en_autocon:
case en_rcon:
case en_lrcon:
case en_fcon:
case en_fcomplexcon:
case en_rcomplexcon:
case en_lrcomplexcon:
case en_fimaginarycon:
case en_rimaginarycon:
case en_lrimaginarycon:
case en_icon:
case en_lcon:
case en_iucon:
case en_lucon:
case en_boolcon:
case en_ccon:
case en_cucon:
case en_nacon:
case en_absacon:
case en_napccon:
case en_llcon:
case en_llucon:
case en_labcon:
case en_nalabcon:
break;
case en_fp_ref:
case en_fimaginaryref:
case en_rimaginaryref:
case en_lrimaginaryref:
case en_fcomplexref:
case en_rcomplexref:
case en_lrcomplexref:
case en_cfi:
case en_cri:
case en_clri:
case en_cfc:
case en_crc:
case en_clrc:
case en_bits:
case en_floatref:
case en_doubleref:
case en_longdoubleref:
case en_ll_ref:
case en_ull_ref:
case en_b_ref:
case en_w_ref:
case en_ul_ref:
case en_l_ref:
case en_ub_ref:
case en_uw_ref:
case en_i_ref:
case en_ui_ref:
case en_a_ref: case en_ua_ref:
case en_bool_ref:
case en_uminus:
case en_asuminus:
case en_ascompl:
case en_compl:
case en_not:
case en_cf:
case en_cd:
case en_cld:
case en_cb:
case en_cub:
case en_cbool:
case en_cw:
case en_cuw:
case en_cll:
case en_cull:
case en_cl:
case en_cul:
case en_ci:
case en_cui:
case en_cp:
case en_cfp:
case en_csp:
case en_trapcall:
case en_cl_reg:
case en_movebyref:
case en_substack:
temp->v.p[0] = copy_enode(node->v.p[0]);
break;
case en_asadd:
case en_assub:
case en_add:
case en_sub:
case en_addstruc:
en_addcast: case en_asalsh:
case en_asarsh:
case en_alsh:
case en_arsh:
case en_arshd:
case en_asarshd:
case en_asmul:
case en_asdiv:
case en_asmod:
case en_aslsh:
case en_asumod:
case en_asudiv:
case en_asumul:
case en_asrsh:
case en_asand:
case en_assign:
case en_refassign:
case en_lassign:
case en_asor:
case en_asxor:
case en_callblock:
case en_pcallblock:
case en_scallblock:
case en_void:
case en_dvoid:
case en_pmul:
case en_arrayindex:
case en_pdiv:
case en_mul:
case en_div:
case en_umul:
case en_udiv:
case en_umod:
case en_lsh:
case en_rsh:
case en_mod:
case en_and:
case en_or:
case en_xor:
case en_lor:
case en_land:
case en_eq:
case en_ne:
case en_gt:
case en_ge:
case en_lt:
case en_le:
case en_ugt:
case en_uge:
case en_ult:
case en_ule:
case en_cond:
case en_intcall:
case en_moveblock:
case en_stackblock:
case en_fcall:
case en_fcallb:
case en_pfcall:
case en_pfcallb:
case en_sfcall:
case en_sfcallb:
case en_thiscall:
case en_repcons:
case en_ainc:
case en_adec:
case en_array:
temp->v.p[1] = copy_enode(node->v.p[1]);
case en_clearblock:
temp->v.p[0] = copy_enode(node->v.p[0]);
break;
case en_conslabel:
case en_destlabel:
temp->v.p[0] = copy_enode(node->v.p[0]);
temp->v.p[1] = copy_enode(node->v.p[1]);
break;
default:
DIAG("copy_enode: Unknown nodetype");
break;
}
return temp;
}
//-------------------------------------------------------------------------
ENODE *copy_default(ENODE *node)
{
/*
* routine takes an enode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -