- Timestamp:
- May 29, 2023, 11:44:29 AM (2 years ago)
- Branches:
- ADT
- Children:
- fa2c005
- Parents:
- 3a513d89 (diff), 2b78949 (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. - Location:
- src
- Files:
-
- 2 added
- 18 edited
-
AST/Convert.cpp (modified) (4 diffs)
-
AST/Fwd.hpp (modified) (1 diff)
-
AST/Node.cpp (modified) (1 diff)
-
AST/Pass.hpp (modified) (1 diff)
-
AST/Pass.impl.hpp (modified) (7 diffs)
-
AST/Pass.proto.hpp (modified) (6 diffs)
-
AST/Print.cpp (modified) (4 diffs)
-
AST/Stmt.hpp (modified) (3 diffs)
-
AST/Visitor.hpp (modified) (1 diff)
-
Common/CodeLocationTools.cpp (modified) (1 diff)
-
Concurrency/WaitforNew.cpp (modified) (2 diffs)
-
Concurrency/Waituntil.cpp (added)
-
Concurrency/Waituntil.hpp (added)
-
Concurrency/module.mk (modified) (1 diff)
-
Parser/StatementNode.cc (modified) (2 diffs)
-
Parser/StatementNode.h (modified) (1 diff)
-
Parser/lex.ll (modified) (2 diffs)
-
Parser/parser.yy (modified) (6 diffs)
-
ResolvExpr/Resolver.cc (modified) (3 diffs)
-
main.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r3a513d89 r044ae62 585 585 } 586 586 587 const ast::WhenClause * visit( const ast::WhenClause * node ) override final { 588 // There is no old-AST WhenClause, so this should never be called. 589 assert( !node ); 590 return nullptr; 591 } 592 587 593 const ast::Stmt * visit( const ast::WaitForStmt * node ) override final { 588 594 if ( inCache( node ) ) return nullptr; … … 591 597 for ( auto clause : node->clauses ) { 592 598 stmt->clauses.push_back({{ 593 get<Expression>().accept1( clause->target _func),599 get<Expression>().accept1( clause->target ), 594 600 get<Expression>().acceptL( clause->target_args ), 595 601 }, 596 602 get<Statement>().accept1( clause->stmt ), 597 get<Expression>().accept1( clause-> cond ),603 get<Expression>().accept1( clause->when_cond ), 598 604 }); 599 605 } … … 612 618 const ast::WaitForClause * visit( const ast::WaitForClause * node ) override final { 613 619 // There is no old-AST WaitForClause, so this should never be called. 620 assert( !node ); 621 return nullptr; 622 } 623 624 const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final { 625 // There is no old-AST WaitUntilStmt, so this should never be called. 614 626 assert( !node ); 615 627 return nullptr; … … 2199 2211 auto clause = new ast::WaitForClause( old->location ); 2200 2212 2201 clause->target _func= GET_ACCEPT_1(clauses[i].target.function, Expr);2213 clause->target = GET_ACCEPT_1(clauses[i].target.function, Expr); 2202 2214 clause->target_args = GET_ACCEPT_V(clauses[i].target.arguments, Expr); 2203 2215 clause->stmt = GET_ACCEPT_1(clauses[i].statement, Stmt); 2204 clause-> cond = GET_ACCEPT_1(clauses[i].condition, Expr);2216 clause->when_cond = GET_ACCEPT_1(clauses[i].condition, Expr); 2205 2217 2206 2218 stmt->clauses.push_back( clause ); -
src/AST/Fwd.hpp
r3a513d89 r044ae62 59 59 class FinallyClause; 60 60 class SuspendStmt; 61 class WhenClause; 61 62 class WaitForStmt; 62 63 class WaitForClause; 64 class WaitUntilStmt; 63 65 class WithStmt; 64 66 class DeclStmt; -
src/AST/Node.cpp
r3a513d89 r044ae62 176 176 template class ast::ptr_base< ast::FinallyClause, ast::Node::ref_type::weak >; 177 177 template class ast::ptr_base< ast::FinallyClause, ast::Node::ref_type::strong >; 178 template class ast::ptr_base< ast::WhenClause, ast::Node::ref_type::weak >; 179 template class ast::ptr_base< ast::WhenClause, ast::Node::ref_type::strong >; 178 180 template class ast::ptr_base< ast::WaitForStmt, ast::Node::ref_type::weak >; 179 181 template class ast::ptr_base< ast::WaitForStmt, ast::Node::ref_type::strong >; 180 182 template class ast::ptr_base< ast::WaitForClause, ast::Node::ref_type::weak >; 181 183 template class ast::ptr_base< ast::WaitForClause, ast::Node::ref_type::strong >; 184 template class ast::ptr_base< ast::WaitUntilStmt, ast::Node::ref_type::weak >; 185 template class ast::ptr_base< ast::WaitUntilStmt, ast::Node::ref_type::strong >; 182 186 template class ast::ptr_base< ast::WithStmt, ast::Node::ref_type::weak >; 183 187 template class ast::ptr_base< ast::WithStmt, ast::Node::ref_type::strong >; -
src/AST/Pass.hpp
r3a513d89 r044ae62 163 163 const ast::FinallyClause * visit( const ast::FinallyClause * ) override final; 164 164 const ast::Stmt * visit( const ast::SuspendStmt * ) override final; 165 const ast::WhenClause * visit( const ast::WhenClause * ) override final; 165 166 const ast::Stmt * visit( const ast::WaitForStmt * ) override final; 166 167 const ast::WaitForClause * visit( const ast::WaitForClause * ) override final; 168 const ast::Stmt * visit( const ast::WaitUntilStmt * ) override final; 167 169 const ast::Decl * visit( const ast::WithStmt * ) override final; 168 170 const ast::NullStmt * visit( const ast::NullStmt * ) override final; -
src/AST/Pass.impl.hpp
r3a513d89 r044ae62 22 22 #include "AST/TranslationUnit.hpp" 23 23 #include "AST/TypeSubstitution.hpp" 24 #include "Common/Iterate.hpp"25 24 26 25 #define VISIT_START( node ) \ … … 127 126 } 128 127 129 template< typename node_t >130 template< typename object_t, typename super_t, typename field_t >131 void __pass::result1< node_t >::apply( object_t * object, field_t super_t::* field ) {132 object->*field = value;133 }134 135 128 template< typename core_t > 136 129 template< typename node_t > … … 234 227 235 228 return {true, compound}; 236 }237 238 template< template <class...> class container_t >239 template< typename object_t, typename super_t, typename field_t >240 void __pass::resultNstmt<container_t>::apply(object_t * object, field_t super_t::* field) {241 auto & container = object->*field;242 __pedantic_pass_assert( container.size() <= values.size() );243 244 auto cit = enumerate(container).begin();245 246 container_t<ptr<Stmt>> nvals;247 for (delta & d : values) {248 if ( d.is_old ) {249 __pedantic_pass_assert( cit.idx <= d.old_idx );250 std::advance( cit, d.old_idx - cit.idx );251 nvals.push_back( std::move( (*cit).val) );252 } else {253 nvals.push_back( std::move(d.new_val) );254 }255 }256 257 container = std::move(nvals);258 }259 260 template< template <class...> class container_t >261 template< template <class...> class incontainer_t >262 void __pass::resultNstmt< container_t >::take_all( incontainer_t<ptr<Stmt>> * stmts ) {263 if (!stmts || stmts->empty()) return;264 265 std::transform(stmts->begin(), stmts->end(), std::back_inserter( values ),266 [](ast::ptr<ast::Stmt>& stmt) -> delta {267 return delta( stmt.release(), -1, false );268 });269 stmts->clear();270 differs = true;271 }272 273 template< template<class...> class container_t >274 template< template<class...> class incontainer_t >275 void __pass::resultNstmt< container_t >::take_all( incontainer_t<ptr<Decl>> * decls ) {276 if (!decls || decls->empty()) return;277 278 std::transform(decls->begin(), decls->end(), std::back_inserter( values ),279 [](ast::ptr<ast::Decl>& decl) -> delta {280 auto loc = decl->location;281 auto stmt = new DeclStmt( loc, decl.release() );282 return delta( stmt, -1, false );283 });284 decls->clear();285 differs = true;286 229 } 287 230 … … 353 296 354 297 return new_kids; 355 }356 357 template< template <class...> class container_t, typename node_t >358 template< typename object_t, typename super_t, typename field_t >359 void __pass::resultN<container_t, node_t>::apply(object_t * object, field_t super_t::* field) {360 auto & container = object->*field;361 __pedantic_pass_assert( container.size() == values.size() );362 363 for(size_t i = 0; i < container.size(); i++) {364 // Take all the elements that are different in 'values'365 // and swap them into 'container'366 if( values[i] != nullptr ) swap(container[i], values[i]);367 }368 369 // Now the original containers should still have the unchanged values370 // but also contain the new values371 298 } 372 299 … … 1097 1024 1098 1025 //-------------------------------------------------------------------------- 1026 // WhenClause 1027 template< typename core_t > 1028 const ast::WhenClause * ast::Pass< core_t >::visit( const ast::WhenClause * node ) { 1029 VISIT_START( node ); 1030 1031 if ( __visit_children() ) { 1032 maybe_accept( node, &WhenClause::target ); 1033 maybe_accept( node, &WhenClause::stmt ); 1034 maybe_accept( node, &WhenClause::when_cond ); 1035 } 1036 1037 VISIT_END( WhenClause, node ); 1038 } 1039 1040 //-------------------------------------------------------------------------- 1099 1041 // WaitForStmt 1100 1042 template< typename core_t > … … 1121 1063 1122 1064 if ( __visit_children() ) { 1123 maybe_accept( node, &WaitForClause::target _func);1065 maybe_accept( node, &WaitForClause::target ); 1124 1066 maybe_accept( node, &WaitForClause::target_args ); 1125 1067 maybe_accept( node, &WaitForClause::stmt ); 1126 maybe_accept( node, &WaitForClause:: cond );1068 maybe_accept( node, &WaitForClause::when_cond ); 1127 1069 } 1128 1070 1129 1071 VISIT_END( WaitForClause, node ); 1072 } 1073 1074 //-------------------------------------------------------------------------- 1075 // WaitUntilStmt 1076 template< typename core_t > 1077 const ast::Stmt * ast::Pass< core_t >::visit( const ast::WaitUntilStmt * node ) { 1078 VISIT_START( node ); 1079 1080 if ( __visit_children() ) { 1081 maybe_accept( node, &WaitUntilStmt::clauses ); 1082 maybe_accept( node, &WaitUntilStmt::timeout_time ); 1083 maybe_accept( node, &WaitUntilStmt::timeout_stmt ); 1084 maybe_accept( node, &WaitUntilStmt::timeout_cond ); 1085 maybe_accept( node, &WaitUntilStmt::else_stmt ); 1086 maybe_accept( node, &WaitUntilStmt::else_cond ); 1087 } 1088 1089 VISIT_END( Stmt, node ); 1130 1090 } 1131 1091 … … 2234 2194 } 2235 2195 2196 #undef __pedantic_pass_assertf 2197 #undef __pedantic_pass_assert 2236 2198 #undef VISIT_START 2237 2199 #undef VISIT_END -
src/AST/Pass.proto.hpp
r3a513d89 r044ae62 17 17 // IWYU pragma: private, include "Pass.hpp" 18 18 19 #include "Common/Iterate.hpp" 19 20 #include "Common/Stats/Heap.h" 20 21 namespace ast { … … 24 25 template<typename node_t> node_t * deepCopy( const node_t * ); 25 26 } 27 28 #ifdef PEDANTIC_PASS_ASSERT 29 #define __pedantic_pass_assert(...) assert (__VA_ARGS__) 30 #define __pedantic_pass_assertf(...) assertf(__VA_ARGS__) 31 #else 32 #define __pedantic_pass_assert(...) 33 #define __pedantic_pass_assertf(...) 34 #endif 26 35 27 36 namespace ast::__pass { … … 130 139 131 140 template< typename object_t, typename super_t, typename field_t > 132 void apply( object_t *, field_t super_t::* field ); 141 void apply( object_t * object, field_t super_t::* field ) { 142 object->*field = value; 143 } 133 144 }; 134 145 … … 150 161 151 162 template< typename object_t, typename super_t, typename field_t > 152 void apply( object_t *, field_t super_t::* field ); 163 void apply( object_t * object, field_t super_t::* field ) { 164 field_t & container = object->*field; 165 __pedantic_pass_assert( container.size() <= values.size() ); 166 167 auto cit = enumerate(container).begin(); 168 169 container_t<ptr<Stmt>> nvals; 170 for ( delta & d : values ) { 171 if ( d.is_old ) { 172 __pedantic_pass_assert( cit.idx <= d.old_idx ); 173 std::advance( cit, d.old_idx - cit.idx ); 174 nvals.push_back( std::move( (*cit).val ) ); 175 } else { 176 nvals.push_back( std::move( d.new_val ) ); 177 } 178 } 179 180 container = std::move(nvals); 181 } 153 182 154 183 template< template<class...> class incontainer_t > 155 void take_all( incontainer_t<ptr<Stmt>> * stmts ); 184 void take_all( incontainer_t<ptr<Stmt>> * stmts ) { 185 if ( !stmts || stmts->empty() ) return; 186 187 std::transform( stmts->begin(), stmts->end(), std::back_inserter( values ), 188 [](ast::ptr<ast::Stmt>& stmt) -> delta { 189 return delta( stmt.release(), -1, false ); 190 }); 191 stmts->clear(); 192 differs = true; 193 } 156 194 157 195 template< template<class...> class incontainer_t > 158 void take_all( incontainer_t<ptr<Decl>> * decls ); 196 void take_all( incontainer_t<ptr<Decl>> * decls ) { 197 if ( !decls || decls->empty() ) return; 198 199 std::transform( decls->begin(), decls->end(), std::back_inserter( values ), 200 [](ast::ptr<ast::Decl>& decl) -> delta { 201 ast::Decl const * d = decl.release(); 202 return delta( new DeclStmt( d->location, d ), -1, false ); 203 }); 204 decls->clear(); 205 differs = true; 206 } 159 207 }; 160 208 … … 166 214 167 215 template< typename object_t, typename super_t, typename field_t > 168 void apply( object_t *, field_t super_t::* field ); 216 void apply( object_t * object, field_t super_t::* field ) { 217 field_t & container = object->*field; 218 __pedantic_pass_assert( container.size() == values.size() ); 219 220 for ( size_t i = 0; i < container.size(); ++i ) { 221 // Take all the elements that are different in 'values' 222 // and swap them into 'container' 223 if ( values[i] != nullptr ) swap(container[i], values[i]); 224 } 225 // Now the original containers should still have the unchanged values 226 // but also contain the new values. 227 } 169 228 }; 170 229 … … 534 593 535 594 } // namespace ast::__pass 595 596 #undef __pedantic_pass_assertf 597 #undef __pedantic_pass_assert -
src/AST/Print.cpp
r3a513d89 r044ae62 208 208 } 209 209 210 void print( const ast::WaitStmt * node ) { 211 if ( node->timeout_time ) { 212 os << indent-1 << "timeout of:" << endl; 213 node->timeout_time->accept( *this ); 214 215 if ( node->timeout_stmt ) { 216 os << indent-1 << "... with statment:" << endl; 217 node->timeout_stmt->accept( *this ); 218 } 219 220 if ( node->timeout_cond ) { 221 os << indent-1 << "... with condition:" << endl; 222 node->timeout_cond->accept( *this ); 223 } 224 } 225 226 if ( node->else_stmt ) { 227 os << indent-1 << "else:" << endl; 228 node->else_stmt->accept( *this ); 229 230 if ( node->else_cond ) { 231 os << indent-1 << "... with condition:" << endl; 232 node->else_cond->accept( *this ); 233 } 234 } 235 } 236 210 237 void preprint( const ast::NamedTypeDecl * node ) { 211 238 if ( ! node->name.empty() ) { … … 761 788 } 762 789 790 virtual const ast::WhenClause * visit( const ast::WhenClause * node ) override final { 791 os << indent-1 << "target: "; 792 safe_print( node->target ); 793 794 if ( node->stmt ) { 795 os << indent-1 << "... with statment:" << endl; 796 node->stmt->accept( *this ); 797 } 798 799 if ( node->when_cond ) { 800 os << indent-1 << "... with when condition:" << endl; 801 node->when_cond->accept( *this ); 802 } 803 804 return node; 805 } 806 763 807 virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) override final { 764 808 os << "Waitfor Statement" << endl; … … 798 842 virtual const ast::WaitForClause * visit( const ast::WaitForClause * node ) override final { 799 843 os << indent-1 << "target function: "; 800 safe_print( node->target _func);844 safe_print( node->target ); 801 845 802 846 if ( !node->target_args.empty() ) { … … 812 856 } 813 857 814 if ( node-> cond ) {858 if ( node->when_cond ) { 815 859 os << indent-1 << "... with condition:" << endl; 816 node->cond->accept( *this ); 817 } 818 860 node->when_cond->accept( *this ); 861 } 862 863 return node; 864 } 865 866 virtual const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final { 867 os << "Waituntil Statement" << endl; 868 indent += 2; 869 for( const auto & clause : node->clauses ) { 870 clause->accept( *this ); 871 } 872 print(node); // calls print( const ast::WaitStmt * node ) 819 873 return node; 820 874 } -
src/AST/Stmt.hpp
r3a513d89 r044ae62 378 378 }; 379 379 380 // Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ...381 class WaitForStmt final : public Stmt { 382 public: 383 std::vector<ptr<WaitForClause>> clauses; 384 ptr<Expr> timeout_time;380 // Base class of WaitFor/WaitUntil statements 381 // form: KEYWORD(...) ... timeout(...) ... else ... 382 class WaitStmt : public Stmt { 383 public: 384 ptr<Expr> timeout_time; 385 385 ptr<Stmt> timeout_stmt; 386 386 ptr<Expr> timeout_cond; … … 388 388 ptr<Expr> else_cond; 389 389 390 WaitStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} ) 391 : Stmt(loc, std::move(labels)) {} 392 393 private: 394 WaitStmt * clone() const override = 0; 395 MUTATE_FRIEND 396 }; 397 398 // Base class for WaitFor/WaitUntil clauses 399 // form: when( when_cond ) KEYWORD( target ) stmt 400 class WhenClause : public StmtClause { 401 public: 402 ptr<Expr> target; 403 ptr<Stmt> stmt; 404 ptr<Expr> when_cond; 405 406 WhenClause( const CodeLocation & loc ) 407 : StmtClause( loc ) {} 408 409 const WhenClause * accept( Visitor & v ) const override { return v.visit( this ); } 410 private: 411 WhenClause * clone() const override { return new WhenClause{ *this }; } 412 MUTATE_FRIEND 413 }; 414 415 // Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ... 416 class WaitForStmt final : public WaitStmt { 417 public: 418 std::vector<ptr<WaitForClause>> clauses; 419 390 420 WaitForStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} ) 391 : Stmt(loc, std::move(labels)) {}421 : WaitStmt(loc, std::move(labels)) {} 392 422 393 423 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } … … 398 428 399 429 // Clause in a waitfor statement: waitfor (..., ...) ... 400 class WaitForClause final : public StmtClause { 401 public: 402 ptr<Expr> target_func; 430 class WaitForClause final : public WhenClause { 431 public: 403 432 std::vector<ptr<Expr>> target_args; 404 ptr<Stmt> stmt;405 ptr<Expr> cond;406 433 407 434 WaitForClause( const CodeLocation & loc ) 408 : StmtClause( loc ) {}435 : WhenClause( loc ) {} 409 436 410 437 const WaitForClause * accept( Visitor & v ) const override { return v.visit( this ); } 411 438 private: 412 439 WaitForClause * clone() const override { return new WaitForClause{ *this }; } 440 MUTATE_FRIEND 441 }; 442 443 // waituntil statement: when (...) waituntil (...) ... timeout(...) ... else ... 444 class WaitUntilStmt final : public WaitStmt { 445 public: 446 // Non-ast node used during compilation to store data needed to generate predicates 447 // and set initial status values for clauses 448 // Used to create a tree corresponding to the structure of the clauses in a WaitUntil 449 struct ClauseNode { 450 enum Op { AND, OR, LEFT_OR, LEAF, ELSE, TIMEOUT } op; // operation/type tag 451 // LEFT_OR used with TIMEOUT/ELSE to indicate that we ignore right hand side after parsing 452 453 ClauseNode * left; 454 ClauseNode * right; 455 WhenClause * leaf; // only set if this node is a leaf (points into vector of clauses) 456 457 bool ambiguousWhen; // used to paint nodes of predicate tree based on when() clauses 458 bool whenState; // used to track if when_cond is toggled on or off for generating init values 459 bool childOfAnd; // true on leaf nodes that are children of AND, false otherwise 460 461 ClauseNode( Op op, ClauseNode * left, ClauseNode * right ) 462 : op(op), left(left), right(right), leaf(nullptr), 463 ambiguousWhen(false), whenState(true), childOfAnd(false) {} 464 ClauseNode( Op op, WhenClause * leaf ) 465 : op(op), left(nullptr), right(nullptr), leaf(leaf), 466 ambiguousWhen(false), whenState(true), childOfAnd(false) {} 467 ClauseNode( WhenClause * leaf ) : ClauseNode(LEAF, leaf) {} 468 469 ~ClauseNode() { 470 if ( left ) delete left; 471 if ( right ) delete right; 472 } 473 }; 474 475 std::vector<ptr<WhenClause>> clauses; 476 ClauseNode * predicateTree; 477 478 WaitUntilStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} ) 479 : WaitStmt(loc, std::move(labels)) {} 480 481 ~WaitUntilStmt() { delete predicateTree; } 482 483 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 484 private: 485 WaitUntilStmt * clone() const override { return new WaitUntilStmt{ *this }; } 413 486 MUTATE_FRIEND 414 487 }; -
src/AST/Visitor.hpp
r3a513d89 r044ae62 51 51 virtual const ast::FinallyClause * visit( const ast::FinallyClause * ) = 0; 52 52 virtual const ast::Stmt * visit( const ast::SuspendStmt * ) = 0; 53 virtual const ast::WhenClause * visit( const ast::WhenClause * ) = 0; 53 54 virtual const ast::Stmt * visit( const ast::WaitForStmt * ) = 0; 54 55 virtual const ast::WaitForClause * visit( const ast::WaitForClause * ) = 0; 56 virtual const ast::Stmt * visit( const ast::WaitUntilStmt * ) = 0; 55 57 virtual const ast::Decl * visit( const ast::WithStmt * ) = 0; 56 58 virtual const ast::NullStmt * visit( const ast::NullStmt * ) = 0; -
src/Common/CodeLocationTools.cpp
r3a513d89 r044ae62 129 129 macro(FinallyClause, FinallyClause) \ 130 130 macro(SuspendStmt, Stmt) \ 131 macro(WhenClause, WhenClause) \ 131 132 macro(WaitForStmt, Stmt) \ 132 133 macro(WaitForClause, WaitForClause) \ 134 macro(WaitUntilStmt, Stmt) \ 133 135 macro(WithStmt, Decl) \ 134 136 macro(NullStmt, NullStmt) \ -
src/Concurrency/WaitforNew.cpp
r3a513d89 r044ae62 305 305 306 306 const ast::VariableExpr * variableExpr = 307 clause->target _func.as<ast::VariableExpr>();307 clause->target.as<ast::VariableExpr>(); 308 308 ast::Expr * castExpr = new ast::CastExpr( 309 309 location, 310 310 new ast::CastExpr( 311 311 location, 312 clause->target _func,312 clause->target, 313 313 ast::deepCopy( variableExpr->result.get() ), 314 314 ast::GeneratedCast ), … … 325 325 326 326 ResolveContext context{ symtab, transUnit().global }; 327 out->push_back( maybeCond( location, clause-> cond.get(), {327 out->push_back( maybeCond( location, clause->when_cond.get(), { 328 328 makeAccStmt( location, acceptables, index, "is_dtor", 329 detectIsDtor( location, clause->target _func), context ),329 detectIsDtor( location, clause->target ), context ), 330 330 makeAccStmt( location, acceptables, index, "func", 331 331 funcExpr, context ), -
src/Concurrency/module.mk
r3a513d89 r044ae62 23 23 Concurrency/WaitforNew.cpp \ 24 24 Concurrency/Waitfor.cc \ 25 Concurrency/Waitfor.h 25 Concurrency/Waitfor.h \ 26 Concurrency/Waituntil.cpp \ 27 Concurrency/Waituntil.hpp -
src/Parser/StatementNode.cc
r3a513d89 r044ae62 328 328 ast::WaitForStmt * build_waitfor( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) { 329 329 auto clause = new ast::WaitForClause( location ); 330 clause->target _func= maybeBuild( targetExpr );330 clause->target = maybeBuild( targetExpr ); 331 331 clause->stmt = maybeMoveBuild( stmt ); 332 clause-> cond = notZeroExpr( maybeMoveBuild( when ) );332 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 333 333 334 334 ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() ); … … 359 359 return existing; 360 360 } // build_waitfor_timeout 361 362 ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) { 363 ast::WhenClause * clause = new ast::WhenClause( loc ); 364 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 365 clause->stmt = maybeMoveBuild( stmt ); 366 clause->target = maybeMoveBuild( targetExpr ); 367 return new ast::WaitUntilStmt::ClauseNode( clause ); 368 } 369 ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation & loc, ExpressionNode * when, StatementNode * stmt ) { 370 ast::WhenClause * clause = new ast::WhenClause( loc ); 371 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 372 clause->stmt = maybeMoveBuild( stmt ); 373 return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::ELSE, clause ); 374 } 375 ast::WaitUntilStmt::ClauseNode * build_waituntil_timeout( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) { 376 ast::WhenClause * clause = new ast::WhenClause( loc ); 377 clause->when_cond = notZeroExpr( maybeMoveBuild( when ) ); 378 clause->stmt = maybeMoveBuild( stmt ); 379 clause->target = maybeMoveBuild( timeout ); 380 return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::TIMEOUT, clause ); 381 } 382 383 ast::WaitUntilStmt * build_waituntil_stmt( const CodeLocation & loc, ast::WaitUntilStmt::ClauseNode * root ) { 384 ast::WaitUntilStmt * retStmt = new ast::WaitUntilStmt( loc ); 385 retStmt->predicateTree = root; 386 387 // iterative tree traversal 388 std::vector<ast::WaitUntilStmt::ClauseNode *> nodeStack; // stack needed for iterative traversal 389 ast::WaitUntilStmt::ClauseNode * currNode = nullptr; 390 ast::WaitUntilStmt::ClauseNode * lastInternalNode = nullptr; 391 ast::WaitUntilStmt::ClauseNode * cleanup = nullptr; // used to cleanup removed else/timeout 392 nodeStack.push_back(root); 393 394 do { 395 currNode = nodeStack.back(); 396 nodeStack.pop_back(); // remove node since it will be processed 397 398 switch (currNode->op) { 399 case ast::WaitUntilStmt::ClauseNode::LEAF: 400 retStmt->clauses.push_back(currNode->leaf); 401 break; 402 case ast::WaitUntilStmt::ClauseNode::ELSE: 403 retStmt->else_stmt = currNode->leaf->stmt 404 ? ast::deepCopy( currNode->leaf->stmt ) 405 : nullptr; 406 407 retStmt->else_cond = currNode->leaf->when_cond 408 ? ast::deepCopy( currNode->leaf->when_cond ) 409 : nullptr; 410 411 delete currNode->leaf; 412 break; 413 case ast::WaitUntilStmt::ClauseNode::TIMEOUT: 414 retStmt->timeout_time = currNode->leaf->target 415 ? ast::deepCopy( currNode->leaf->target ) 416 : nullptr; 417 retStmt->timeout_stmt = currNode->leaf->stmt 418 ? ast::deepCopy( currNode->leaf->stmt ) 419 : nullptr; 420 retStmt->timeout_cond = currNode->leaf->when_cond 421 ? ast::deepCopy( currNode->leaf->when_cond ) 422 : nullptr; 423 424 delete currNode->leaf; 425 break; 426 default: 427 nodeStack.push_back( currNode->right ); // process right after left 428 nodeStack.push_back( currNode->left ); 429 430 // Cut else/timeout out of the tree 431 if ( currNode->op == ast::WaitUntilStmt::ClauseNode::LEFT_OR ) { 432 if ( lastInternalNode ) 433 lastInternalNode->right = currNode->left; 434 else // if not set then root is LEFT_OR 435 retStmt->predicateTree = currNode->left; 436 437 currNode->left = nullptr; 438 cleanup = currNode; 439 } 440 441 lastInternalNode = currNode; 442 break; 443 } 444 } while ( !nodeStack.empty() ); 445 446 if ( cleanup ) delete cleanup; 447 448 return retStmt; 449 } 361 450 362 451 ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) { -
src/Parser/StatementNode.h
r3a513d89 r044ae62 100 100 ast::WaitForStmt * build_waitfor_else( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ); 101 101 ast::WaitForStmt * build_waitfor_timeout( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ); 102 ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation &, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ); 103 ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation &, ExpressionNode * when, StatementNode * stmt ); 104 ast::WaitUntilStmt::ClauseNode * build_waituntil_timeout( const CodeLocation &, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ); 105 ast::WaitUntilStmt * build_waituntil_stmt( const CodeLocation &, ast::WaitUntilStmt::ClauseNode * root ); 102 106 ast::Stmt * build_with( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt ); 103 107 ast::Stmt * build_mutex( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt ); -
src/Parser/lex.ll
r3a513d89 r044ae62 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Sat Mar 25 08:09:03202313 * Update Count : 76 812 * Last Modified On : Tue May 2 08:45:21 2023 13 * Update Count : 769 14 14 */ 15 15 … … 258 258 enable { KEYWORD_RETURN(ENABLE); } // CFA 259 259 enum { KEYWORD_RETURN(ENUM); } 260 exception { KEYWORD_RETURN(EXCEPTION); } // CFA 260 261 __extension__ { KEYWORD_RETURN(EXTENSION); } // GCC 261 exception { KEYWORD_RETURN(EXCEPTION); } // CFA262 262 extern { KEYWORD_RETURN(EXTERN); } 263 263 fallthrough { KEYWORD_RETURN(FALLTHROUGH); } // CFA -
src/Parser/parser.yy
r3a513d89 r044ae62 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 // Last Modified By : Andrew Beach12 // Last Modified On : Tue Apr 4 14:02:00202313 // Update Count : 63 2911 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Apr 26 16:45:37 2023 13 // Update Count : 6330 14 14 // 15 15 … … 307 307 ClauseNode * clause; 308 308 ast::WaitForStmt * wfs; 309 ast::WaitUntilStmt::ClauseNode * wucn; 309 310 CondCtl * ifctl; 310 311 ForCtrl * forctl; … … 427 428 %type<expr> when_clause when_clause_opt waitfor waituntil timeout 428 429 %type<stmt> waitfor_statement waituntil_statement 429 %type<wfs> wor_waitfor_clause waituntil_clause wand_waituntil_clause wor_waituntil_clause 430 %type<wfs> wor_waitfor_clause 431 %type<wucn> waituntil_clause wand_waituntil_clause wor_waituntil_clause 430 432 431 433 // declarations … … 1682 1684 1683 1685 waituntil: 1684 WAITUNTIL '(' c ast_expression ')'1686 WAITUNTIL '(' comma_expression ')' 1685 1687 { $$ = $3; } 1686 1688 ; … … 1688 1690 waituntil_clause: 1689 1691 when_clause_opt waituntil statement 1690 { printf( "waituntil_clause 1\n" ); $$ = nullptr; }1692 { $$ = build_waituntil_clause( yylloc, $1, $2, maybe_build_compound( yylloc, $3 ) ); } 1691 1693 | '(' wor_waituntil_clause ')' 1692 { printf( "waituntil_clause 2\n" ); $$ = nullptr; }1694 { $$ = $2; } 1693 1695 ; 1694 1696 1695 1697 wand_waituntil_clause: 1696 1698 waituntil_clause %prec THEN 1697 { printf( "wand_waituntil_clause 1\n" ); $$ = nullptr; }1699 { $$ = $1; } 1698 1700 | waituntil_clause wand wand_waituntil_clause 1699 { printf( "wand_waituntil_clause 2\n" ); $$ = nullptr; }1701 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::AND, $1, $3 ); } 1700 1702 ; 1701 1703 1702 1704 wor_waituntil_clause: 1703 1705 wand_waituntil_clause 1704 { printf( "wor_waituntil_clause 1\n" ); $$ = nullptr; }1706 { $$ = $1; } 1705 1707 | wor_waituntil_clause wor wand_waituntil_clause 1706 { printf( "wor_waituntil_clause 2\n" ); $$ = nullptr; }1708 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, $1, $3 ); } 1707 1709 | wor_waituntil_clause wor when_clause_opt ELSE statement 1708 { printf( "wor_waituntil_clause 3\n" ); $$ = nullptr; }1710 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_else( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); } 1709 1711 | wor_waituntil_clause wor when_clause_opt timeout statement %prec THEN 1710 { printf( "wor_waituntil_clause 4\n" ); $$ = nullptr; }1712 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ) ); } 1711 1713 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1712 1714 | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error 1713 1715 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1714 1716 | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement 1715 { printf( "wor_waituntil_clause 6\n" ); $$ = nullptr; } 1717 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, 1718 new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, 1719 build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ), 1720 build_waituntil_else( yylloc, $7, maybe_build_compound( yylloc, $9 ) ) ) ); } 1716 1721 ; 1717 1722 … … 1719 1724 wor_waituntil_clause %prec THEN 1720 1725 // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement. 1721 { $$ = new StatementNode( build_compound( yylloc, nullptr ) ); } 1726 { 1727 $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) ); 1728 // $$ = new StatementNode( build_compound( yylloc, nullptr ) ); 1729 } 1722 1730 ; 1723 1731 -
src/ResolvExpr/Resolver.cc
r3a513d89 r044ae62 1730 1730 1731 1731 // Find all candidates for a function in canonical form 1732 funcFinder.find( clause.target _func, ResolvMode::withAdjustment() );1732 funcFinder.find( clause.target, ResolvMode::withAdjustment() ); 1733 1733 1734 1734 if ( funcFinder.candidates.empty() ) { 1735 1735 stringstream ss; 1736 1736 ss << "Use of undeclared indentifier '"; 1737 ss << clause.target _func.strict_as< ast::NameExpr >()->name;1737 ss << clause.target.strict_as< ast::NameExpr >()->name; 1738 1738 ss << "' in call to waitfor"; 1739 1739 SemanticError( stmt->location, ss.str() ); … … 1922 1922 auto clause2 = new ast::WaitForClause( clause.location ); 1923 1923 1924 clause2->target _func= funcCandidates.front()->expr;1924 clause2->target = funcCandidates.front()->expr; 1925 1925 1926 1926 clause2->target_args.reserve( clause.target_args.size() ); … … 1945 1945 1946 1946 // Resolve the conditions as if it were an IfStmt, statements normally 1947 clause2-> cond = findSingleExpression( clause.cond, context );1947 clause2->when_cond = findSingleExpression( clause.when_cond, context ); 1948 1948 clause2->stmt = clause.stmt->accept( *visitor ); 1949 1949 -
src/main.cc
r3a513d89 r044ae62 48 48 #include "Concurrency/Keywords.h" // for implementMutex, implement... 49 49 #include "Concurrency/Waitfor.h" // for generateWaitfor 50 #include "Concurrency/Waituntil.hpp" // for generateWaitUntil 50 51 #include "ControlStruct/ExceptDecl.h" // for translateExcept 51 52 #include "ControlStruct/ExceptTranslate.h" // for translateThrows, translat... … … 340 341 PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords, transUnit ); 341 342 PASS( "Forall Pointer Decay", Validate::decayForallPointers, transUnit ); 343 PASS( "Implement Waituntil", Concurrency::generateWaitUntil, transUnit ); 342 344 PASS( "Hoist Control Declarations", ControlStruct::hoistControlDecls, transUnit ); 343 345
Note:
See TracChangeset
for help on using the changeset viewer.