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

📄 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 页
字号:
    snp = xalloc(sizeof(SNODE));
    snp->next = 0;
    if ((sp = search(lastid, &lsyms)) == 0)
    {
        sp = makesym(sc_ulabel);
        sp->name = litlate(lastid);
        sp->value.i = nextlabel++;
        sp->tp = xalloc(sizeof(TYP));
        sp->tp->bits = sp->tp->startbit =  - 1;
        sp->tp->type = bt_unsigned;
        insert(sp, &lsyms);
    }
    sp->tp->uflags = UF_USED;
    getsym(); /* get past label name */
    gotoCount++ ;
    if (lastst != eof)
        needpunc(semicolon, 0);
    if (sp->storage_class != sc_label && sp->storage_class != sc_ulabel)
        gensymerror(ERR_LABEL, sp->name);
    else
    {
        snp->stype = st_goto;
        snp->label = (SNODE*)sp->value.i;
        snp->next = 0;
        return snp;
    }
    return 0;
}

//-------------------------------------------------------------------------

SNODE *catchstmt(TRYBLOCK *a)
{
    int pushed = FALSE;
    SNODE *sn = snp_line(TRUE),  *sn1,  *sn2;
    CATCHBLOCK *c,  **s,  *p;
    global_flag++;
    c = xalloc(sizeof(CATCHBLOCK));
    global_flag--;
    c->label = nextlabel++;
    getsym();
    if (needpunc(openpa, 0))
    {
        if (lastst != ellipse)
        {
            TYP *tp;
            if (gotellipse)
            {
                generror(ERR_ELLIPSEHANDLERLAST, 0, 0);
                gotellipse = FALSE;
            }
            incatchclause = TRUE;
            declid[0] = 0;
            typequal = 0;
            decl(0, 0); /* do cast declaration */
            headptr = &head;
            decl1(sc_auto, 0);
            incatchclause = FALSE;
            tp = head;
            if (!tp || defaulttype && tp->type == bt_int)
            // || !isstructured(tp))
                generror(ERR_TYPENAMEEXP, 0, 0);
            else
            {
                global_flag++;
                c->xtcatch = copytype(tp, 0);
                global_flag--;
            }
            global_flag++;
            c->dummy = dummyvar(tp->size, tp, declid[0] ? declid : 0);
            global_flag--;
            c->dummy->v.sp->iscatchvar = TRUE;
            pushed = TRUE;
            p = a->catchit;
            while (p)
            {
                char buf[256];
                if (p->xtcatch == tp)
                {
                    typenum2(buf, tp);
                    gensymerror(ERR_DUPHANDLER, buf);
                    break;
                }
                p = p->next;
            }


        }
        else
        {
            getsym();
            gotellipse = TRUE;
        }
        if (needpunc(closepa, 0))
        {
            if (lastst != begin)
                needpunc(begin, 0);
            else
            {
                ENODE *ep1,  *ep2 = makenode(en_napccon, (void*)
                    catch_cleanup_func, 0);
                int blocknum = dbgblocknum;
                catch_cleanup_func->mainsym->extflag = TRUE;
                sn1 = xalloc(sizeof(SNODE));
                sn1->stype = st_label;
                sn1->label = (SNODE*)c->label;
                if (sn)
                    sn->next = sn1;
                else
                    sn = sn1;
                sn1->next = xalloc(sizeof(SNODE));
                sn1->next->stype = st_tryblock;
                sn1->next->label = (void*)1; // beginning of catch block
                sn1 = sn1->next;
                getsym();
                sn2 = xalloc(sizeof(SNODE));
                sn2->exp = compoundblock();
                sn2->stype = st_block;
                sn2->label = blocknum + 1;
                sn1 = sn1->next = sn2;
                ep1 = makenode(en_void, 0, 0);
                ep2 = makenode(en_void, ep2, ep2);
                ep1 = makenode(en_void, ep2, ep1);
                ep1 = makenode(en_fcall, makeintnode(en_icon, 0), ep1);
                sn1->next = xalloc(sizeof(SNODE));
                sn1->next->stype = st_expr;
                sn1->next->exp = ep1;
                sn1 = sn1->next;
                sn1->next = xalloc(sizeof(SNODE));
                sn1->next->stype = st_goto;
                sn1->next->label = a->catchendlab;
                s = &a->catchit;
                while (*s)
                    s = &(*s)->next;
                *s = c;
            }
        }
    }
    if (pushed)
        lsyms.head->name = "$$$dummy";
    return sn;
}

