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

📄 expr.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 5 页
字号:

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

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 + -