Changeset 04cdd9b for src/Parser/StatementNode.cc
- Timestamp:
- Aug 19, 2016, 2:42:04 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- e85a8631
- Parents:
- 03da511 (diff), ac71a86 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/StatementNode.cc
r03da511 r04cdd9b 10 10 // Created On : Sat May 16 14:59:41 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Aug 7 06:42:38201613 // Update Count : 13512 // Last Modified On : Mon Aug 15 20:47:11 2016 13 // Update Count : 322 14 14 // 15 15 … … 26 26 using namespace std; 27 27 28 const char *StatementNode::StType[] = { 29 "Exp", "If", "Switch", "Case", "Default", "Choose", "Fallthru", 30 "While", "Do", "For", 31 "Goto", "Continue", "Break", "Return", "Throw", 32 "Try", "Catch", "Finally", "Asm", 33 "Decl" 34 }; 35 36 StatementNode::StatementNode() : ParseNode(), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false ) {} 37 38 StatementNode::StatementNode( const string *name ) : ParseNode( name ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false ) {} 39 40 StatementNode::StatementNode( DeclarationNode *decl ) : type( Decl ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), isCatchRest ( false ) { 28 29 StatementNode::StatementNode( DeclarationNode *decl ) { 41 30 if ( decl ) { 42 if ( DeclarationNode *agg = decl->extractAggregate() ) { 43 this->decl = agg; 44 StatementNode *nextStmt = new StatementNode; 45 nextStmt->type = Decl; 46 nextStmt->decl = decl; 47 next = nextStmt; 48 if ( decl->get_link() ) { 49 next->set_next( new StatementNode( dynamic_cast< DeclarationNode* >( decl->get_link() ) ) ); 31 DeclarationNode *agg = decl->extractAggregate(); 32 if ( agg ) { 33 StatementNode *nextStmt = new StatementNode( new DeclStmt( noLabels, maybeBuild< Declaration >( decl ) ) ); 34 set_next( nextStmt ); 35 if ( decl->get_next() ) { 36 get_next()->set_next( new StatementNode( dynamic_cast< DeclarationNode * >(decl->get_next()) ) ); 50 37 decl->set_next( 0 ); 51 38 } // if 52 39 } else { 53 if ( decl->get_ link() ) {54 next = new StatementNode( dynamic_cast< DeclarationNode* >( decl->get_link() ) );40 if ( decl->get_next() ) { 41 set_next(new StatementNode( dynamic_cast< DeclarationNode * >( decl->get_next() ) ) ); 55 42 decl->set_next( 0 ); 56 43 } // if 57 this->decl= decl;44 agg = decl; 58 45 } // if 46 stmt.reset( new DeclStmt( noLabels, maybeBuild< Declaration >(agg) ) ); 47 } else { 48 assert( false ); 59 49 } // if 60 50 } 61 51 62 StatementNode::StatementNode( Type t, ExpressionNode *ctrl_label, StatementNode *block ) : type( t ), control( ctrl_label ), block( block ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false ) { 63 this->control = ( t == Default ) ? 0 : control; 64 } 65 66 StatementNode::StatementNode( Type t, string *target ) : type( t ), control( 0 ), block( 0 ), labels( 0 ), target( target ), decl( 0 ), isCatchRest ( false ) {} 67 68 StatementNode::~StatementNode() { 69 delete control; 70 delete block; 71 delete target; 72 delete decl; 73 } 74 75 StatementNode * StatementNode::newCatchStmt( DeclarationNode *d, StatementNode *s, bool catchRestP ) { 76 StatementNode *ret = new StatementNode( StatementNode::Catch, 0, s ); 77 ret->addDeclaration( d ); 78 ret->setCatchRest( catchRestP ); 79 80 return ret; 81 } 82 83 std::string StatementNode::get_target() const{ 84 if ( target ) 85 return *target; 86 87 return string(""); 88 } 89 90 StatementNode * StatementNode::clone() const { 91 StatementNode *newnode = new StatementNode( type, maybeClone( control ), maybeClone( block ) ); 92 if ( target ) { 93 newnode->target = new string( *target ); 94 } else { 95 newnode->target = 0; 52 StatementNode *StatementNode::append_last_case( StatementNode *stmt ) { 53 StatementNode *prev = this; 54 // find end of list and maintain previous pointer 55 for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) { 56 StatementNode *node = dynamic_cast< StatementNode * >(curr); 57 assert( node ); 58 assert( dynamic_cast< CaseStmt * >(node->stmt.get()) ); 59 prev = curr; 60 } // for 61 // convert from StatementNode list to Statement list 62 StatementNode *node = dynamic_cast< StatementNode * >(prev); 63 std::list< Statement * > stmts; 64 buildMoveList( stmt, stmts ); 65 // splice any new Statements to end of current Statements 66 CaseStmt * caseStmt = dynamic_cast< CaseStmt * >(node->stmt.get()); 67 caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts ); 68 return this; 69 } 70 71 Statement *build_expr( ExpressionNode *ctl ) { 72 Expression *e = maybeMoveBuild< Expression >( ctl ); 73 74 if ( e ) 75 return new ExprStmt( noLabels, e ); 76 else 77 return new NullStmt( noLabels ); 78 } 79 80 Statement *build_if( ExpressionNode *ctl, StatementNode *then_stmt, StatementNode *else_stmt ) { 81 Statement *thenb, *elseb = 0; 82 std::list< Statement * > branches; 83 buildMoveList< Statement, StatementNode >( then_stmt, branches ); 84 assert( branches.size() == 1 ); 85 thenb = branches.front(); 86 87 if ( else_stmt ) { 88 std::list< Statement * > branches; 89 buildMoveList< Statement, StatementNode >( else_stmt, branches ); 90 assert( branches.size() == 1 ); 91 elseb = branches.front(); 96 92 } // if 97 newnode->decl = maybeClone( decl ); 98 return newnode; 99 } 100 101 StatementNode *StatementNode::add_label( const std::string *l ) { 102 if ( l != 0 ) { 103 labels.push_front( *l ); 104 delete l; 93 return new IfStmt( noLabels, notZeroExpr( maybeMoveBuild< Expression >(ctl) ), thenb, elseb ); 94 } 95 96 Statement *build_switch( ExpressionNode *ctl, StatementNode *stmt ) { 97 std::list< Statement * > branches; 98 buildMoveList< Statement, StatementNode >( stmt, branches ); 99 assert( branches.size() >= 0 ); // size == 0 for switch (...) {}, i.e., no declaration or statements 100 return new SwitchStmt( noLabels, maybeMoveBuild< Expression >(ctl), branches ); 101 } 102 Statement *build_case( ExpressionNode *ctl ) { 103 std::list< Statement * > branches; 104 return new CaseStmt( noLabels, maybeMoveBuild< Expression >(ctl), branches ); 105 } 106 Statement *build_default() { 107 std::list< Statement * > branches; 108 return new CaseStmt( noLabels, nullptr, branches, true ); 109 } 110 111 Statement *build_while( ExpressionNode *ctl, StatementNode *stmt, bool kind ) { 112 std::list< Statement * > branches; 113 buildMoveList< Statement, StatementNode >( stmt, branches ); 114 assert( branches.size() == 1 ); 115 return new WhileStmt( noLabels, notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), kind ); 116 } 117 118 Statement *build_for( ForCtl *forctl, StatementNode *stmt ) { 119 std::list< Statement * > branches; 120 buildMoveList< Statement, StatementNode >( stmt, branches ); 121 assert( branches.size() == 1 ); 122 123 std::list< Statement * > init; 124 if ( forctl->init != 0 ) { 125 buildMoveList( forctl->init, init ); 105 126 } // if 106 return this; 107 } 108 109 StatementNode *StatementNode::append_block( StatementNode *stmt ) { 110 if ( stmt != 0 ) { 111 if ( block == 0 ) 112 block = stmt; 113 else 114 block->set_link( stmt ); 115 } // if 116 return this; 117 } 118 119 StatementNode *StatementNode::append_last_case( StatementNode *stmt ) { 120 if ( stmt != 0 ) { 121 StatementNode *next = ( StatementNode *)get_link(); 122 if ( next && ( next->get_type() == StatementNode::Case || next->get_type() == StatementNode::Default ) ) 123 next->append_last_case ( stmt ); 124 else 125 if ( block == 0 ) 126 block = stmt; 127 else 128 block->set_link( stmt ); 129 } // if 130 return this; 131 } 132 133 void StatementNode::print( std::ostream &os, int indent ) const { 134 if ( ! labels.empty() ) { 135 std::list<std::string>::const_iterator i; 136 137 os << string( indent, ' ' ); 138 for ( i = labels.begin(); i != labels.end(); i++ ) 139 os << *i << ":"; 140 os << endl; 141 } // if 142 143 switch ( type ) { 144 case Decl: 145 decl->print( os, indent ); 146 break; 147 case Exp: 148 if ( control ) { 149 os << string( indent, ' ' ); 150 control->print( os, indent ); 151 os << endl; 152 } else 153 os << string( indent, ' ' ) << "Null Statement" << endl; 154 break; 155 default: 156 os << string( indent, ' ' ) << StatementNode::StType[type] << endl; 157 if ( type == Catch ) { 158 if ( decl ) { 159 os << string( indent + ParseNode::indent_by, ' ' ) << "Declaration: " << endl; 160 decl->print( os, indent + 2 * ParseNode::indent_by ); 161 } else if ( isCatchRest ) { 162 os << string( indent + ParseNode::indent_by, ' ' ) << "Catches the rest " << endl; 163 } else { 164 ; // should never reach here 165 } // if 166 } // if 167 if ( control ) { 168 os << string( indent + ParseNode::indent_by, ' ' ) << "Control: " << endl; 169 control->printList( os, indent + 2 * ParseNode::indent_by ); 170 } // if 171 if ( block ) { 172 os << string( indent + ParseNode::indent_by, ' ' ) << "Cases: " << endl; 173 block->printList( os, indent + 2 * ParseNode::indent_by ); 174 } // if 175 if ( target ) { 176 os << string( indent + ParseNode::indent_by, ' ' ) << "Target: " << get_target() << endl; 177 } // if 178 break; 179 } // switch 180 } 181 182 Statement *StatementNode::build() const { 183 std::list<Statement *> branches; 184 std::list<Expression *> exps; 185 std::list<Label> labs; 186 187 if ( ! labels.empty() ) { 188 std::back_insert_iterator< std::list<Label> > lab_it( labs ); 189 copy( labels.begin(), labels.end(), lab_it ); 190 } // if 191 192 // try { 193 buildList<Statement, StatementNode>( get_block(), branches ); 194 195 switch ( type ) { 196 case Decl: 197 return new DeclStmt( labs, maybeBuild< Declaration >( decl ) ); 198 case Exp: 199 { 200 Expression *e = maybeBuild< Expression >( get_control() ); 201 202 if ( e ) 203 return new ExprStmt( labs, e ); 204 else 205 return new NullStmt( labs ); 206 } 207 case If: 208 { 209 Statement *thenb = 0, *elseb = 0; 210 assert( branches.size() >= 1 ); 211 212 thenb = branches.front(); 213 branches.pop_front(); 214 if ( ! branches.empty() ) { 215 elseb = branches.front(); 216 branches.pop_front(); 217 } // if 218 return new IfStmt( labs, notZeroExpr( maybeBuild<Expression>(get_control()) ), thenb, elseb ); 219 } 220 case While: 221 assert( branches.size() == 1 ); 222 return new WhileStmt( labs, notZeroExpr( maybeBuild<Expression>(get_control()) ), branches.front() ); 223 case Do: 224 assert( branches.size() == 1 ); 225 return new WhileStmt( labs, notZeroExpr( maybeBuild<Expression>(get_control()) ), branches.front(), true ); 226 case For: 227 { 228 assert( branches.size() == 1 ); 229 230 ForCtlExprNode *ctl = dynamic_cast<ForCtlExprNode *>( get_control() ); 231 assert( ctl != 0 ); 232 233 std::list<Statement *> init; 234 if ( ctl->get_init() != 0 ) { 235 buildList( ctl->get_init(), init ); 236 } // if 237 238 Expression *cond = 0; 239 if ( ctl->get_condition() != 0 ) 240 cond = notZeroExpr( maybeBuild<Expression>(ctl->get_condition()) ); 241 242 Expression *incr = 0; 243 if ( ctl->get_change() != 0 ) 244 incr = maybeBuild<Expression>(ctl->get_change()); 245 246 return new ForStmt( labs, init, cond, incr, branches.front() ); 247 } 248 case Switch: 249 return new SwitchStmt( labs, maybeBuild<Expression>(get_control()), branches ); 250 case Case: 251 return new CaseStmt( labs, maybeBuild<Expression>(get_control()), branches ); 252 case Default: 253 return new CaseStmt( labs, 0, branches, true ); 254 case Goto: 255 { 256 if ( get_target() == "" ) { // computed goto 257 assert( get_control() != 0 ); 258 return new BranchStmt( labs, maybeBuild<Expression>(get_control()), BranchStmt::Goto ); 259 } // if 260 261 return new BranchStmt( labs, get_target(), BranchStmt::Goto ); 262 } 263 case Break: 264 return new BranchStmt( labs, get_target(), BranchStmt::Break ); 265 case Continue: 266 return new BranchStmt( labs, get_target(), BranchStmt::Continue ); 267 case Return: 268 case Throw : 269 buildList( get_control(), exps ); 270 if ( exps.size() ==0 ) 271 return new ReturnStmt( labs, 0, type == Throw ); 272 if ( exps.size() > 0 ) 273 return new ReturnStmt( labs, exps.back(), type == Throw ); 274 case Try: 275 { 276 assert( branches.size() >= 0 ); 277 CompoundStmt *tryBlock = dynamic_cast<CompoundStmt *>( branches.front()); 278 branches.pop_front(); 279 FinallyStmt *finallyBlock = 0; 280 if ( ( finallyBlock = dynamic_cast<FinallyStmt *>( branches.back())) ) { 281 branches.pop_back(); 282 } // if 283 return new TryStmt( labs, tryBlock, branches, finallyBlock ); 284 } 285 case Catch: 286 { 287 assert( branches.size() == 1 ); 288 289 return new CatchStmt( labs, maybeBuild< Declaration >( decl ), branches.front(), isCatchRest ); 290 } 291 case Finally: 292 { 293 assert( branches.size() == 1 ); 294 CompoundStmt *block = dynamic_cast<CompoundStmt *>( branches.front() ); 295 assert( block != 0 ); 296 297 return new FinallyStmt( labs, block ); 298 } 299 case Asm: 300 assert( false ); 301 default: 302 // shouldn't be here 303 return 0; 304 } // switch 305 } 306 307 308 CompoundStmtNode::CompoundStmtNode() : first( 0 ), last( 0 ) {} 309 310 CompoundStmtNode::CompoundStmtNode( const string *name_ ) : StatementNode( name_ ), first( 0 ), last( 0 ) {} 311 312 CompoundStmtNode::CompoundStmtNode( StatementNode *stmt ) : first( stmt ) { 313 if ( first ) { 314 last = ( StatementNode *)( stmt->get_last()); 315 } else { 316 last = 0; 317 } // if 318 } 319 320 CompoundStmtNode::~CompoundStmtNode() { 321 delete first; 322 } 323 324 void CompoundStmtNode::add_statement( StatementNode *stmt ) { 325 if ( stmt != 0 ) { 326 last->set_link( stmt ); 327 last = ( StatementNode *)( stmt->get_link()); 328 } // if 329 } 330 331 void CompoundStmtNode::print( ostream &os, int indent ) const { 332 if ( first ) { 333 first->printList( os, indent+2 ); 334 } // if 335 } 336 337 Statement *CompoundStmtNode::build() const { 338 std::list<Label> labs; 339 const std::list<std::string> &labels = get_labels(); 340 341 if ( ! labels.empty() ) { 342 std::back_insert_iterator< std::list<Label> > lab_it( labs ); 343 copy( labels.begin(), labels.end(), lab_it ); 344 } // if 345 346 CompoundStmt *cs = new CompoundStmt( labs ); 347 buildList( first, cs->get_kids() ); 127 128 Expression *cond = 0; 129 if ( forctl->condition != 0 ) 130 cond = notZeroExpr( maybeMoveBuild< Expression >(forctl->condition) ); 131 132 Expression *incr = 0; 133 if ( forctl->change != 0 ) 134 incr = maybeMoveBuild< Expression >(forctl->change); 135 136 delete forctl; 137 return new ForStmt( noLabels, init, cond, incr, branches.front() ); 138 } 139 140 Statement *build_branch( std::string identifier, BranchStmt::Type kind ) { 141 return new BranchStmt( noLabels, identifier, kind ); 142 } 143 Statement *build_computedgoto( ExpressionNode *ctl ) { 144 return new BranchStmt( noLabels, maybeMoveBuild< Expression >(ctl), BranchStmt::Goto ); 145 } 146 147 Statement *build_return( ExpressionNode *ctl ) { 148 std::list< Expression * > exps; 149 buildMoveList( ctl, exps ); 150 return new ReturnStmt( noLabels, exps.size() > 0 ? exps.back() : nullptr ); 151 } 152 Statement *build_throw( ExpressionNode *ctl ) { 153 std::list< Expression * > exps; 154 buildMoveList( ctl, exps ); 155 assertf( exps.size() < 2, "This means we are leaking memory"); 156 return new ReturnStmt( noLabels, !exps.empty() ? exps.back() : nullptr, true ); 157 } 158 159 Statement *build_try( StatementNode *try_stmt, StatementNode *catch_stmt, StatementNode *finally_stmt ) { 160 std::list< Statement * > branches; 161 buildMoveList< Statement, StatementNode >( catch_stmt, branches ); 162 CompoundStmt *tryBlock = dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >(try_stmt)); 163 assert( tryBlock ); 164 FinallyStmt *finallyBlock = dynamic_cast< FinallyStmt * >(maybeMoveBuild< Statement >(finally_stmt) ); 165 return new TryStmt( noLabels, tryBlock, branches, finallyBlock ); 166 } 167 Statement *build_catch( DeclarationNode *decl, StatementNode *stmt, bool catchAny ) { 168 std::list< Statement * > branches; 169 buildMoveList< Statement, StatementNode >( stmt, branches ); 170 assert( branches.size() == 1 ); 171 return new CatchStmt( noLabels, maybeMoveBuild< Declaration >(decl), branches.front(), catchAny ); 172 } 173 Statement *build_finally( StatementNode *stmt ) { 174 std::list< Statement * > branches; 175 buildMoveList< Statement, StatementNode >( stmt, branches ); 176 assert( branches.size() == 1 ); 177 return new FinallyStmt( noLabels, dynamic_cast< CompoundStmt * >( branches.front() ) ); 178 } 179 180 Statement *build_compound( StatementNode *first ) { 181 CompoundStmt *cs = new CompoundStmt( noLabels ); 182 buildMoveList( first, cs->get_kids() ); 348 183 return cs; 349 184 } 350 185 351 352 AsmStmtNode::AsmStmtNode( Type t, bool voltile, ConstantNode *instruction, ExpressionNode *output, ExpressionNode *input, ConstantNode *clobber, LabelNode *gotolabels ) : 353 StatementNode( t ), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ) { 354 if ( gotolabels ) { 355 this->gotolabels = gotolabels->get_labels(); 356 delete gotolabels; 357 } // if 358 } 359 360 AsmStmtNode::~AsmStmtNode() { 361 delete instruction; delete output; delete input; delete clobber; 362 } 363 364 void AsmStmtNode::print( std::ostream &os, int indent ) const { 365 StatementNode::print( os, indent ); // print statement labels 366 os << string( indent + ParseNode::indent_by, ' ' ) << "volatile:" << voltile << endl; 367 if ( instruction ) { 368 os << string( indent + ParseNode::indent_by, ' ' ) << "Instruction:" << endl; 369 instruction->printList( os, indent + 2 * ParseNode::indent_by ); 370 } // if 371 if ( output ) { 372 os << string( indent + ParseNode::indent_by, ' ' ) << "Output:" << endl; 373 output->printList( os, indent + 2 * ParseNode::indent_by ); 374 } // if 375 if ( input ) { 376 os << string( indent + ParseNode::indent_by, ' ' ) << "Input:" << endl; 377 input->printList( os, indent + 2 * ParseNode::indent_by ); 378 } // if 379 if ( clobber ) { 380 os << string( indent + ParseNode::indent_by, ' ' ) << "Clobber:" << endl; 381 clobber->printList( os, indent + 2 * ParseNode::indent_by ); 382 } // if 383 if ( ! gotolabels.empty() ) { 384 os << string( indent + ParseNode::indent_by, ' ' ) << "Goto Labels:" << endl; 385 os << string( indent + 2 * ParseNode::indent_by, ' ' ); 386 for ( std::list<Label>::const_iterator i = gotolabels.begin();; ) { 387 os << *i; 388 i++; 389 if ( i == gotolabels.end() ) break; 390 os << ", "; 391 } 392 os << endl; 393 } // if 394 } 395 396 Statement *AsmStmtNode::build() const { 397 std::list<Label> labs; 398 399 if ( ! get_labels().empty() ) { 400 std::back_insert_iterator< std::list<Label> > lab_it( labs ); 401 copy( get_labels().begin(), get_labels().end(), lab_it ); 402 } // if 403 186 Statement *build_asmstmt( bool voltile, ConstantExpr *instruction, ExpressionNode *output, ExpressionNode *input, ExpressionNode *clobber, LabelNode *gotolabels ) { 404 187 std::list< Expression * > out, in; 405 188 std::list< ConstantExpr * > clob; 406 buildList( output, out ); 407 build List( input, in);408 build List( clobber, clob);409 std::list< Label > gotolabs = gotolabels;410 return new AsmStmt( labs, voltile, (ConstantExpr *)maybeBuild< Expression >( instruction ), out, in, clob, gotolabs );189 190 buildMoveList( output, out ); 191 buildMoveList( input, in ); 192 buildMoveList( clobber, clob ); 193 return new AsmStmt( noLabels, voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels ); 411 194 } 412 195
Note:
See TracChangeset
for help on using the changeset viewer.