//-------------------------------------------------------------------------

SNODE *trystmt(void)
{
    SNODE *sn,  *sn1;
    int oldgotellipse = gotellipse;
    gotellipse = FALSE;
    getsym();
    global_flag++;
    sn = xalloc(sizeof(SNODE));
    sn->stype = st_label;
    sn->label = (SNODE*)nextlabel++;
    if (!prm_xcept)
        generror(ERR_NOXCEPT, 0, 0);
    if (lastst != begin)
        needpunc(begin, 0);
    else
    {
        TRYBLOCK *a = xalloc(sizeof(TRYBLOCK));
        int blocknum = dbgblocknum;
        a->startlab = nextlabel++;
        a->endlab = nextlabel++;
        a->catchendlab = nextlabel++;
        a->next = try_block_list;
        try_block_list = a;
        sn->label = (SNODE*)a->startlab;
        sn1 = sn;
        sn1->next = xalloc(sizeof(SNODE));
        sn1->next->stype = st_tryblock;
        sn1->next->label = (void*)0; // start of try block
        sn1 = sn1->next;
        getsym();
        sn1->next = xalloc(sizeof(SNODE));
        sn1->next->exp = compoundblock();
        sn1->next->stype = st_block;
        sn1->next->label = blocknum + 1;
        sn1 = sn1->next;
        sn1->next = xalloc(sizeof(SNODE));
        sn1->next->stype = st_tryblock;
        sn1->next->label = (void*)2; // end of try block
        sn1 = sn1->next;
        sn1->next = xalloc(sizeof(SNODE));
        sn1->next->stype = st_goto;
        sn1->next->label = (SNODE*)a->catchendlab;
        sn1 = sn1->next;
        sn1->next = xalloc(sizeof(SNODE));
        sn1->next->stype = st_label;
        sn1->next->label = (SNODE*)a->endlab;
        sn1 = sn1->next;
        if (lastst != kw_catch)
        {
            generror(ERR_CATCHEXP, 0, 0);
        }
        else
        {
            global_flag--;
            while (lastst == kw_catch)
            {
                SYM *sn2 = catchstmt(a);
                sn1->next = sn2;
                while (sn1->next)
                    sn1 = sn1->next;
            }
            global_flag++;
        }
        sn1->next = xalloc(sizeof(SNODE));
        sn1->next->stype = st_label;
        sn1->next->label = (SNODE*)a->catchendlab;
        sn1 = sn1->next;

    }
    gotellipse = oldgotellipse;
    global_flag--;
    return sn;
}

//-------------------------------------------------------------------------

