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

📄 cexpr2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    for(;;) {
        if( tree == 0 ) tree = ExprOpnd();
        curclass = TokenClass[ CurToken ] & 0x7F;
        while( curclass <= Class[ Level ] ) {
            op1 = ValueStack[ Level ];

            /* the following cases are listed from lowest to highest
               priority */
            switch( Class[ Level ] ) {
            case TC_START:
            case TC_START1:
            case TC_START2:
            case TC_START_UNARY:
                return( tree );
            case TC_LEFT_PAREN:         /* bracketed expression */
                MustRecog( T_RIGHT_PAREN );
                curclass = TokenClass[ CurToken ] & 0x7F;
                break;
            case TC_COMMA:
                if( op1->op.opr == OPR_ERROR ) {
                    FreeExprTree( tree );
                    return( op1 );
                }
                if( tree->op.opr == OPR_ERROR ) {
                    FreeExprTree( op1 );
                    return( tree );
                }
                op1 = VoidRValue( op1 );
                typ = TypeOf( tree );
                if( !IsStruct( typ ) ){
                    tree = VoidRValue( tree );
                }
                tree = ExprNode( op1, OPR_COMMA, tree );
                tree->expr_type = typ;
                tree->op.result_type = typ;
                break;
            case TC_ASSIGNMENT:  /*  = += -= *= /= %= >>= <<= &= ^= |=  */
                ChkConst( op1 );
                tree = AsgnOp( op1, Token[ Level ], tree );
                CompFlags.meaningless_stmt = 0;
                CompFlags.useful_side_effect = 1;
                break;
            case TC_TERNARY:
                MustRecog( T_COLON );
                break;
            case TC_TERNARY_DONE:
                CompFlags.meaningless_stmt &= Token[ Level ];/*13-mar-93*/
                --Level;
                tree = TernOp( ValueStack[ Level ], op1, tree );
                CompFlags.pending_dead_code = 0;
                break;
            case TC_OR_OR:
                if( Token[ Level ] == 0 ) {
                    BoolExpr( tree );   /* checks type of op2 */
                    --SizeOfCount;
                    tree = op1;
                } else {
                    tree = FlowOp( op1, OPR_OR_OR, BoolExpr( tree ) );
                }
                CompFlags.meaningless_stmt = 1;
                CompFlags.pending_dead_code = 0;
                break;
            case TC_AND_AND:
                if( Token[ Level ] == 0 ) {
                    BoolExpr( tree );   /* checks type of op2 */
                    --SizeOfCount;
                    tree = op1;
                } else {
                    tree = FlowOp( op1, OPR_AND_AND, BoolExpr( tree ) );
                }
                CompFlags.meaningless_stmt = 1;
                CompFlags.pending_dead_code = 0;
                break;
            case TC_OR:
            case TC_XOR:
            case TC_AND:
                tree = IntOp( op1, Token[ Level ], tree );
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_EQ_NE:
            case TC_REL_OP:
                tree = RelOp( op1, Token[ Level ], tree );
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_SHIFT_OP:
                tree = ShiftOp( op1, Token[ Level ], tree );
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_ADD_OP:
                tree = AddOp( op1, Token[ Level ], tree );
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_MUL_OP:
                tree = BinOp( RValue(op1), Token[ Level ], tree );
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_PREINC:
                tree = IncDec( tree, Token[ Level ] );
                break;
            case TC_ADDR:
                tree = AddrOp( tree );
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_EXCLAMATION:
                tree = NotOp( RValue( tree ) );
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_PLUS:                       /* unary plus */
                tree = UnaryPlus( tree );
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_MINUS:                      /* unary minus */
                tree = UMinus( tree );
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_TILDE:
                tree = UComplement( tree );
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_SIZEOF:
                typ = tree->expr_type;
                FreeExprTree( tree );
                if( typ != NULL ){
                    tree = SizeofOp( typ );
                }else{
                    tree = UIntLeaf( 1 ); //error use this as default
                }
                --SizeOfCount;
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_INDIRECTION:
                tree = PtrOp( RValue( tree ) );
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_CAST:
                tree = CnvOp( tree, TypeOf( op1 ), 1 );
                FreeExprTree( op1 );
                break;
            case TC_INDEX:
                tree = IndexOp( op1, tree );
                curclass = TokenClass[ CurToken ] & 0x7F;
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_SEG_OP:                             /* 23-oct-91 */
                tree = SegOp( op1, tree );
                CompFlags.meaningless_stmt = 1;
                break;
            case TC_PARM_LIST:          /* do func call */
                {
                SYMPTR      sym;
                int         n;
                TREEPTR     functree;

                // find the corresponding function symbol
                n = Level;
                while( Token[ n ] != T_LEFT_PAREN ) {
                    --n;
                }
                functree = ValueStack[ n ];
                sym = SymGetPtr( functree->op.sym_handle );
                if( !(sym->flags & SYM_TEMP) )
                    SetDiagSymbol( sym, functree->op.sym_handle );
                tree = GenNextParm( tree, &plist );
                tree = GenFuncCall( tree );
                if( plist != NULL ){  // function has prototype
                    if(  *plist != NULL && (*plist)->decl_type != TYPE_DOT_DOT_DOT ) {
                        CErr1( ERR_PARM_COUNT_MISMATCH );
                    }
                } else {
                    AddCallNode( tree );
                }
                if( !(sym->flags & SYM_TEMP) )
                    SetDiagPop();
                PopNestedParms( &plist );
                curclass = TokenClass[ CurToken ] & 0x7F;
                CompFlags.meaningless_stmt = 0;
                CompFlags.useful_side_effect = 1;
                }
                break;
            }
            --Level;
        }
        switch( curclass ) {
        case TC_RIGHT_PAREN:                    /* 27-feb-94 */
            CErr1( ERR_UNEXPECTED_RIGHT_PAREN );
            NextToken();
            continue;
        case TC_QUESTION:
            tree = StartTernary( tree );
            curclass = TC_TERNARY;
            break;
        case TC_COLON:
            tree = ColonOp( tree );
            CurToken = CompFlags.meaningless_stmt;
            curclass = TC_TERNARY_DONE;
            break;
        case TC_OR_OR:
            tree = BoolExpr( tree );
            tree = OrOr( tree );
            break;
        case TC_AND_AND:
            tree = BoolExpr( tree );
            tree = AndAnd( tree );
            break;
        case TC_OR:
        case TC_XOR:
        case TC_AND:
        case TC_EQ_NE:
        case TC_REL_OP:
        case TC_SHIFT_OP:
        case TC_ADD_OP:
        case TC_MUL_OP:
/*              tree = RValue( tree );   17-jan-88 */
            break;
        case TC_ASSIGN_OP:
            curclass = TC_ASSIGNMENT;
            break;
        case TC_LEFT_BRACKET:
            curclass = TC_INDEX;
            break;
        case TC_COMMA:
            if( Class[ Level ] != TC_PARM_LIST ) {
                if( CompFlags.meaningless_stmt == 1 ) {
                    if( CompFlags.useful_side_effect ) {
                        CWarn1( WARN_USEFUL_SIDE_EFFECT,
                                ERR_USEFUL_SIDE_EFFECT );
                    } else {
                        CWarn1( WARN_MEANINGLESS, ERR_MEANINGLESS );
                    }
                }
            } else {
                tree = GenNextParm( tree, &plist );
                curclass = TC_PARM_LIST;
            }
            break;
        case TC_FUNC_CALL:
            tree = StartFunc( tree, &plist );
            continue;
        case TC_DOT:
            NextToken();
            tree = DotOp( tree );
            if( CurToken != T_SEMI_COLON ) NextToken();
            CompFlags.meaningless_stmt = 1;
            continue;
        case TC_ARROW:
            NextToken();
            tree = ArrowOp( RValue( tree ) );
            if( CurToken != T_SEMI_COLON ) NextToken();
            CompFlags.meaningless_stmt = 1;
            continue;
        case TC_POSTINC:

            tree = IncDec( tree, CurToken );
            NextToken();
            continue;
        }
        if( Level >= (MAX_LEVEL - 1) ) {
            CErr1( ERR_EXPR_TOO_COMPLICATED );
            CSuicide();
        }
        if( tree != 0 ) {
            ++Level;
            ValueStack[ Level ] = tree;
            Class[ Level ] = curclass;
            Token[ Level ] = CurToken;
            tree = 0;               /* indicate need opnd */
        }
        NextToken();
    }
}


