📄 stmt.c
字号:
void dodefaultinit(SYM *sp)
/*
* Evalueate a C++ default clause
*/
{
TYP *tp;
ENODE *ep;
char nm[256];
if (lastst == assign)
{
indefaultinit = TRUE;
strcpy(nm, declid);
expr_runup[expr_updowncount] = 0;
expr_rundown[expr_updowncount++] = 0;
if ((tp = autoasnop(&ep, sp, TRUE)) == 0)
{
generror(ERR_EXPREXPECT, 0, 0);
getsym();
expr_updowncount--;
}
else
{
ep = ep->v.p[1];
if (sp->tp->type == bt_ref)
if (ep->nodetype == en_refassign && (isintconst(ep->v.p[1]
->nodetype) && ep->v.p[1]->v.i != 0 || isfloatconst(ep
->v.p[1]->nodetype)))
generror(ERR_REFLVALUE, 0, 0);
sp->value.classdata.defalt = xalloc(sizeof(DEFVALUE));
sp->value.classdata.defalt->ep = ep;
sp->value.classdata.defalt->cons = expr_runup[
--expr_updowncount];
sp->value.classdata.defalt->dest =
expr_rundown[expr_updowncount];
}
strcpy(declid, nm);
indefaultinit = FALSE;
}
}
void evaluateVLAtypedef(SYM *sp)
{
TYP *tp = sp->tp;
if (tp->type == bt_pointer && !(tp->val_flag & VARARRAY))
tp = tp->btp;
if (tp->val_flag & VARARRAY)
{
TYP *tp1 = tp->btp;
while (tp1->esize)
{
if (!funcnesting) {
// DIAG("evaluateVLAtypedef: global typedef to VLA") ;
} else
{
ENODE *ep1 = dummyvar(stdintsize, &stdint, 0);
ENODE *ep2;
SNODE *snp = xalloc(sizeof(SNODE));
ep1->v.sp->value.i = 1;
ep1 = makenode(en_a_ref, ep1, 0);
ep2 = makenode(en_assign, ep1, tp1->esize);
tp1->esize = ep1;
snp->next = 0;
snp->stype = st_expr;
snp->exp = ep2;
snp->flags |= ST_VARARRAY ;
if (cbautoinithead == 0)
cbautoinithead = cbautoinittail = snp;
else
{
cbautoinittail->next = snp;
cbautoinittail = snp;
}
}
tp1 = tp1->btp;
}
}
}
ENODE *createVarArray(SYM *sp, TYP *tp, int global, int alloc)
{
TYP *list[100];
int i;
ENODE *ep, *ep1, *result = 0;
int count = 0;
if (tp->type == bt_pointer && (tp->val_flag &VARARRAY))
{
TYP *tp1 = tp->btp;
enum e_node sv = global ? en_nacon : en_autocon;
while (tp1->esize)
{
if (tp1->esize == (ENODE*) - 1)
{
tp1->esize = list[count++] = makeintnode(en_icon, 1);
generror(ERR_VLAMUSTSIZE, 0, 0);
}
else
list[count++] = tp1->esize;
tp1->esizeindex = (count + 1); // replace with index in table
tp1->sp = sp;
tp1 = tp1->btp;
}
list[count++] = makeintnode(en_icon, tp1->size);
ep = makeintnode(en_icon, count - 1);
ep1 = makenode(sv, (void*)sp, 0);
ep1 = makenode(en_add, makeintnode(en_icon, stdaddrsize), ep1);
ep1 = makenode(en_a_ref, ep1, 0);
result = makenode(en_assign, ep1, ep);
ep = list[count - 1];
ep1 = makenode(sv, (void*)sp, 0);
ep1 = makenode(en_add, makeintnode(en_icon, stdaddrsize + count *
stdintsize), ep1);
ep1 = makenode(en_a_ref, ep1, 0);
result = makenode(en_void, result, makenode(en_assign, ep1, ep));
for (i = count - 2; i >= 0; i--)
{
ENODE *ep2 = makenode(sv, (void*)sp, 0);
ep2 = makenode(en_add, makeintnode(en_icon, stdaddrsize + (i + 2)
*stdintsize), ep2);
ep2 = makenode(en_a_ref, ep2, 0);
ep = list[i];
ep = makenode(en_mul, ep, ep2);
ep1 = makenode(sv, (void*)sp, 0);
ep1 = makenode(en_add, makeintnode(en_icon, stdaddrsize + (i + 1)
*stdintsize), ep1);
ep1 = makenode(en_a_ref, ep1, 0);
result = makenode(en_void, result, makenode(en_assign, ep1, ep));
}
if (alloc)
{
ep = makenode(sv, (void*)sp, 0);
ep = makenode(en_add, ep, makeintnode(en_icon, stdaddrsize +
stdintsize));
ep = makenode(en_a_ref, ep, 0);
if (global)
{
ENODE *ep2 = makenode(en_napccon, (void*)global_vararray_func,
0);
global_vararray_func->mainsym->extflag = TRUE;
ep1 = makenode(en_void, ep, 0);
ep1 = makenode(en_void, ep1, 0);
ep2 = makenode(en_void, ep2, ep2);
ep1 = makenode(en_void, ep2, ep1);
ep1 = makenode(en_fcall, makeintnode(en_icon, stdaddrsize), ep1);
}
else
{
ep1 = makenode(en_substack, ep, 0);
}
ep = makenode(sv, (void*)sp, 0);
ep = makenode(en_a_ref, ep, 0);
ep1 = makenode(en_assign, ep, ep1);
result = makenode(en_void, result, ep1);
}
return result;
}
return 0;
}
//-------------------------------------------------------------------------
void doautoinit(SYM *sym)
/*
* This is here rather than in init because autoinit is a type of
* statement
*/
{
TYP *tp;
#ifdef XXXXX
if (prm_cplusplus && sym->storage_class != sc_static && sym
->storage_class != sc_global && (sym->tp->type == bt_class ||
sym->tp->type == bt_struct))
{
SNODE *snp = 0, *snp1;
ENODE *exp;
SYM *typesp = sym->tp->sp;
// if (lastst == openpa || lastst == assign) {
snp = snp_line(TRUE);
if (snp)
if (cbautoinithead == 0)
cbautoinithead = cbautoinittail = snp;
else
{
cbautoinittail->next = snp;
cbautoinittail = snp;
}
basedecl(&exp, sym);
if (exp)
{
snp = xalloc(sizeof(SNODE));
snp->next = 0;
snp->stype = st_expr;
snp->exp = exp;
if (snp)
if (cbautoinithead == 0)
cbautoinithead = cbautoinittail = snp;
else
{
cbautoinittail->next = snp;
cbautoinittail = snp;
}
}
// }
if (!(typesp->value.classdata.cppflags &PF_HASCONS) && typesp
->value.classdata.baseclass->vtabsp)
{
ENODE *exp = makenode(en_nacon, typesp
->value.classdata.baseclass->vtabsp, 0);
ENODE *exp1, *exp2, *exp3;
CLASSLIST *l = typesp->value.classdata.baseclass;
if (sym->absflag)
exp1 = makenode(en_absacon, sym, 0);
else if (sym->storage_class == sc_auto)
exp1 = makenode(en_autocon, sym, 0);
else
exp1 = makenode(en_nacon, sym, 0);
while (l)
{
if (l->flags &CL_VTAB)
{
exp3 = makenode(en_addstruc, exp1, makeintnode
(en_icon, l->offset));
exp3 = makenode(en_a_ref, exp3, 0);
exp2 = makenode(en_addstruc, exp, makeintnode
(en_icon, l->vtaboffs));
exp2 = makenode(en_assign, exp3, exp2);
if (snp)
snp->exp = makenode(en_void, exp2, snp->exp);
else
{
snp = xalloc(sizeof(SNODE));
snp->next = 0;
snp->stype = st_expr;
snp->exp = exp2;
if (cbautoinithead == 0)
cbautoinithead = cbautoinittail = snp;
else
{
cbautoinittail->next = snp;
cbautoinittail = snp;
}
}
}
l = l->link;
}
}
}
else
#endif
tp = sym->tp;
if (tp->type == bt_pointer && !(sym->tp->val_flag &VARARRAY))
tp = tp->btp;
if (tp->type == bt_pointer && (tp->val_flag &VARARRAY) && !infuncargs)
{
SNODE *snp = snp_line(TRUE);
ENODE *ep;
if (snp)
if (cbautoinithead == 0)
cbautoinithead = cbautoinittail = snp;
else
{
cbautoinittail->next = snp;
cbautoinittail = snp;
}
snp = xalloc(sizeof(SNODE));
snp->next = 0;
snp->stype = st_expr;
snp->exp = createVarArray(sym, tp, FALSE, tp == sym->tp);
snp->flags |= ST_VARARRAY ;
if (cbautoinithead == 0)
cbautoinithead = cbautoinittail = snp;
else
{
cbautoinittail->next = snp;
cbautoinittail = snp;
}
if (tp == sym->tp)
{
ep = makenode(en_autocon, (void*)sym, 0);
ep = makenode(en_add, ep, makeintnode(en_icon, stdaddrsize +
stdintsize));
ep = makenode(en_a_ref, ep, 0);
ep = makenode(en_uminus, ep, 0);
ep = makenode(en_substack, ep, 0);
if (block_rundown)
block_rundown = makenode(en_void, ep, block_rundown);
else
block_rundown = ep;
}
if (tp == sym->tp && lastst == assign || prm_cplusplus && lastst ==
openpa)
gensymerror(ERR_NOINIT, sym->name);
}
if (lastst == assign || prm_cplusplus && lastst == openpa)
{
SNODE *snp = snp_line(TRUE);
int s = lastst;
if (snp)
if (cbautoinithead == 0)
cbautoinithead = cbautoinittail = snp;
else
{
cbautoinittail->next = snp;
cbautoinittail = snp;
}
snp = xalloc(sizeof(SNODE));
snp->next = 0;
snp->stype = st_expr;
if (autoasnop(&(snp->exp), sym, FALSE) == 0)
{
generror(ERR_EXPREXPECT, 0, 0);
}
else
{
if (cbautoinithead == 0)
cbautoinithead = cbautoinittail = snp;
else
{
cbautoinittail->next = snp;
cbautoinittail = snp;
}
}
if (s == openpa)
needpunc(closepa, 0);
}
else if ((sym->tp->cflags &DF_CONST) && !(sym->tp->cflags &DF_FUNCPARMS) &&
!(sym->mainsym->constructed))
generror(ERR_CONSTMUSTINIT, 0, skm_declend);
}
//-------------------------------------------------------------------------
SNODE *compound(void)
/*
* Process the body of a compound block. Declarations are already
* handled by now.
*
*/
{
SNODE *head, *tail, *temp;
head = cbautoinithead;
tail = cbautoinittail;
cbautoinithead = 0;
goodcode &= ~(GF_RETURN | GF_BREAK | GF_CONTINUE | GF_GOTO | GF_THROW);
while (lastst != end && lastst != eof)
{
if (goodcode &(GF_RETURN | GF_BREAK | GF_CONTINUE | GF_GOTO | GF_THROW | GF_UNREACH))
if (lastst == id)
{
while (isspace(lastch))
getch();
if (lastch != ':')
generror(ERR_UNREACHABLE, 0, 0);
}
else
if (lastst != semicolon && lastst != kw_case && lastst != kw_default && lastst != kw_break)
generror(ERR_UNREACHABLE, 0, 0);
if (lastst != semicolon)
goodcode &= ~(GF_RETURN | GF_BREAK | GF_CONTINUE | GF_GOTO | GF_THROW | GF_UNREACH);
temp = statement();
if (head == 0)
head = tail = temp;
else
{
tail->next = temp;
}
if (head)
while (tail->next != 0)
tail = tail->next;
}
if (prm_ansi && lastlastst != semicolon && lastlastst != end)
generror(ERR_PUNCT, semicolon, 0);
funcendstmt = snp_line(TRUE);
if (lastst == eof)
generror(ERR_PUNCT, end, 0);
else
getsym();
return head;
}
//-------------------------------------------------------------------------
SNODE *labelstmt(int fetchnext)
/*
* labelstmt processes a label that appears before a
* statement as a seperate statement.
*/
{
SNODE *snp;
SYM *sp;
snp = xalloc(sizeof(SNODE));
snp->next = 0;
snp->stype = st_label;
goodcode &= ~GF_UNREACH;
if ((sp = search(lastid, &lsyms)) == 0)
{
sp = makesym(sc_label);
sp->name = litlate(lastid);
sp->tp = xalloc(sizeof(TYP));
sp->tp->type = bt_unsigned;
sp->tp->uflags = 0;
sp->tp->bits = sp->tp->startbit = - 1;
sp->value.i = nextlabel++;
insert(sp, &lsyms);
}
else
{
if (sp->storage_class != sc_ulabel)
gensymerror(ERR_DUPLABEL, sp->name);
else
sp->storage_class = sc_label;
}
getsym(); /* get past id */
needpunc(colon, 0);
if (sp->storage_class == sc_label)
{
snp->label = (SNODE*)sp->value.i;
snp->next = 0;
if (lastst != end && fetchnext && lastst != kw_case && lastst !=
kw_default)
snp->next = statement();
return snp;
}
return 0;
}
//-------------------------------------------------------------------------
SNODE *gotostmt(void)
/*
* gotostmt processes the goto statement and puts undefined
* labels into the symbol table.
*/
{
SNODE *snp;
SYM *sp;
getsym();
if (lastst != id)
{
generror(ERR_IDEXPECT, 0, 0);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -