⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stmt.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 4 页
字号:
                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 + -