SNODE *asm_statement(int shortfin);
SNODE *statement(void)
/* 
 *      statement figures out which of the statement processors 
 *      should be called and transfers control to the proper 
 *      routine. 
 */
{
    SNODE *snp = 0,  *snp2,  **psnp;
    SNODE *snp3 = snp_line(TRUE);
    int done = FALSE;
    //        while (!done) {
    //            done = TRUE ;
    switch (lastst)
    {
        case kw_using:
            using_keyword();
            break;
            #ifndef ICODE
            case kw_asm:
                asmline = TRUE;
                getsym();
                if (lastst == begin)
                {
                    getsym();
                    snp = snp3;
                    if (snp)
                        psnp = &snp->next;
                    else
                        psnp = &snp;
                    *psnp = 0;
                    while (lastst != end && lastst != eof)
                    {
                        *psnp = asm_statement(TRUE);
                        while (*psnp)
                            psnp = &(*psnp)->next;
                        *psnp = snp_line(TRUE);
                        while (*psnp)
                            psnp = &(*psnp)->next;
                    }
                    asmline = FALSE;
                    if (lastst == end)
                        getsym();
                    return snp;
                }
                snp = asm_statement(FALSE);
                asmline = FALSE;
                break;
            #endif 
        case semicolon:
            getsym();
            snp = 0;
            break;
        case begin:
            {
                int oldpragma = stdpragmas;
                int blocknum = dbgblocknum;
                getsym();
                if ((goodcode & GF_UNREACH) && lastst != semicolon && lastst != kw_case && lastst != kw_default)
                    generror(ERR_UNREACHABLE, 0, 0);
                snp2 = compoundblock();
                snp = xalloc(sizeof(SNODE));
                snp->next = 0;
                snp->exp = snp2;
                snp->stype = st_block;
                snp->label = blocknum + 1;
                stdpragmas = oldpragma;
                break;
            }
        case kw_if:
            snp = ifstmt();
            break;
        case kw_while:
            snp = whilestmt();
            snp->lst = snp3;
            snp3 = 0;
            break;
        case kw_for:
            snp = forstmt();
            snp->lst = snp3;
            snp3 = 0;
            break;
        case kw_return:
            snp = retstmt();
            goodcode |= GF_RETURN;
            break;
        case kw_break:
            goodcode |= GF_BREAK;
            switchbreak = 1;
            snp = breakstmt();
            break;
        case kw_goto:
            goodcode |= GF_GOTO;
            snp = gotostmt();
            break;
        case kw_continue:
            goodcode |= GF_CONTINUE;
            snp = contstmt();
            break;
        case kw_do:
            snp = dostmt();
            break;
        case kw_switch:
            snp = switchstmt();
            break;
        case kw_try:
            snp = trystmt();
            break;
        case kw_else:
            generror(ERR_ELSE, 0, 0);
            getsym();
            break;
        case kw_case:
        case kw_default:
            if (!inswitch) {
                generror(ERR_CASENOSWITCH,0,0);
            }
            snp = casestmt();
            break;
        case kw__genword:
            snp = _genwordstmt();
            break;
        doid: case id:
        default:
                if (castbegin(lastst) || lastst == kw_typedef)
                {
                    if (prm_cplusplus || prm_c99)
                    {
                        cbautoinithead = cbautoinittail = 0;
                        if (blockdecl())
                        {
                            snp = cbautoinithead;
                            goto doexpr;
                        }
                        snp = cbautoinithead;
                    }
                    else
                    {
                        generror(ERR_NODECLARE, 0, skm_semi);
                        snp = 0;
                    }
                }
                else
                {
                doexpr: if (lastst == id)
                {
                    while (isspace(lastch))
                        getch();
                    if (lastch == ':' &&  *lptr != ':')
                        snp = labelstmt(TRUE);
                    else
                        snp = exprstmt();
                }
                else
                    snp = exprstmt();
            }
            break;
    }
    //        }
    if (snp != 0)
    {
        if (snp3)
        {
            snp3->next = snp;
            snp = snp3;
        }
    }
    return snp;
}

/* Handling for special C++ situations */
SNODE *cppblockedstatement(int breakdest)
{
    SNODE *snp;
    TABLE oldoldlsym, oldoldltag;
    LIST *nsusing,  *nstusing;
    int oldpragma = stdpragmas;
    long oldlcauto;
    ENODE *obrd = block_rundown;
    LASTDEST rundown;
    int nested = FALSE;
    rundown.last = lastDestPointer;
    rundown.block = block_rundown;
    if (breakdest)
        rundown.chain = 0;
    else
        rundown.chain = lastDestPointer;
    lastDestPointer = &rundown;
    block_rundown = 0;
        if (prm_cplusplus || prm_c99)
        {
            oldoldlsym = oldlsym;
            oldlsym = lsyms;
            oldoldltag = oldltag;
            oldltag = ltags;
            nsusing = local_using_list;
            nstusing = local_tag_using_list;
            if (lastst != begin)
            {
                block_nesting++;
                nested = TRUE;
            }
        }
    snp = statement();
        if (prm_cplusplus || prm_c99)
        {
            if (nested)
                block_nesting--;
            addblocklist(lsyms.head, oldlsym.head);
            addrundown(snp);
            check_funcused(&oldlsym, &lsyms);
            gather_labels(&oldlsym, &lsyms);
            cseg();
            lsyms = oldlsym;
            oldlsym.head = oldoldlsym.head;
            ltags = oldltag;
            oldltag.head = oldoldltag.head;
            local_using_list = nsusing;
            local_tag_using_list = nstusing;
        }
    block_rundown = rundown.block;
    lastDestPointer = rundown.last;
    return (snp);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -