📄 stmt.c
字号:
if (cc->last >= CASE_MAX) {
cc->next = xalloc(sizeof(struct caselist));
cc = cc->next;
}
cc->cases[cc->last++] = ssize;
}
if (cc)
cc = cc->next;
}
}
else // default
{
goodcode |= GF_DEF;
getsym();
snp->stype = st_case;
snp->s2 = (SNODE*)1;
if (hasdefault++) {
generror(ERR_HASDEF,0,0);
}
}
needpunc(colon, 0);
return snp;
}
//-------------------------------------------------------------------------
SNODE *switchstmt(void)
/*
* Handle the SWITCH statement
*/
{
SNODE *snp;
TYP *tp;
int osw = switchwidth;
int oswb = switchbreak;
int ogf = goodcode;
struct caselist *occ = currentCases ;
int ohd = hasdefault;
switchbreak = 0;
hasdefault = 0;
currentCases = xalloc(sizeof(struct caselist));
snp = xalloc(sizeof(SNODE));
snp->next = 0;
snp->stype = st_switch;
snp->label = dbgblocknum + 1;
getsym();
needpunc(openpa, 0);
tp = doassign(&snp->exp, TRUE, 0);
switchwidth = natural_size(snp->exp);
if (tp)
{
if (tp->type == bt_cond)
tp = tp->btp ;
if (!scalarnonfloat(tp))
generror(ERR_SWITCHINT, 0, 0);
}
needpunc(closepa, skm_closepa);
inswitch++;
goodcode |= GF_UNREACH | GF_BREAKABLE;
snp->s1 = cppblockedstatement(TRUE);
if ((goodcode & GF_DEF) && (goodcode & GF_RETURN) && !(switchbreak))
ogf |= GF_UNREACH;
else
ogf &= ~GF_UNREACH;
inswitch--;
hasdefault = ohd;
currentCases = occ;
goodcode = ogf;
switchbreak = oswb;
switchwidth = osw;
return snp;
}
//-------------------------------------------------------------------------
ENODE *do_ret_constructor(TYP *tp, TYP *head1, ENODE *node, int size, int
offset, int implicit)
{
char buf[256];
int voidfunc = FALSE;
SYM *sp;
ENODE *pnode, *rnode, *tcnode = 0;
if (tp->lst.head == (SYM*) - 1)
voidfunc = TRUE;
{
SYM *sp1 = search(cpp_funcname_tab[CI_CONSTRUCTOR], &head1->lst);
if (!sp1)
{
return 0;
}
sp = funcovermatch(sp1, tp, node, FALSE, FALSE);
if (!sp)
{
return 0;
}
pnode = makenode(en_napccon, sp, 0);
}
if (!isaccessible(sp))
genclasserror(ERR_NOTACCESSIBLE, fullcppmangle(sp->parentclass
->parentclass, sp->name, 0));
if (implicit && (sp->value.classdata.cppflags &PF_EXPLICIT))
generror(ERR_NOEXPLICITHERE, 0, 0);
sp->mainsym->extflag = TRUE;
parmlist(&node, tp, sp->tp);
rnode = makenode(en_void, pnode, pnode);
pnode = makenode(en_void, rnode, node);
rnode = makeintnode(en_icon, sp->tp->btp->size);
if (sp->pascaldefn)
pnode = makenode(en_pfcall, rnode, pnode);
else
if (sp->isstdcall)
pnode = makenode(en_sfcall, rnode, pnode);
else
pnode = makenode(en_fcall, rnode, pnode);
if (!(sp->value.classdata.cppflags &PF_STATIC))
tcnode = makenode(en_structret, 0, 0);
if (prm_cplusplus && tcnode && (sp->value.classdata.cppflags &PF_MEMBER)
&& !(sp->value.classdata.cppflags &PF_STATIC))
{
pnode = makenode(en_thiscall, tcnode, pnode);
}
if (size == 1)
pnode = doinline(pnode);
else
{
ENODE *snode;
snode = makeintnode(en_icon, head1->size);
snode = makenode(en_void, makeintnode(en_icon, size), (void*)snode);
pnode = makenode(en_repcons, (void*)snode, (void*)pnode);
SetExtFlag(sp, TRUE);
}
pnode->cflags = head1->cflags;
return pnode;
}
//-------------------------------------------------------------------------
SNODE *breakcontrundowns(SNODE *snp)
{
LASTDEST *p = lastDestPointer;
SNODE *result = 0, **v = &result;
while (p)
{
if (p->block && p->chain)
{
SNODE *snp2 = xalloc(sizeof(SNODE));
snp2->next = 0;
snp2->stype = st_expr;
snp2->exp = p->block;
*v = snp2;
v = &(snp2->next);
}
p = p->chain;
}
*v = snp;
return result;
}
//-------------------------------------------------------------------------
ENODE *retrundowns(void)
{
ENODE *ep = 0;
if (prm_cplusplus)
{
LASTDEST *p = lastDestPointer;
while (p)
{
if (p->block && p->chain)
{
if (ep)
ep = makenode(en_void, ep, p->block);
else
ep = p->block;
}
p = p->chain;
}
}
return ep;
}
//-------------------------------------------------------------------------
SNODE *retstmt(void)
/*
* Handle return
*/
{
SNODE *snp;
TYP *tp;
snp = xalloc(sizeof(SNODE));
snp->next = 0;
snp->stype = st_return;
snp->exp = 0;
getsym();
if (lastst == end || lastst == semicolon)
{
if (currentfunc->tp->btp->type != bt_void)
generror(ERR_FUNCRETVAL2, 0, 0);
needpunc(semicolon, 0);
}
else
{
ENODE *epn;
int ogc = goodcode;
goodcode |= GF_SUPERAND;
tp = expression(&(snp->exp), TRUE);
tp = stmtsize(&snp->exp, tp);
if (currentfunc->tp->btp->type == bt_bool)
{
snp->exp = makenode(en_cbool, snp->exp, 0);
typedconsts(snp->exp);
}
else if (isstructured(currentfunc->tp->btp))
{
ENODE *ep1, *ep2, *qn, **epq = 0, **ep;
TYP *tp1;
if (snp->exp && (snp->exp->nodetype == en_void || snp->exp
->nodetype == en_dvoid))
{
ep = actualexpr(&snp->exp);
epq = &(*ep)->v.p[1];
ep = &(*ep)->v.p[0];
}
else
ep = &snp->exp;
ep1 = makenode(en_structret, 0, 0);
if (prm_cplusplus)
{
SYM s;
qn = makenode(en_void, (*ep), 0);
tp1 = maketype(bt_func, 0);
memset(&s, 0, sizeof(s));
s.tp = tp;
tp1->lst.head = tp1->lst.tail = &s;
ep2 = do_ret_constructor(tp1, currentfunc->tp->btp, qn, 1, 0,
!exactype(tp, currentfunc->tp->btp, FALSE));
if (ep2)
tp = currentfunc->tp->btp;
else if (isstructured(tp))
{
tp1->lst.head = tp1->lst.tail = tp->sp;
ep2 = do_ret_constructor(tp1, tp, qn, 1, 0, TRUE);
}
}
else
ep2 = 0;
if (!ep2)
{
ep2 = makenode(en_moveblock, ep1, *ep);
ep2->size = tp->size;
}
ep2 = makenode(en_void, ep2, ep1);
*ep = ep2;
epn = retrundowns();
if (epn)
if (epq)
*epq = makenode(en_void, *epq, epn);
else
*ep = makenode(en_dvoid, *ep, epn);
}
else
{
if (currentfunc->tp->btp->type == bt_ref && !isstructured
(currentfunc->tp->btp->btp))
{
while (castvalue(snp->exp))
snp->exp = snp->exp->v.p[0];
if (lvalue(snp->exp))
snp->exp = snp->exp->v.p[0];
}
if (currentfunc->tp->btp->type == bt_memberptr)
{
tp = FindMemberPointer(currentfunc->tp->btp, tp, &snp->exp);
while (castvalue(snp->exp))
snp->exp = snp->exp->v.p[0];
if (lvalue(snp->exp))
snp->exp = snp->exp->v.p[0];
// } else if (currentfunc->tp->btp->type == bt_ref) {
// while (castvalue(snp->exp))
// snp->exp = snp->exp->v.p[0] ;
// if (lvalue(snp->exp))
// snp->exp = snp->exp->v.p[0] ;
}
epn = retrundowns();
if (epn)
snp->exp = makenode(en_dvoid, snp->exp, epn);
}
goodcode = ogc;
if (lastst != eof)
needpunc(semicolon, 0);
if (tp->type == bt_void)
{
generror(ERR_NOVOIDRET, 0, 0);
}
else
{
TYP *tp1 = tp;
if (tp1->type == bt_ref)
tp1 = tp1->btp;
if (currentfunc->tp->btp->type == bt_void)
generror(ERR_VOIDFUNCNOVALUE, 0, 0);
else {
if (!checktype(currentfunc->tp->btp, tp1, TRUE))
if (!(isscalar(tp1) && isscalar(currentfunc->tp->btp)))
if (currentfunc->tp->btp->type != bt_pointer &&
currentfunc->tp->btp->type != bt_farpointer ||
floatrecurse(snp->exp))
generror(ERR_RETMISMATCH, 0, 0);
}
}
}
return snp;
}
//-------------------------------------------------------------------------
SNODE *breakstmt(void)
/*
* handle break
*/
{
SNODE *snp;
snp = xalloc(sizeof(SNODE));
snp->next = 0;
snp->stype = st_break;
getsym();
if (!(goodcode &GF_BREAKABLE))
generror(ERR_NOCONTINUE, 0, 0);
if (lastst != eof)
needpunc(semicolon, 0);
return breakcontrundowns(snp);
}
//-------------------------------------------------------------------------
SNODE *contstmt(void)
/*
* handle continue
*/
{
SNODE *snp;
snp = xalloc(sizeof(SNODE));
snp->next = 0;
snp->stype = st_continue;
if (!(goodcode &GF_CONTINUABLE))
generror(ERR_NOCONTINUE, 0, 0);
getsym();
if (lastst != eof)
needpunc(semicolon, 0);
return breakcontrundowns(snp);
}
//-------------------------------------------------------------------------
SNODE *_genwordstmt(void)
/*
* Insert data in the code stream
*/
{
SNODE *snp;
snp = xalloc(sizeof(SNODE));
snp->next = 0;
snp->stype = st__genword;
snp->exp = 0;
getsym();
if (lastst != openpa)
{
generror(ERR_PUNCT, openpa, skm_semi);
getsym();
snp = 0;
}
else
{
getsym();
snp->exp = (ENODE*)intexpr(0);
if (lastst != closepa)
{
generror(ERR_PUNCT, closepa, skm_semi);
snp = 0;
}
getsym();
}
if (lastst != eof)
needpunc(semicolon, 0);
return (snp);
}
//-------------------------------------------------------------------------
SNODE *exprstmt(void)
/*
* exprstmt is called whenever a statement does not begin
* with a keyword. the statement should be an expression.
*/
{
SNODE *snp;
snp = xalloc(sizeof(SNODE));
snp->next = 0;
snp->stype = st_expr;
goodcode &= ~(GF_ASSIGN);
if (expression(&snp->exp, TRUE) == 0)
{
generror(ERR_EXPREXPECT, 0, skm_semi);
snp->exp = 0;
}
if (!(goodcode &GF_ASSIGN))
generror(ERR_CODENONE, 0, 0);
if (lastst != eof)
needpunc(semicolon, 0);
return snp;
}
//-------------------------------------------------------------------------
SNODE *snp_line(int tocode)
/*
* construct a statement for the beginning of a new line
*/
{
SNODE *snp3 = 0;
if (lineno != lastlineno && lastst != semicolon && lastst != begin)
{
int i = 0, j, l = pstrlen(unalteredline);
snp3 = xalloc(sizeof(SNODE));
snp3->next = 0;
snp3->stype = st_line;
snp3->exp = (ENODE*)lineno;
snp3->s1 = (SNODE*)currentfile;
snp3->next = 0;
for (j = 0; j < l && isspace(unalteredline[j]); j++)
;
for (; j < l; j++)
phibuf[i++] = unalteredline[j];
if (phibuf[i - 1] == '\n')
i--;
phibuf[i] = 0;
snp3->label = (SNODE*)xalloc(i + 1);
strcpy(snp3->label, phibuf);
lastlineno = lineno;
if (tocode && currentfile)
lastinc->hascode = TRUE;
}
return snp3;
}
//-------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -