📄 cstmt2.c
字号:
static void ElseStmt( void )
{
LABEL_INDEX if_label;
SrcLineNum = TokenLine; /* 18-jan-89 */
SrcFno = TokenFno;
NextToken();
BlockStack->block_type = T_ELSE;
if_label = BlockStack->break_label;
if( DeadCode ) { /* 05-apr-92 */
BlockStack->break_label = 0;
} else {
BlockStack->break_label = NextLabel();
Jump( BlockStack->break_label );
}
DropLabel( if_label );
}
static void GotoStmt( void )
{
LABELPTR label;
NextToken();
if( CurToken != T_ID ) {
CErr1( ERR_EXPECTING_LABEL );
} else {
label = LkLabel( Buffer );
label->referenced = 1; /* 05-apr-91 */
Jump( label->ref_list );
}
NextToken();
MustRecog( T_SEMI_COLON );
}
static void ForStmt( void )
{
NextToken();
MustRecog( T_LEFT_PAREN );
if( CurToken != T_SEMI_COLON ) ChkStmtExpr(); // init_expr
MustRecog( T_SEMI_COLON );
NewLoop();
BlockStack->block_type = T_FOR;
if( CurToken != T_SEMI_COLON ) {
BlockStack->break_label = NextLabel();
if( ! JumpFalse( Expr(), BlockStack->break_label ) ) {
BlockStack->break_label = 0; /* 09-sep-92 */
}
}
MustRecog( T_SEMI_COLON );
BlockStack->inc_var = NULL;
if( CurToken != T_RIGHT_PAREN ) {
BlockStack->inc_var = Expr(); // save this
if( CompFlags.meaningless_stmt == 1 ) {
ChkUseful();
}
}
MustRecog( T_RIGHT_PAREN );
}
static void EndForStmt( void )
{
DropContinueLabel();
if( BlockStack->inc_var ) {
AddStmt( BlockStack->inc_var );
}
Jump( BlockStack->top_label );
}
static void StmtExpr( void )
{
ChkStmtExpr();
switch( CurToken ) {
case T_IF:
case T_WHILE:
case T_DO:
case T_FOR:
case T_SWITCH:
case T_CASE:
case T_DEFAULT:
case T_BREAK:
case T_CONTINUE:
case T_RETURN:
case T_GOTO:
case T_LEFT_BRACE:
case T_RIGHT_BRACE:
Expecting( Tokens[ T_SEMI_COLON ] );
break;
default:
Expecting( Tokens[ T_SEMI_COLON ] );
case T_SEMI_COLON:
NextToken();
break;
}
}
void ChkStmtExpr( void )
{
TREEPTR tree;
tree = Expr();
if( CompFlags.meaningless_stmt == 1 ) {
ChkUseful();
}
AddStmt( tree );
if( CompFlags.pending_dead_code ) {
DeadCode = 1;
}
}
static void ChkUseful( void )
{
if( CompFlags.useful_side_effect ) {
CWarn1( WARN_USEFUL_SIDE_EFFECT, ERR_USEFUL_SIDE_EFFECT );
} else {
CWarn1( WARN_MEANINGLESS, ERR_MEANINGLESS );
}
}
static void AddCaseLabel( unsigned long value )
{
CASEPTR ce, prev_ce, new_ce;
unsigned long old_value, converted_value;
TREEPTR tree;
auto char buffer[12];
prev_ce = NULL;
#if 0
leaf.u.ulong_konst = value;
leaf.data_type = SwitchStack->case_type;
SetLeafType( &leaf, 1 );
// converted_value = value & SwitchStack->case_mask;
converted_value = leaf.u.ulong_konst;
#else
converted_value = value;
#endif
old_value = converted_value + 1; /* make old_value different */
for( ce = SwitchStack->case_list; ce; ce = ce->next_case ) {
old_value = ce->value;
if( old_value >= converted_value ) break;
prev_ce = ce;
}
if( converted_value == old_value ) { /* duplicate case value found */
sprintf( buffer, SwitchStack->case_format, value );
CErr2p( ERR_DUPLICATE_CASE_VALUE, buffer );
} else {
new_ce = (CASEPTR) CMemAlloc( sizeof( CASEDEFN ) );
new_ce->value = converted_value;
new_ce->label = NextLabel();
if( prev_ce == NULL ) {
new_ce->next_case = SwitchStack->case_list;
SwitchStack->case_list = new_ce;
} else {
prev_ce->next_case = new_ce;
new_ce->next_case = ce;
}
SwitchStack->number_of_cases++;
if( converted_value < SwitchStack->low_value ) {
SwitchStack->low_value = converted_value;
}
if( converted_value > SwitchStack->high_value ) {
SwitchStack->high_value = converted_value;
}
tree = LeafNode( OPR_CASE );
tree->op.label_index = new_ce->label;
AddStmt( tree );
}
}
static void CaseStmt( void )
{
const_val val;
NextToken();
if( SwitchStack ) {
if( ConstExprAndType( &val ) ){
AddCaseLabel( val.val32 );
}
MustRecog( T_COLON );
if( CurToken == T_RIGHT_BRACE ) {
CErr1( ERR_STMT_REQUIRED_AFTER_CASE );
}
// FlushScoreBoard();
} else {
CErr1( ERR_MISPLACED_CASE );
ConstExprAndType( &val ); /* grab constant expression */
MustRecog( T_COLON );
}
}
#ifdef __SEH__
static void MarkTryVolatile( SYM_HANDLE sym_handle )
{
SYM_ENTRY sym;
for(;;) {
if( sym_handle == 0 ) break;
SymGet( &sym, sym_handle );
sym.flags |= SYM_TRY_VOLATILE; //force into memory
SymReplace( &sym, sym_handle );
sym_handle = sym.handle;
}
}
static void TryStmt( void )
{
TREEPTR tree;
MarkTryVolatile( CurFunc->u.func.parms );
MarkTryVolatile( CurFunc->u.func.locals );
CurFuncNode->op.func.flags |= FUNC_USES_SEH;
CurFuncNode->op.func.flags &= ~FUNC_OK_TO_INLINE;
CurToken = T__TRY;
startNewBlock();
NextToken();
BlockStack->parent_index = TryScope;
++TryCount;
BlockStack->try_index = TryCount;
TryScope = TryCount;
tree = LeafNode( OPR_TRY );
tree->op.try_index = 0;
tree->op.parent_scope = TryCount;
AddStmt( tree );
}
static SYM_HANDLE DummyTrySymbol( void )
{
SYM_ENTRY sym;
SYM_HANDLE sym_handle;
sym_handle = MakeNewSym( &sym, 'T', GetType( TYPE_VOID ), SC_STATIC );
SymReplace( &sym, sym_handle );
return( sym_handle );
}
static int EndTry( void )
{
int parent_scope;
TREEPTR expr;
TREEPTR func;
TREEPTR tree;
TYPEPTR typ;
int expr_type;
DropBreakLabel(); /* _leave jumps to this label */
parent_scope = BlockStack->parent_index;
tree = LeafNode( OPR_TRY );
tree->op.try_index = BlockStack->try_index;
tree->op.parent_scope = parent_scope;
AddStmt( tree );
if( CurToken == T__EXCEPT ) {
NextToken();
BlockStack->block_type = T__EXCEPT;
BlockStack->break_label = NextLabel();
Jump( BlockStack->break_label );
DeadCode = 0;
tree = LeafNode( OPR_EXCEPT );
tree->op.try_sym_handle = DummyTrySymbol();
tree->op.parent_scope = parent_scope;
AddStmt( tree );
CompFlags.exception_filter_expr = 1;
expr = RValue( BracketExpr() );
CompFlags.exception_filter_expr = 0;
CompFlags.exception_handler = 1;
typ = TypeOf( expr );
expr_type = DataTypeOf( typ->decl_type );
if( expr_type != TYPE_VOID ) {
if( expr_type > TYPE_ULONG ) {
CErr1( ERR_EXPR_MUST_BE_INTEGRAL );
}
}
func = VarLeaf( SymGetPtr( SymExcept ), SymExcept );
func->op.opr = OPR_FUNCNAME;
expr = ExprNode( NULL, OPR_PARM, expr );
expr->expr_type = typ;
expr->op.result_type = typ;
tree = ExprNode( func, OPR_CALL, expr );
tree->expr_type = GetType( TYPE_VOID );
AddStmt( tree );
return( 1 );
} else if( CurToken == T__FINALLY ) {
CompFlags.in_finally_block = 1;
NextToken();
BlockStack->block_type = T__FINALLY;
DeadCode = 0;
tree = LeafNode( OPR_FINALLY );
tree->op.try_sym_handle = DummyTrySymbol();
tree->op.parent_scope = parent_scope;
AddStmt( tree );
return( 1 );
}
return( 0 );
}
#endif
static void UnWindTry( int try_scope )
{
#ifdef __SEH__
TREEPTR tree;
tree = LeafNode( OPR_UNWIND );
tree->op.try_index = try_scope;
AddStmt( tree );
#else
try_scope = try_scope;
#endif
}
static void NewLoop( void )
{
startNewBlock();
LoopStack = BlockStack;
LoopStack->top_label = NextLabel();
DropLabel( LoopStack->top_label );
++LoopDepth;
}
static void startNewBlock( void )
{
BLOCKPTR block;
block = (BLOCKPTR) CMemAlloc( sizeof( BLOCKDEFN ) );
block->block_type = CurToken;
block->top_label = 0;
block->continue_label = 0;
block->break_label = 0;
block->prev_block = BlockStack;
block->prev_loop = LoopStack;
BlockStack = block;
}
static void PopBlock( void )
{
BLOCKPTR block;
TREEPTR tree;
if( BlockStack->sym_list != 0 ) {
tree = LeafNode( OPR_ENDBLOCK );
tree->op.sym_handle = BlockStack->sym_list;
AddStmt( tree );
AddSymList( BlockStack->sym_list );
}
block = BlockStack;
LoopStack = block->prev_loop;
BlockStack = block->prev_block;
CMemFree( block );
}
static void SwitchStmt( void )
{
SWITCHPTR sw;
TREEPTR tree;
TYPEPTR typ;
int switch_type;
startNewBlock();
NextToken();
sw = (SWITCHPTR) CMemAlloc( sizeof( SWITCHDEFN ) );
sw->prev_switch = SwitchStack;
sw->low_value = ~0l;
sw->high_value = 0;
sw->case_format = "%ld"; /* assume signed cases */
SwitchStack = sw;
switch_type = TYPE_INT; /* assume int */
tree = RValue( BracketExpr() );
typ = TypeOf( tree );
if( typ->decl_type == TYPE_ENUM ) typ = typ->object;
if( typ->decl_type == TYPE_UFIELD ) {
if( typ->u.f.field_width == (TARGET_INT * 8) ) {
sw->case_format = "%lu";
switch_type = TYPE_UINT;
}
}
switch( typ->decl_type ) {
case TYPE_USHORT:
case TYPE_UINT:
sw->case_format = "%lu";
switch_type = TYPE_UINT;
case TYPE_CHAR:
case TYPE_UCHAR:
case TYPE_SHORT:
case TYPE_INT:
case TYPE_FIELD:
case TYPE_UFIELD:
break;
case TYPE_ULONG:
sw->case_format = "%lu";
switch_type = TYPE_ULONG;
break;
case TYPE_LONG:
switch_type = TYPE_LONG;
break;
default:
CErr1( ERR_INVALID_TYPE_FOR_SWITCH );
}
tree = ExprNode( 0, OPR_SWITCH, tree );
tree->op.switch_info = sw;
AddStmt( tree );
}
static void EndSwitch( void )
{
SWITCHPTR sw;
// CASEPTR ce;
sw = SwitchStack;
SwitchStack = sw->prev_switch;
if( sw->default_label == 0 ) {
if( BlockStack->break_label == 0 ) {
sw->default_label = NextLabel();
DropLabel( sw->default_label );
} else {
sw->default_label = BlockStack->break_label;
}
}
// if( sw->case_list == NULL ) {
// CWarn1( WARN_EMPTY_SWITCH, ERR_EMPTY_SWITCH );
// }
#if 0
for( ; ce = sw->case_list; ) {
sw->case_list = ce->next_case;
CMemFree( ce );
}
CMemFree( sw );
#endif
// FlushScoreBoard();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -