Changeset 6e1e2d0 for src/Parser/StatementNode.cc
- Timestamp:
- May 1, 2023, 4:19:09 PM (14 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- c083c3d
- Parents:
- a50fdfb (diff), 985b624 (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
ra50fdfb r6e1e2d0 11 11 // Created On : Sat May 16 14:59:41 2015 12 12 // Last Modified By : Andrew Beach 13 // Last Modified On : Tue Apr 4 11:40:00 202314 // Update Count : 42 713 // Last Modified On : Tue Apr 11 10:16:00 2023 14 // Update Count : 428 15 15 // 16 17 #include "StatementNode.h" 16 18 17 19 #include <cassert> // for assert, strict_dynamic_cast, assertf … … 23 25 #include "Common/SemanticError.h" // for SemanticError 24 26 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild 25 #include "ParseNode.h" // for StatementNode, ExpressionNode, bui... 27 #include "DeclarationNode.h" // for DeclarationNode 28 #include "ExpressionNode.h" // for ExpressionNode 26 29 #include "parserutility.h" // for notZeroExpr 27 30 … … 29 32 30 33 using namespace std; 34 35 // Some helpers for cases that really want a single node but check for lists. 36 static const ast::Stmt * buildMoveSingle( StatementNode * node ) { 37 std::vector<ast::ptr<ast::Stmt>> list; 38 buildMoveList( node, list ); 39 assertf( list.size() == 1, "CFA Internal Error: Extra/Missing Nodes" ); 40 return list.front().release(); 41 } 42 43 static const ast::Stmt * buildMoveOptional( StatementNode * node ) { 44 std::vector<ast::ptr<ast::Stmt>> list; 45 buildMoveList( node, list ); 46 assertf( list.size() <= 1, "CFA Internal Error: Extra Nodes" ); 47 return list.empty() ? nullptr : list.front().release(); 48 } 31 49 32 50 StatementNode::StatementNode( DeclarationNode * decl ) { … … 53 71 } // StatementNode::StatementNode 54 72 55 StatementNode * StatementNode::append_last_case( StatementNode * stmt ) { 56 StatementNode * prev = this; 73 StatementNode * StatementNode::add_label( 74 const CodeLocation & location, 75 const std::string * name, 76 DeclarationNode * attr ) { 77 stmt->labels.emplace_back( location, 78 *name, 79 attr ? std::move( attr->attributes ) 80 : std::vector<ast::ptr<ast::Attribute>>{} ); 81 delete attr; 82 delete name; 83 return this; 84 } 85 86 ClauseNode * ClauseNode::append_last_case( StatementNode * stmt ) { 87 ClauseNode * prev = this; 57 88 // find end of list and maintain previous pointer 58 for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) { 59 StatementNode * node = strict_dynamic_cast< StatementNode * >(curr); 60 assert( nullptr == node->stmt.get() ); 89 for ( ClauseNode * curr = prev; curr != nullptr; curr = (ClauseNode *)curr->get_next() ) { 90 ClauseNode * node = strict_dynamic_cast< ClauseNode * >(curr); 61 91 assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) ); 62 92 prev = curr; 63 93 } // for 94 ClauseNode * node = dynamic_cast< ClauseNode * >(prev); 64 95 // convert from StatementNode list to Statement list 65 StatementNode * node = dynamic_cast< StatementNode * >(prev);66 96 std::vector<ast::ptr<ast::Stmt>> stmts; 67 97 buildMoveList( stmt, stmts ); … … 73 103 stmts.clear(); 74 104 return this; 75 } // StatementNode::append_last_case105 } // ClauseNode::append_last_case 76 106 77 107 ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) { … … 97 127 for ( ast::ptr<ast::Stmt> & stmt : inits ) { 98 128 // build the && of all of the declared variables compared against 0 99 //auto declStmt = strict_dynamic_cast<ast::DeclStmt *>( stmt );100 129 auto declStmt = stmt.strict_as<ast::DeclStmt>(); 101 //ast::DeclWithType * dwt = strict_dynamic_cast<ast::DeclWithType *>( declStmt->decl );102 130 auto dwt = declStmt->decl.strict_as<ast::DeclWithType>(); 103 131 ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) ); … … 113 141 ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 114 142 115 std::vector<ast::ptr<ast::Stmt>> aststmt; 116 buildMoveList( then, aststmt ); 117 assert( aststmt.size() == 1 ); 118 ast::Stmt const * astthen = aststmt.front().release(); 119 120 ast::Stmt const * astelse = nullptr; 121 if ( else_ ) { 122 std::vector<ast::ptr<ast::Stmt>> aststmt; 123 buildMoveList( else_, aststmt ); 124 assert( aststmt.size() == 1 ); 125 astelse = aststmt.front().release(); 126 } // if 143 ast::Stmt const * astthen = buildMoveSingle( then ); 144 ast::Stmt const * astelse = buildMoveOptional( else_ ); 127 145 128 146 return new ast::IfStmt( location, astcond, astthen, astelse, … … 131 149 } // build_if 132 150 133 // Temporary work around. Split StmtClause off from StatementNode. 134 template<typename clause_t> 135 static void buildMoveClauseList( StatementNode * firstNode, 136 std::vector<ast::ptr<clause_t>> & output ) { 137 SemanticErrorException errors; 138 std::back_insert_iterator<std::vector<ast::ptr<clause_t>>> 139 out( output ); 140 StatementNode * cur = firstNode; 141 142 while ( cur ) { 143 try { 144 auto clause = cur->clause.release(); 145 if ( auto result = dynamic_cast<clause_t *>( clause ) ) { 146 *out++ = result; 147 } else { 148 assertf(false, __PRETTY_FUNCTION__ ); 149 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." ); 150 } // if 151 } catch( SemanticErrorException & e ) { 152 errors.append( e ); 153 } // try 154 ParseNode * temp = cur->get_next(); 155 // Should not return nullptr, then it is non-homogeneous: 156 cur = dynamic_cast<StatementNode *>( temp ); 157 if ( !cur && temp ) { 158 SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." ); 159 } // if 160 } // while 161 if ( ! errors.isEmpty() ) { 162 throw errors; 163 } // if 164 // Usually in the wrapper. 165 delete firstNode; 166 } 167 168 ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) { 151 ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, ClauseNode * stmt ) { 169 152 std::vector<ast::ptr<ast::CaseClause>> aststmt; 170 buildMove ClauseList( stmt, aststmt );153 buildMoveList( stmt, aststmt ); 171 154 // If it is not a switch it is a choose statement. 172 155 if ( ! isSwitch ) { … … 190 173 } // build_switch 191 174 192 ast::CaseClause * build_case( ExpressionNode * ctl ) {175 ast::CaseClause * build_case( const CodeLocation & location, ExpressionNode * ctl ) { 193 176 // stmt starts empty and then added to 194 177 auto expr = maybeMoveBuild( ctl ); 195 return new ast::CaseClause( expr->location, expr, {} );178 return new ast::CaseClause( location, expr, {} ); 196 179 } // build_case 197 180 … … 205 188 ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 206 189 207 std::vector<ast::ptr<ast::Stmt>> aststmt; // loop body, compound created if empty208 buildMoveList( stmt, aststmt );209 assert( aststmt.size() == 1 );210 211 std::vector<ast::ptr<ast::Stmt>> astelse; // else clause, maybe empty212 buildMoveList( else_, astelse );213 assert( astelse.size() <= 1 );214 215 190 return new ast::WhileDoStmt( location, 216 191 astcond, 217 aststmt.front(),218 astelse.empty() ? nullptr : astelse.front().release(),192 buildMoveSingle( stmt ), 193 buildMoveOptional( else_ ), 219 194 std::move( astinit ), 220 false195 ast::While 221 196 ); 222 197 } // build_while 223 198 224 199 ast::Stmt * build_do_while( const CodeLocation & location, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) { 225 std::vector<ast::ptr<ast::Stmt>> aststmt; // loop body, compound created if empty226 buildMoveList( stmt, aststmt );227 assert( aststmt.size() == 1 ); // compound created if empty228 229 std::vector<ast::ptr<ast::Stmt>> astelse; // else clause, maybe empty230 buildMoveList( else_, astelse );231 assert( astelse.size() <= 1 );232 233 200 // do-while cannot have declarations in the contitional, so init is always empty 234 201 return new ast::WhileDoStmt( location, 235 202 notZeroExpr( maybeMoveBuild( ctl ) ), 236 aststmt.front(),237 astelse.empty() ? nullptr : astelse.front().release(),203 buildMoveSingle( stmt ), 204 buildMoveOptional( else_ ), 238 205 {}, 239 true206 ast::DoWhile 240 207 ); 241 208 } // build_do_while … … 251 218 astincr = maybeMoveBuild( forctl->change ); 252 219 delete forctl; 253 254 std::vector<ast::ptr<ast::Stmt>> aststmt; // loop body, compound created if empty255 buildMoveList( stmt, aststmt );256 assert( aststmt.size() == 1 );257 258 std::vector<ast::ptr<ast::Stmt>> astelse; // else clause, maybe empty259 buildMoveList( else_, astelse );260 assert( astelse.size() <= 1 );261 220 262 221 return new ast::ForStmt( location, … … 264 223 astcond, 265 224 astincr, 266 aststmt.front(),267 astelse.empty() ? nullptr : astelse.front().release()225 buildMoveSingle( stmt ), 226 buildMoveOptional( else_ ) 268 227 ); 269 228 } // build_for … … 326 285 } // build_resume_at 327 286 328 ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) {287 ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, ClauseNode * catch_, ClauseNode * finally_ ) { 329 288 std::vector<ast::ptr<ast::CatchClause>> aststmt; 330 buildMove ClauseList( catch_, aststmt );289 buildMoveList( catch_, aststmt ); 331 290 ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) ); 332 291 ast::FinallyClause * finallyBlock = nullptr; … … 342 301 343 302 ast::CatchClause * build_catch( const CodeLocation & location, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) { 344 std::vector<ast::ptr<ast::Stmt>> aststmt;345 buildMoveList( body, aststmt );346 assert( aststmt.size() == 1 );347 303 return new ast::CatchClause( location, 348 304 kind, 349 305 maybeMoveBuild( decl ), 350 306 maybeMoveBuild( cond ), 351 aststmt.front().release()307 buildMoveSingle( body ) 352 308 ); 353 309 } // build_catch 354 310 355 311 ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) { 356 std::vector<ast::ptr<ast::Stmt>> aststmt;357 buildMoveList( stmt, aststmt );358 assert( aststmt.size() == 1 );359 312 return new ast::FinallyClause( location, 360 aststmt.front().strict_as<ast::CompoundStmt>() 313 strict_dynamic_cast<const ast::CompoundStmt *>( 314 buildMoveSingle( stmt ) 315 ) 361 316 ); 362 317 } // build_finally 363 318 364 ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Type type ) { 365 std::vector<ast::ptr<ast::Stmt>> stmts; 366 buildMoveList( then, stmts ); 367 ast::CompoundStmt const * then2 = nullptr; 368 if(!stmts.empty()) { 369 assert( stmts.size() == 1 ); 370 then2 = stmts.front().strict_as<ast::CompoundStmt>(); 371 } 372 auto node = new ast::SuspendStmt( location, then2, ast::SuspendStmt::None ); 373 node->type = type; 374 return node; 319 ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Kind kind ) { 320 return new ast::SuspendStmt( location, 321 strict_dynamic_cast<const ast::CompoundStmt *, nullptr>( 322 buildMoveOptional( then ) 323 ), 324 kind 325 ); 375 326 } // build_suspend 376 327 … … 525 476 526 477 // Question 527 ast::Stmt * build_asm( const CodeLocation & location, bool voltile, ast::Expr* instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {478 ast::Stmt * build_asm( const CodeLocation & location, bool is_volatile, ExpressionNode * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) { 528 479 std::vector<ast::ptr<ast::Expr>> out, in; 529 480 std::vector<ast::ptr<ast::ConstantExpr>> clob; … … 533 484 buildMoveList( clobber, clob ); 534 485 return new ast::AsmStmt( location, 535 voltile,536 instruction,486 is_volatile, 487 maybeMoveBuild( instruction ), 537 488 std::move( out ), 538 489 std::move( in ),
Note: See TracChangeset
for help on using the changeset viewer.