📄 cexpr2.c
字号:
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 + -