local TREEPTR ExprOpnd()
{
    TREEPTR     tree;
    TYPEPTR     typ;

    CompFlags.meaningless_stmt = 1;
    for(;;) {
        ++Level;
        switch( CurToken ) {
        case T_PLUS_PLUS:
        case T_MINUS_MINUS:
            Token[ Level ] = CurToken - 1;
            Class[ Level ] = TC_PREINC;
            NextToken();
            continue;
        case T_AND:
            Class[ Level ] = TC_ADDR;
            NextToken();
            continue;
        case T_EXCLAMATION:
            Class[ Level ] = TC_EXCLAMATION;
            NextToken();
            continue;
        case T_PLUS:
            Class[ Level ] = TC_PLUS;
            NextToken();
            continue;
        case T_MINUS:
            Class[ Level ] = TC_MINUS;
            NextToken();
            continue;
        case T_TILDE:
            Class[ Level ] = TC_TILDE;
            NextToken();
            continue;
        case T_SIZEOF:
            if( CompFlags.pre_processing ) {
                CErr1( ERR_NO_SIZEOF_DURING_PP );
            }
            Class[ Level ] = TC_SIZEOF;
            NextToken();
            Token[ Level ] = CurToken;
            if( CurToken == T_LEFT_PAREN ) {
                NextToken();
                typ = TypeName();
                if( typ != NULL ) {
                    tree = SizeofOp( typ );
                    MustRecog( T_RIGHT_PAREN );
                    break;
                }
                ++Level;
                Class[ Level ] = TC_LEFT_PAREN;
            }
            ++SizeOfCount;
            continue;
        case T___BUILTIN_ISFLOAT:
            NextToken();
            if( CurToken == T_LEFT_PAREN ) {
                NextToken();
                typ = TypeName();
                if( typ != NULL ) {
                    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
                    switch( typ->decl_type ) {
                    case TYPE_FLOAT:
                    case TYPE_DOUBLE:
                        tree = IntLeaf( 1 );
                        break;
                    default:
                        tree = IntLeaf( 0 );
                        break;
                    }
                } else {
                    CErr1( ERR_OPND_OF_BUILTIN_ISFLOAT_MUST_BE_TYPE );
                    NextToken();
                    tree = LeafNode( OPR_ERROR );
                }
                MustRecog( T_RIGHT_PAREN );
            } else {
                MustRecog( T_LEFT_PAREN );
                tree = LeafNode( OPR_ERROR );
            }
            break;
        case T_TIMES:
            Class[ Level ] = TC_INDIRECTION;
            NextToken();
            continue;
        case T_LEFT_PAREN:
            NextToken();
            typ = TypeName();
            if( typ != NULL ) {
                if( CompFlags.pre_processing ) {
                    CErr1( ERR_NO_CAST_DURING_PP );
                }
                MustRecog( T_RIGHT_PAREN );
                Class[ Level ] = TC_CAST;
                tree = LeafNode( OPR_CAST );
                tree->expr_type = typ;
                ValueStack[ Level ] = tree;
            } else {
                Class[ Level ] = TC_LEFT_PAREN;
            }
            continue;
        case T_ID:
            tree = ExprId();
            CompFlags.meaningless_stmt = 0;             /* 07-apr-93 */
            break;
        case T_SAVED_ID:
            tree = SymLeaf();
            CMemFree( SavedId );
            SavedId = NULL;
            CurToken = LAToken;
            CompFlags.meaningless_stmt = 0;             /* 07-apr-93 */
            break;
        case T_CONSTANT:
            tree = ConstLeaf();
            NextToken();
            break;
        case T_STRING:
            if( CompFlags.strings_in_code_segment ) {
                tree = StringLeaf( FLAG_CONST );        /* 01-sep-89 */
            } else {
                tree = StringLeaf( 0 );
            }
            break;
        case T_BAD_TOKEN:
            CErr1( BadTokenInfo );
            BadTokenInfo = 0;
            NextToken();
            tree = ErrorNode( NULL );

⌨️ 快捷键说明

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