Changeset bb7422a for src/Parser/StatementNode.cc
- Timestamp:
- Apr 4, 2023, 2:25:52 PM (15 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- beeff61e, e02e13f
- Parents:
- 4541b09
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/StatementNode.cc
r4541b09 rbb7422a 10 10 // Author : Rodolfo G. Esteves 11 11 // Created On : Sat May 16 14:59:41 2015 12 // Last Modified By : Peter A. Buhr13 // Last Modified On : Wed Mar 29 08:51:23202314 // Update Count : 4 5412 // Last Modified By : Andrew Beach 13 // Last Modified On : Tue Apr 4 11:40:00 2023 14 // Update Count : 427 15 15 // 16 16 17 17 #include <cassert> // for assert, strict_dynamic_cast, assertf 18 #include <list> // for list19 18 #include <memory> // for unique_ptr 20 19 #include <string> // for string 21 20 21 #include "AST/Label.hpp" // for Label 22 #include "AST/Stmt.hpp" // for Stmt, AsmStmt, BranchStmt, CaseCla... 22 23 #include "Common/SemanticError.h" // for SemanticError 23 24 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild 24 25 #include "ParseNode.h" // for StatementNode, ExpressionNode, bui... 25 #include "SynTree/Expression.h" // for Expression, ConstantExpr26 #include "SynTree/Label.h" // for Label, noLabels27 #include "SynTree/Declaration.h"28 #include "SynTree/Statement.h" // for Statement, BranchStmt, CaseStmt29 26 #include "parserutility.h" // for notZeroExpr 30 27 … … 32 29 33 30 using namespace std; 34 35 31 36 32 StatementNode::StatementNode( DeclarationNode * decl ) { … … 38 34 DeclarationNode * agg = decl->extractAggregate(); 39 35 if ( agg ) { 40 StatementNode * nextStmt = new StatementNode( new DeclStmt( maybeBuild( decl ) ) ); 36 StatementNode * nextStmt = new StatementNode( 37 new ast::DeclStmt( decl->location, maybeBuild( decl ) ) ); 41 38 set_next( nextStmt ); 42 39 if ( decl->get_next() ) { … … 51 48 agg = decl; 52 49 } // if 53 stmt.reset( new DeclStmt( maybeMoveBuild( agg ) ) ); 50 // Local copy to avoid accessing the pointer after it is moved from. 51 CodeLocation declLocation = agg->location; 52 stmt.reset( new ast::DeclStmt( declLocation, maybeMoveBuild( agg ) ) ); 54 53 } // StatementNode::StatementNode 55 54 … … 59 58 for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) { 60 59 StatementNode * node = strict_dynamic_cast< StatementNode * >(curr); 61 assert( dynamic_cast< CaseStmt * >(node->stmt.get()) ); 60 assert( nullptr == node->stmt.get() ); 61 assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) ); 62 62 prev = curr; 63 63 } // for 64 64 // convert from StatementNode list to Statement list 65 65 StatementNode * node = dynamic_cast< StatementNode * >(prev); 66 list< Statement *> stmts;66 std::vector<ast::ptr<ast::Stmt>> stmts; 67 67 buildMoveList( stmt, stmts ); 68 68 // splice any new Statements to end of current Statements 69 CaseStmt * caseStmt = dynamic_cast< CaseStmt * >(node->stmt.get()); 70 caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts ); 69 auto caseStmt = strict_dynamic_cast<ast::CaseClause *>( node->clause.get() ); 70 for ( auto const & newStmt : stmts ) { 71 caseStmt->stmts.emplace_back( newStmt ); 72 } 73 stmts.clear(); 71 74 return this; 72 75 } // StatementNode::append_last_case 73 76 74 Statement * build_expr( ExpressionNode * ctl ) { 75 Expression * e = maybeMoveBuild( ctl ); 76 77 if ( e ) return new ExprStmt( e ); 78 else return new NullStmt(); 77 ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) { 78 if ( ast::Expr * e = maybeMoveBuild( ctl ) ) { 79 return new ast::ExprStmt( location, e ); 80 } else { 81 return new ast::NullStmt( location ); 82 } 79 83 } // build_expr 80 84 81 Expression * build_if_control( CondCtl * ctl, list< Statement * > & init ) { 82 if ( ctl->init != 0 ) { 83 buildMoveList( ctl->init, init ); 84 } // if 85 86 Expression * cond = nullptr; 85 static ast::Expr * build_if_control( CondCtl * ctl, 86 std::vector<ast::ptr<ast::Stmt>> & inits ) { 87 assert( inits.empty() ); 88 if ( nullptr != ctl->init ) { 89 buildMoveList( ctl->init, inits ); 90 } // if 91 92 ast::Expr * cond = nullptr; 87 93 if ( ctl->condition ) { 88 94 // compare the provided condition against 0 89 95 cond = notZeroExpr( maybeMoveBuild( ctl->condition ) ); 90 96 } else { 91 for ( Statement * stmt : init) {97 for ( ast::ptr<ast::Stmt> & stmt : inits ) { 92 98 // build the && of all of the declared variables compared against 0 93 DeclStmt * declStmt = strict_dynamic_cast< DeclStmt * >( stmt ); 94 DeclarationWithType * dwt = strict_dynamic_cast< DeclarationWithType * >( declStmt->decl ); 95 Expression * nze = notZeroExpr( new VariableExpr( dwt ) ); 96 cond = cond ? new LogicalExpr( cond, nze, true ) : nze; 99 //auto declStmt = strict_dynamic_cast<ast::DeclStmt *>( stmt ); 100 auto declStmt = stmt.strict_as<ast::DeclStmt>(); 101 //ast::DeclWithType * dwt = strict_dynamic_cast<ast::DeclWithType *>( declStmt->decl ); 102 auto dwt = declStmt->decl.strict_as<ast::DeclWithType>(); 103 ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) ); 104 cond = cond ? new ast::LogicalExpr( dwt->location, cond, nze, ast::AndExpr ) : nze; 97 105 } 98 106 } … … 101 109 } // build_if_control 102 110 103 Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ ) { 104 list< Statement * > astinit; // maybe empty 105 Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 106 107 Statement * astthen, * astelse = nullptr; 108 list< Statement * > aststmt; 109 buildMoveList< Statement, StatementNode >( then, aststmt ); 111 ast::Stmt * build_if( const CodeLocation & location, CondCtl * ctl, StatementNode * then, StatementNode * else_ ) { 112 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty 113 ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 114 115 std::vector<ast::ptr<ast::Stmt>> aststmt; 116 buildMoveList( then, aststmt ); 110 117 assert( aststmt.size() == 1 ); 111 astthen = aststmt.front(); 112 118 ast::Stmt const * astthen = aststmt.front().release(); 119 120 ast::Stmt const * astelse = nullptr; 113 121 if ( else_ ) { 114 list< Statement *> aststmt;115 buildMoveList < Statement, StatementNode >( else_, aststmt );122 std::vector<ast::ptr<ast::Stmt>> aststmt; 123 buildMoveList( else_, aststmt ); 116 124 assert( aststmt.size() == 1 ); 117 astelse = aststmt.front(); 118 } // if 119 120 return new IfStmt( astcond, astthen, astelse, astinit ); 125 astelse = aststmt.front().release(); 126 } // if 127 128 return new ast::IfStmt( location, astcond, astthen, astelse, 129 std::move( astinit ) 130 ); 121 131 } // build_if 122 132 123 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) { 124 list< Statement * > aststmt; 125 buildMoveList< Statement, StatementNode >( stmt, aststmt ); 126 if ( ! isSwitch ) { // choose statement 127 for ( Statement * stmt : aststmt ) { 128 CaseStmt * caseStmt = strict_dynamic_cast< CaseStmt * >( stmt ); 129 if ( ! caseStmt->stmts.empty() ) { // code after "case" => end of case list 130 CompoundStmt * block = strict_dynamic_cast< CompoundStmt * >( caseStmt->stmts.front() ); 131 block->kids.push_back( new BranchStmt( "", BranchStmt::Break ) ); 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 ) { 169 std::vector<ast::ptr<ast::CaseClause>> aststmt; 170 buildMoveClauseList( stmt, aststmt ); 171 // If it is not a switch it is a choose statement. 172 if ( ! isSwitch ) { 173 for ( ast::ptr<ast::CaseClause> & stmt : aststmt ) { 174 // Code after "case" is the end of case list. 175 if ( !stmt->stmts.empty() ) { 176 auto mutStmt = ast::mutate( stmt.get() ); 177 // I believe the stmts are actually always one block. 178 auto stmts = mutStmt->stmts.front().get_and_mutate(); 179 auto block = strict_dynamic_cast<ast::CompoundStmt *>( stmts ); 180 block->kids.push_back( new ast::BranchStmt( block->location, 181 ast::BranchStmt::Break, 182 ast::Label( block->location ) ) ); 183 stmt = mutStmt; 132 184 } // if 133 185 } // for 134 186 } // if 135 187 // aststmt.size() == 0 for switch (...) {}, i.e., no declaration or statements 136 return new SwitchStmt( maybeMoveBuild( ctl ), aststmt ); 188 return new ast::SwitchStmt( location, 189 maybeMoveBuild( ctl ), std::move( aststmt ) ); 137 190 } // build_switch 138 191 139 Statement * build_case( ExpressionNode * ctl ) { 140 return new CaseStmt( maybeMoveBuild( ctl ), {} ); // stmt starts empty and then added to 192 ast::CaseClause * build_case( ExpressionNode * ctl ) { 193 // stmt starts empty and then added to 194 auto expr = maybeMoveBuild( ctl ); 195 return new ast::CaseClause( expr->location, expr, {} ); 141 196 } // build_case 142 197 143 Statement * build_default() { 144 return new CaseStmt( nullptr, {}, true ); // stmt starts empty and then added to 198 ast::CaseClause * build_default( const CodeLocation & location ) { 199 // stmt starts empty and then added to 200 return new ast::CaseClause( location, nullptr, {} ); 145 201 } // build_default 146 202 147 Statement * build_while(CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) {148 list< Statement *> astinit; // maybe empty149 Expression* astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set150 151 list< Statement *> aststmt; // loop body, compound created if empty152 buildMoveList < Statement, StatementNode >( stmt, aststmt );203 ast::Stmt * build_while( const CodeLocation & location, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) { 204 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty 205 ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 206 207 std::vector<ast::ptr<ast::Stmt>> aststmt; // loop body, compound created if empty 208 buildMoveList( stmt, aststmt ); 153 209 assert( aststmt.size() == 1 ); 154 210 155 list< Statement * > astelse; // else clause, maybe empty 156 buildMoveList< Statement, StatementNode >( else_, astelse ); 157 158 return new WhileDoStmt( astcond, aststmt.front(), astelse.front(), astinit, false ); 211 std::vector<ast::ptr<ast::Stmt>> astelse; // else clause, maybe empty 212 buildMoveList( else_, astelse ); 213 assert( astelse.size() <= 1 ); 214 215 return new ast::WhileDoStmt( location, 216 astcond, 217 aststmt.front(), 218 astelse.empty() ? nullptr : astelse.front().release(), 219 std::move( astinit ), 220 false 221 ); 159 222 } // build_while 160 223 161 Statement * build_do_while(ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) {162 list< Statement *> aststmt; // loop body, compound created if empty163 buildMoveList < Statement, StatementNode >( stmt, aststmt );224 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 empty 226 buildMoveList( stmt, aststmt ); 164 227 assert( aststmt.size() == 1 ); // compound created if empty 165 228 166 list< Statement * > astelse; // else clause, maybe empty 167 buildMoveList< Statement, StatementNode >( else_, astelse ); 229 std::vector<ast::ptr<ast::Stmt>> astelse; // else clause, maybe empty 230 buildMoveList( else_, astelse ); 231 assert( astelse.size() <= 1 ); 168 232 169 233 // do-while cannot have declarations in the contitional, so init is always empty 170 return new WhileDoStmt( notZeroExpr( maybeMoveBuild( ctl ) ), aststmt.front(), astelse.front(), {}, true ); 234 return new ast::WhileDoStmt( location, 235 notZeroExpr( maybeMoveBuild( ctl ) ), 236 aststmt.front(), 237 astelse.empty() ? nullptr : astelse.front().release(), 238 {}, 239 true 240 ); 171 241 } // build_do_while 172 242 173 Statement * build_for(ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {174 list< Statement *> astinit; // maybe empty243 ast::Stmt * build_for( const CodeLocation & location, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) { 244 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty 175 245 buildMoveList( forctl->init, astinit ); 176 246 177 Expression* astcond = nullptr; // maybe empty247 ast::Expr * astcond = nullptr; // maybe empty 178 248 astcond = notZeroExpr( maybeMoveBuild( forctl->condition ) ); 179 249 180 Expression* astincr = nullptr; // maybe empty250 ast::Expr * astincr = nullptr; // maybe empty 181 251 astincr = maybeMoveBuild( forctl->change ); 182 252 delete forctl; 183 253 184 list< Statement *> aststmt; // loop body, compound created if empty185 buildMoveList < Statement, StatementNode >( stmt, aststmt );254 std::vector<ast::ptr<ast::Stmt>> aststmt; // loop body, compound created if empty 255 buildMoveList( stmt, aststmt ); 186 256 assert( aststmt.size() == 1 ); 187 257 188 list< Statement * > astelse; // else clause, maybe empty 189 buildMoveList< Statement, StatementNode >( else_, astelse ); 190 191 return new ForStmt( astinit, astcond, astincr, aststmt.front(), astelse.front() ); 258 std::vector<ast::ptr<ast::Stmt>> astelse; // else clause, maybe empty 259 buildMoveList( else_, astelse ); 260 assert( astelse.size() <= 1 ); 261 262 return new ast::ForStmt( location, 263 std::move( astinit ), 264 astcond, 265 astincr, 266 aststmt.front(), 267 astelse.empty() ? nullptr : astelse.front().release() 268 ); 192 269 } // build_for 193 270 194 Statement * build_branch( BranchStmt::Type kind ) { 195 Statement * ret = new BranchStmt( "", kind ); 271 ast::Stmt * build_branch( const CodeLocation & location, ast::BranchStmt::Kind kind ) { 272 return new ast::BranchStmt( location, 273 kind, 274 ast::Label( location ) 275 ); 276 } // build_branch 277 278 ast::Stmt * build_branch( const CodeLocation & location, string * identifier, ast::BranchStmt::Kind kind ) { 279 ast::Stmt * ret = new ast::BranchStmt( location, 280 kind, 281 ast::Label( location, *identifier ) 282 ); 283 delete identifier; // allocated by lexer 196 284 return ret; 197 285 } // build_branch 198 286 199 Statement * build_branch( string * identifier, BranchStmt::Type kind ) { 200 Statement * ret = new BranchStmt( * identifier, kind ); 201 delete identifier; // allocated by lexer 202 return ret; 203 } // build_branch 204 205 Statement * build_computedgoto( ExpressionNode * ctl ) { 206 return new BranchStmt( maybeMoveBuild( ctl ), BranchStmt::Goto ); 287 ast::Stmt * build_computedgoto( ExpressionNode * ctl ) { 288 ast::Expr * expr = maybeMoveBuild( ctl ); 289 return new ast::BranchStmt( expr->location, expr ); 207 290 } // build_computedgoto 208 291 209 Statement * build_return(ExpressionNode * ctl ) {210 list< Expression *> exps;292 ast::Stmt * build_return( const CodeLocation & location, ExpressionNode * ctl ) { 293 std::vector<ast::ptr<ast::Expr>> exps; 211 294 buildMoveList( ctl, exps ); 212 return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr ); 295 return new ast::ReturnStmt( location, 296 exps.size() > 0 ? exps.back().release() : nullptr 297 ); 213 298 } // build_return 214 299 215 Statement * build_throw( ExpressionNode * ctl ) { 216 list< Expression * > exps; 300 static ast::Stmt * build_throw_stmt( 301 const CodeLocation & location, 302 ExpressionNode * ctl, 303 ast::ExceptionKind kind ) { 304 std::vector<ast::ptr<ast::Expr>> exps; 217 305 buildMoveList( ctl, exps ); 218 306 assertf( exps.size() < 2, "CFA internal error: leaking memory" ); 219 return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr ); 307 return new ast::ThrowStmt( location, 308 kind, 309 !exps.empty() ? exps.back().release() : nullptr, 310 (ast::Expr *)nullptr 311 ); 312 } 313 314 ast::Stmt * build_throw( const CodeLocation & loc, ExpressionNode * ctl ) { 315 return build_throw_stmt( loc, ctl, ast::Terminate ); 220 316 } // build_throw 221 317 222 Statement * build_resume( ExpressionNode * ctl ) { 223 list< Expression * > exps; 224 buildMoveList( ctl, exps ); 225 assertf( exps.size() < 2, "CFA internal error: leaking memory" ); 226 return new ThrowStmt( ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr ); 318 ast::Stmt * build_resume( const CodeLocation & loc, ExpressionNode * ctl ) { 319 return build_throw_stmt( loc, ctl, ast::Resume ); 227 320 } // build_resume 228 321 229 Statement * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {322 ast::Stmt * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) { 230 323 (void)ctl; 231 324 (void)target; … … 233 326 } // build_resume_at 234 327 235 Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) { 236 list< CatchStmt * > aststmt; 237 buildMoveList< CatchStmt, StatementNode >( catch_, aststmt ); 238 CompoundStmt * tryBlock = strict_dynamic_cast< CompoundStmt * >( maybeMoveBuild( try_ ) ); 239 FinallyStmt * finallyBlock = dynamic_cast< FinallyStmt * >( maybeMoveBuild( finally_ ) ); 240 return new TryStmt( tryBlock, aststmt, finallyBlock ); 328 ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) { 329 std::vector<ast::ptr<ast::CatchClause>> aststmt; 330 buildMoveClauseList( catch_, aststmt ); 331 ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) ); 332 ast::FinallyClause * finallyBlock = nullptr; 333 if ( finally_ ) { 334 finallyBlock = dynamic_cast<ast::FinallyClause *>( finally_->clause.release() ); 335 } 336 return new ast::TryStmt( location, 337 tryBlock, 338 std::move( aststmt ), 339 finallyBlock 340 ); 241 341 } // build_try 242 342 243 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {244 list< Statement *> aststmt;245 buildMoveList < Statement, StatementNode >( body, aststmt );343 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 ); 246 346 assert( aststmt.size() == 1 ); 247 return new CatchStmt( kind, maybeMoveBuild( decl ), maybeMoveBuild( cond ), aststmt.front() ); 347 return new ast::CatchClause( location, 348 kind, 349 maybeMoveBuild( decl ), 350 maybeMoveBuild( cond ), 351 aststmt.front().release() 352 ); 248 353 } // build_catch 249 354 250 Statement * build_finally(StatementNode * stmt ) {251 list< Statement *> aststmt;252 buildMoveList < Statement, StatementNode >( stmt, aststmt );355 ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) { 356 std::vector<ast::ptr<ast::Stmt>> aststmt; 357 buildMoveList( stmt, aststmt ); 253 358 assert( aststmt.size() == 1 ); 254 return new FinallyStmt( dynamic_cast< CompoundStmt * >( aststmt.front() ) ); 359 return new ast::FinallyClause( location, 360 aststmt.front().strict_as<ast::CompoundStmt>() 361 ); 255 362 } // build_finally 256 363 257 SuspendStmt * build_suspend( StatementNode * then, SuspendStmt::Type type ) { 258 auto node = new SuspendStmt(); 259 260 node->type = type; 261 262 list< Statement * > stmts; 263 buildMoveList< Statement, StatementNode >( then, stmts ); 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; 264 368 if(!stmts.empty()) { 265 369 assert( stmts.size() == 1 ); 266 node->then = dynamic_cast< CompoundStmt * >( stmts.front());370 then2 = stmts.front().strict_as<ast::CompoundStmt>(); 267 371 } 268 372 auto node = new ast::SuspendStmt( location, then2, ast::SuspendStmt::None ); 373 node->type = type; 269 374 return node; 270 375 } // build_suspend 271 376 272 WaitForStmt * build_waitfor( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) { 273 WaitForStmt::Target target; 274 target.function = maybeBuild( targetExpr ); 377 ast::WaitForStmt * build_waitfor( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) { 378 auto clause = new ast::WaitForClause( location ); 379 clause->target_func = maybeBuild( targetExpr ); 380 clause->stmt = maybeMoveBuild( stmt ); 381 clause->cond = notZeroExpr( maybeMoveBuild( when ) ); 275 382 276 383 ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() ); 277 384 targetExpr->set_next( nullptr ); 278 buildMoveList < Expression >( next, target.arguments );385 buildMoveList( next, clause->target_args ); 279 386 280 387 delete targetExpr; 281 388 282 existing->clauses.insert( existing->clauses.begin(), WaitForStmt::Clause{ 283 std::move( target ), 284 maybeMoveBuild( stmt ), 285 notZeroExpr( maybeMoveBuild( when ) ) 286 }); 389 existing->clauses.insert( existing->clauses.begin(), clause ); 287 390 288 391 return existing; 289 392 } // build_waitfor 290 393 291 WaitForStmt * build_waitfor_else( WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) { 292 existing->orelse.statement = maybeMoveBuild( stmt ); 293 existing->orelse.condition = notZeroExpr( maybeMoveBuild( when ) ); 294 394 ast::WaitForStmt * build_waitfor_else( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) { 395 existing->else_stmt = maybeMoveBuild( stmt ); 396 existing->else_cond = notZeroExpr( maybeMoveBuild( when ) ); 397 398 (void)location; 295 399 return existing; 296 400 } // build_waitfor_else 297 401 298 WaitForStmt * build_waitfor_timeout( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) { 299 existing->timeout.time = maybeMoveBuild( timeout ); 300 existing->timeout.statement = maybeMoveBuild( stmt ); 301 existing->timeout.condition = notZeroExpr( maybeMoveBuild( when ) ); 302 402 ast::WaitForStmt * build_waitfor_timeout( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) { 403 existing->timeout_time = maybeMoveBuild( timeout ); 404 existing->timeout_stmt = maybeMoveBuild( stmt ); 405 existing->timeout_cond = notZeroExpr( maybeMoveBuild( when ) ); 406 407 (void)location; 303 408 return existing; 304 409 } // build_waitfor_timeout 305 410 306 Statement * build_with(ExpressionNode * exprs, StatementNode * stmt ) {307 list< Expression *> e;411 ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) { 412 std::vector<ast::ptr<ast::Expr>> e; 308 413 buildMoveList( exprs, e ); 309 Statement * s = maybeMoveBuild( stmt );310 return new DeclStmt( new WithStmt( e, s ) );414 ast::Stmt * s = maybeMoveBuild( stmt ); 415 return new ast::DeclStmt( location, new ast::WithStmt( location, std::move( e ), s ) ); 311 416 } // build_with 312 417 313 Statement * build_compound(StatementNode * first ) {314 CompoundStmt * cs = new CompoundStmt();315 buildMoveList( first, cs-> get_kids());418 ast::Stmt * build_compound( const CodeLocation & location, StatementNode * first ) { 419 auto cs = new ast::CompoundStmt( location ); 420 buildMoveList( first, cs->kids ); 316 421 return cs; 317 422 } // build_compound … … 321 426 // statement and wrap it into a compound statement to insert additional code. Hence, all control structures have a 322 427 // conical form for code generation. 323 StatementNode * maybe_build_compound( StatementNode * first ) {428 StatementNode * maybe_build_compound( const CodeLocation & location, StatementNode * first ) { 324 429 // Optimization: if the control-structure statement is a compound statement, do not wrap it. 325 430 // e.g., if (...) {...} do not wrap the existing compound statement. 326 if ( ! dynamic_cast<CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr 327 CompoundStmt * cs = new CompoundStmt(); 328 buildMoveList( first, cs->get_kids() ); 329 return new StatementNode( cs ); 431 if ( !dynamic_cast<ast::CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr 432 return new StatementNode( build_compound( location, first ) ); 330 433 } // if 331 434 return first; … … 333 436 334 437 // Question 335 Statement * build_asm( bool voltile, Expression* instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {336 list< Expression *> out, in;337 list< ConstantExpr *> clob;438 ast::Stmt * build_asm( const CodeLocation & location, bool voltile, ast::Expr * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) { 439 std::vector<ast::ptr<ast::Expr>> out, in; 440 std::vector<ast::ptr<ast::ConstantExpr>> clob; 338 441 339 442 buildMoveList( output, out ); 340 443 buildMoveList( input, in ); 341 444 buildMoveList( clobber, clob ); 342 return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels ); 445 return new ast::AsmStmt( location, 446 voltile, 447 instruction, 448 std::move( out ), 449 std::move( in ), 450 std::move( clob ), 451 gotolabels ? gotolabels->labels : std::vector<ast::Label>() 452 ); 343 453 } // build_asm 344 454 345 Statement * build_directive( string * directive ) { 346 return new DirectiveStmt( *directive ); 455 ast::Stmt * build_directive( const CodeLocation & location, string * directive ) { 456 auto stmt = new ast::DirectiveStmt( location, *directive ); 457 delete directive; 458 return stmt; 347 459 } // build_directive 348 460 349 Statement * build_mutex(ExpressionNode * exprs, StatementNode * stmt ) {350 list< Expression *> expList;461 ast::Stmt * build_mutex( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) { 462 std::vector<ast::ptr<ast::Expr>> expList; 351 463 buildMoveList( exprs, expList ); 352 Statement * body = maybeMoveBuild( stmt );353 return new MutexStmt( body, expList);464 ast::Stmt * body = maybeMoveBuild( stmt ); 465 return new ast::MutexStmt( location, body, std::move( expList ) ); 354 466 } // build_mutex 355 467
Note: See TracChangeset
for help on using the changeset viewer.