- Timestamp:
- Mar 9, 2020, 11:09:52 AM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 6565321
- Parents:
- 87f572e (diff), e6cfa8ff (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:
-
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r87f572e r5b544a6 493 493 } 494 494 495 const ast::Stmt * visit(const ast::SuspendStmt * node ) override final { 496 if ( inCache( node ) ) return nullptr; 497 auto stmt = new SuspendStmt(); 498 stmt->then = get<CompoundStmt>().accept1( node->then ); 499 switch(node->type) { 500 case ast::SuspendStmt::None : stmt->type = SuspendStmt::None ; break; 501 case ast::SuspendStmt::Coroutine: stmt->type = SuspendStmt::Coroutine; break; 502 case ast::SuspendStmt::Generator: stmt->type = SuspendStmt::Generator; break; 503 } 504 return stmtPostamble( stmt, node ); 505 } 506 495 507 const ast::Stmt * visit( const ast::WaitForStmt * node ) override final { 496 508 if ( inCache( node ) ) return nullptr; … … 1859 1871 } 1860 1872 1873 virtual void visit( const SuspendStmt * old ) override final { 1874 if ( inCache( old ) ) return; 1875 ast::SuspendStmt::Type type; 1876 switch (old->type) { 1877 case SuspendStmt::Coroutine: type = ast::SuspendStmt::Coroutine; break; 1878 case SuspendStmt::Generator: type = ast::SuspendStmt::Generator; break; 1879 case SuspendStmt::None : type = ast::SuspendStmt::None ; break; 1880 default: abort(); 1881 } 1882 this->node = new ast::SuspendStmt( 1883 old->location, 1884 GET_ACCEPT_1(then , CompoundStmt), 1885 type, 1886 GET_LABELS_V(old->labels) 1887 ); 1888 cache.emplace( old, this->node ); 1889 } 1890 1861 1891 virtual void visit( const WaitForStmt * old ) override final { 1862 1892 if ( inCache( old ) ) return; -
src/AST/Decl.hpp
r87f572e r5b544a6 259 259 260 260 bool is_coroutine() { return kind == Coroutine; } 261 bool is_monitor() { return kind == Monitor; } 262 bool is_thread() { return kind == Thread; } 261 bool is_generator() { return kind == Generator; } 262 bool is_monitor () { return kind == Monitor ; } 263 bool is_thread () { return kind == Thread ; } 263 264 264 265 const Decl * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Fwd.hpp
r87f572e r5b544a6 53 53 class CatchStmt; 54 54 class FinallyStmt; 55 class SuspendStmt; 55 56 class WaitForStmt; 56 57 class WithStmt; -
src/AST/Pass.hpp
r87f572e r5b544a6 111 111 const ast::Stmt * visit( const ast::CatchStmt * ) override final; 112 112 const ast::Stmt * visit( const ast::FinallyStmt * ) override final; 113 const ast::Stmt * visit( const ast::SuspendStmt * ) override final; 113 114 const ast::Stmt * visit( const ast::WaitForStmt * ) override final; 114 115 const ast::Decl * visit( const ast::WithStmt * ) override final; -
src/AST/Pass.impl.hpp
r87f572e r5b544a6 823 823 824 824 //-------------------------------------------------------------------------- 825 // FinallyStmt 826 template< typename pass_t > 827 const ast::Stmt * ast::Pass< pass_t >::visit( const ast::SuspendStmt * node ) { 828 VISIT_START( node ); 829 830 VISIT( 831 maybe_accept( node, &SuspendStmt::then ); 832 ) 833 834 VISIT_END( Stmt, node ); 835 } 836 837 //-------------------------------------------------------------------------- 825 838 // WaitForStmt 826 839 template< typename pass_t > -
src/AST/Print.cpp
r87f572e r5b544a6 674 674 safe_print( node->body ); 675 675 --indent; 676 677 return node; 678 } 679 680 virtual const ast::Stmt * visit( const ast::SuspendStmt * node ) override final { 681 os << "Suspend Statement"; 682 switch (node->type) { 683 case ast::SuspendStmt::None : os << " with implicit target"; break; 684 case ast::SuspendStmt::Generator: os << " for generator"; break; 685 case ast::SuspendStmt::Coroutine: os << " for coroutine"; break; 686 } 687 os << endl; 688 689 ++indent; 690 if(node->then) { 691 os << indent << " with post statement :" << endl; 692 safe_print( node->then ); 693 } 694 ++indent; 676 695 677 696 return node; -
src/AST/Stmt.hpp
r87f572e r5b544a6 342 342 }; 343 343 344 /// Suspend statement 345 class SuspendStmt final : public Stmt { 346 public: 347 ptr<CompoundStmt> then; 348 enum Type { None, Coroutine, Generator } type = None; 349 350 SuspendStmt( const CodeLocation & loc, const CompoundStmt * then, Type type, std::vector<Label> && labels = {} ) 351 : Stmt(loc, std::move(labels)), then(then), type(type) {} 352 353 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 354 private: 355 SuspendStmt * clone() const override { return new SuspendStmt{ *this }; } 356 MUTATE_FRIEND 357 }; 358 344 359 /// Wait for concurrency statement `when (...) waitfor (... , ...) ... timeout(...) ... else ...` 345 360 class WaitForStmt final : public Stmt { -
src/AST/Visitor.hpp
r87f572e r5b544a6 47 47 virtual const ast::Stmt * visit( const ast::CatchStmt * ) = 0; 48 48 virtual const ast::Stmt * visit( const ast::FinallyStmt * ) = 0; 49 virtual const ast::Stmt * visit( const ast::SuspendStmt * ) = 0; 49 50 virtual const ast::Stmt * visit( const ast::WaitForStmt * ) = 0; 50 51 virtual const ast::Decl * visit( const ast::WithStmt * ) = 0; -
src/Common/PassVisitor.h
r87f572e r5b544a6 110 110 virtual void visit( FinallyStmt * finallyStmt ) override final; 111 111 virtual void visit( const FinallyStmt * finallyStmt ) override final; 112 virtual void visit( SuspendStmt * suspendStmt ) override final; 113 virtual void visit( const SuspendStmt * suspendStmt ) override final; 112 114 virtual void visit( WaitForStmt * waitforStmt ) override final; 113 115 virtual void visit( const WaitForStmt * waitforStmt ) override final; … … 276 278 virtual Statement * mutate( CatchStmt * catchStmt ) override final; 277 279 virtual Statement * mutate( FinallyStmt * finallyStmt ) override final; 280 virtual Statement * mutate( SuspendStmt * suspendStmt ) override final; 278 281 virtual Statement * mutate( WaitForStmt * waitforStmt ) override final; 279 282 virtual Declaration * mutate( WithStmt * withStmt ) override final; -
src/Common/PassVisitor.impl.h
r87f572e r5b544a6 1522 1522 1523 1523 //-------------------------------------------------------------------------- 1524 // SuspendStmt 1525 template< typename pass_type > 1526 void PassVisitor< pass_type >::visit( SuspendStmt * node ) { 1527 VISIT_START( node ); 1528 1529 maybeAccept_impl( node->then , *this ); 1530 1531 VISIT_END( node ); 1532 } 1533 1534 template< typename pass_type > 1535 void PassVisitor< pass_type >::visit( const SuspendStmt * node ) { 1536 VISIT_START( node ); 1537 1538 maybeAccept_impl( node->then , *this ); 1539 1540 VISIT_END( node ); 1541 } 1542 1543 template< typename pass_type > 1544 Statement * PassVisitor< pass_type >::mutate( SuspendStmt * node ) { 1545 MUTATE_START( node ); 1546 1547 maybeMutate_impl( node->then , *this ); 1548 1549 MUTATE_END( Statement, node ); 1550 } 1551 1552 //-------------------------------------------------------------------------- 1524 1553 // WaitForStmt 1525 1554 template< typename pass_type > -
src/Concurrency/Keywords.cc
r87f572e r5b544a6 16 16 #include "Concurrency/Keywords.h" 17 17 18 #include <cassert> // for assert 19 #include <string> // for string, operator== 20 21 #include "Common/PassVisitor.h" // for PassVisitor 22 #include "Common/SemanticError.h" // for SemanticError 23 #include "Common/utility.h" // for deleteAll, map_range 24 #include "CodeGen/OperatorTable.h" // for isConstructor 25 #include "InitTweak/InitTweak.h" // for getPointerBase 26 #include "SynTree/LinkageSpec.h" // for Cforall 27 #include "SynTree/Constant.h" // for Constant 28 #include "SynTree/Declaration.h" // for StructDecl, FunctionDecl, ObjectDecl 29 #include "SynTree/Expression.h" // for VariableExpr, ConstantExpr, Untype... 30 #include "SynTree/Initializer.h" // for SingleInit, ListInit, Initializer ... 31 #include "SynTree/Label.h" // for Label 32 #include "SynTree/Statement.h" // for CompoundStmt, DeclStmt, ExprStmt 33 #include "SynTree/Type.h" // for StructInstType, Type, PointerType 34 #include "SynTree/Visitor.h" // for Visitor, acceptAll 18 #include <cassert> // for assert 19 #include <string> // for string, operator== 20 21 #include "Common/PassVisitor.h" // for PassVisitor 22 #include "Common/SemanticError.h" // for SemanticError 23 #include "Common/utility.h" // for deleteAll, map_range 24 #include "CodeGen/OperatorTable.h" // for isConstructor 25 #include "ControlStruct/LabelGenerator.h" // for LebelGenerator 26 #include "InitTweak/InitTweak.h" // for getPointerBase 27 #include "SynTree/LinkageSpec.h" // for Cforall 28 #include "SynTree/Constant.h" // for Constant 29 #include "SynTree/Declaration.h" // for StructDecl, FunctionDecl, ObjectDecl 30 #include "SynTree/Expression.h" // for VariableExpr, ConstantExpr, Untype... 31 #include "SynTree/Initializer.h" // for SingleInit, ListInit, Initializer ... 32 #include "SynTree/Label.h" // for Label 33 #include "SynTree/Statement.h" // for CompoundStmt, DeclStmt, ExprStmt 34 #include "SynTree/Type.h" // for StructInstType, Type, PointerType 35 #include "SynTree/Visitor.h" // for Visitor, acceptAll 35 36 36 37 class Attribute; … … 147 148 }; 148 149 150 151 149 152 //----------------------------------------------------------------------------- 150 153 //Handles monitor type declarations : … … 180 183 181 184 //----------------------------------------------------------------------------- 185 //Handles generator type declarations : 186 // generator MyGenerator { struct MyGenerator { 187 // int data; int data; 188 // a_struct_t more_data; a_struct_t more_data; 189 // => int __gen_next; 190 // }; }; 191 // 192 class GeneratorKeyword final : public ConcurrentSueKeyword { 193 public: 194 195 GeneratorKeyword() : ConcurrentSueKeyword( 196 "$generator", 197 "__generator_state", 198 "get_generator", 199 "Unable to find builtin type $generator\n", 200 true, 201 AggregateDecl::Generator 202 ) 203 {} 204 205 virtual ~GeneratorKeyword() {} 206 207 virtual bool is_target( StructDecl * decl ) override final { return decl->is_generator(); } 208 209 static void implement( std::list< Declaration * > & translationUnit ) { 210 PassVisitor< GeneratorKeyword > impl; 211 mutateAll( translationUnit, impl ); 212 } 213 }; 214 215 216 //----------------------------------------------------------------------------- 217 class SuspendKeyword final : public WithStmtsToAdd, public WithGuards { 218 public: 219 SuspendKeyword() = default; 220 virtual ~SuspendKeyword() = default; 221 222 void premutate( FunctionDecl * ); 223 DeclarationWithType * postmutate( FunctionDecl * ); 224 225 Statement * postmutate( SuspendStmt * ); 226 227 static void implement( std::list< Declaration * > & translationUnit ) { 228 PassVisitor< SuspendKeyword > impl; 229 mutateAll( translationUnit, impl ); 230 } 231 232 private: 233 DeclarationWithType * is_main( FunctionDecl * ); 234 bool is_real_suspend( FunctionDecl * ); 235 236 Statement * make_generator_suspend( SuspendStmt * ); 237 Statement * make_coroutine_suspend( SuspendStmt * ); 238 239 struct LabelPair { 240 Label obj; 241 int idx; 242 }; 243 244 LabelPair make_label() { 245 labels.push_back( gen.newLabel("generator") ); 246 return { labels.back(), int(labels.size()) }; 247 } 248 249 DeclarationWithType * in_generator = nullptr; 250 FunctionDecl * decl_suspend = nullptr; 251 std::vector<Label> labels; 252 ControlStruct::LabelGenerator & gen = *ControlStruct::LabelGenerator::getGenerator(); 253 }; 254 255 //----------------------------------------------------------------------------- 182 256 //Handles mutex routines definitions : 183 257 // void foo( A * mutex a, B * mutex b, int i ) { void foo( A * a, B * b, int i ) { … … 251 325 CoroutineKeyword ::implement( translationUnit ); 252 326 MonitorKeyword ::implement( translationUnit ); 327 GeneratorKeyword ::implement( translationUnit ); 328 SuspendKeyword ::implement( translationUnit ); 253 329 } 254 330 … … 446 522 447 523 declsToAddAfter.push_back( get_decl ); 448 449 // get_decl->fixUniqueId(); 450 } 524 } 525 526 //============================================================================================= 527 // Suspend keyword implementation 528 //============================================================================================= 529 DeclarationWithType * SuspendKeyword::is_main( FunctionDecl * func) { 530 if(func->name != "main") return nullptr; 531 if(func->type->parameters.size() != 1) return nullptr; 532 533 auto param = func->type->parameters.front(); 534 535 auto type = dynamic_cast<ReferenceType * >(param->get_type()); 536 if(!type) return nullptr; 537 538 auto obj = dynamic_cast<StructInstType *>(type->base); 539 if(!obj) return nullptr; 540 541 if(!obj->baseStruct->is_generator()) return nullptr; 542 543 return param; 544 } 545 546 bool SuspendKeyword::is_real_suspend( FunctionDecl * func ) { 547 if(isMangled(func->linkage)) return false; // the real suspend isn't mangled 548 if(func->name != "__cfactx_suspend") return false; // the real suspend has a specific name 549 if(func->type->parameters.size() != 0) return false; // Too many parameters 550 if(func->type->returnVals.size() != 0) return false; // Too many return values 551 552 return true; 553 } 554 555 void SuspendKeyword::premutate( FunctionDecl * func ) { 556 GuardValue(in_generator); 557 in_generator = nullptr; 558 559 // Is this the real suspend? 560 if(is_real_suspend(func)) { 561 decl_suspend = decl_suspend ? decl_suspend : func; 562 return; 563 } 564 565 // Is this the main of a generator? 566 auto param = is_main( func ); 567 if(!param) return; 568 569 if(func->type->returnVals.size() != 0) SemanticError(func->location, "Generator main must return void"); 570 571 in_generator = param; 572 GuardValue(labels); 573 labels.clear(); 574 } 575 576 DeclarationWithType * SuspendKeyword::postmutate( FunctionDecl * func ) { 577 if( !func->statements ) return func; // Not the actual definition, don't do anything 578 if( !in_generator ) return func; // Not in a generator, don't do anything 579 if( labels.empty() ) return func; // Generator has no states, nothing to do, could throw a warning 580 581 // This is a generator main, we need to add the following code to the top 582 // static void * __generator_labels[] = {&&s0, &&s1, ...}; 583 // goto * __generator_labels[gen.__generator_state]; 584 const auto & loc = func->location; 585 586 const auto first_label = gen.newLabel("generator"); 587 588 // for each label add to declaration 589 std::list<Initializer*> inits = { new SingleInit( new LabelAddressExpr( first_label ) ) }; 590 for(const auto & label : labels) { 591 inits.push_back( 592 new SingleInit( 593 new LabelAddressExpr( label ) 594 ) 595 ); 596 } 597 auto init = new ListInit(std::move(inits), noDesignators, true); 598 labels.clear(); 599 600 // create decl 601 auto decl = new ObjectDecl( 602 "__generator_labels", 603 Type::StorageClasses( Type::Static ), 604 LinkageSpec::AutoGen, 605 nullptr, 606 new ArrayType( 607 Type::Qualifiers(), 608 new PointerType( 609 Type::Qualifiers(), 610 new VoidType( Type::Qualifiers() ) 611 ), 612 nullptr, 613 false, false 614 ), 615 init 616 ); 617 618 // create the goto 619 assert(in_generator); 620 621 auto go_decl = new ObjectDecl( 622 "__generator_label", 623 noStorageClasses, 624 LinkageSpec::AutoGen, 625 nullptr, 626 new PointerType( 627 Type::Qualifiers(), 628 new VoidType( Type::Qualifiers() ) 629 ), 630 new SingleInit( 631 new UntypedExpr( 632 new NameExpr("?[?]"), 633 { 634 new NameExpr("__generator_labels"), 635 new UntypedMemberExpr( 636 new NameExpr("__generator_state"), 637 new VariableExpr( in_generator ) 638 ) 639 } 640 ) 641 ) 642 ); 643 go_decl->location = loc; 644 645 auto go = new BranchStmt( 646 new VariableExpr( go_decl ), 647 BranchStmt::Goto 648 ); 649 go->location = loc; 650 go->computedTarget->location = loc; 651 652 auto noop = new NullStmt({ first_label }); 653 noop->location = loc; 654 655 // wrap everything in a nice compound 656 auto body = new CompoundStmt({ 657 new DeclStmt( decl ), 658 new DeclStmt( go_decl ), 659 go, 660 noop, 661 func->statements 662 }); 663 body->location = loc; 664 func->statements = body; 665 666 return func; 667 } 668 669 Statement * SuspendKeyword::postmutate( SuspendStmt * stmt ) { 670 SuspendStmt::Type type = stmt->type; 671 if(type == SuspendStmt::None) { 672 // This suspend has a implicit target, find it 673 type = in_generator ? SuspendStmt::Generator : SuspendStmt::Coroutine; 674 } 675 676 // Check that the target makes sense 677 if(!in_generator && type == SuspendStmt::Generator) SemanticError( stmt->location, "'suspend generator' must be used inside main of generator type."); 678 679 // Act appropriately 680 switch(type) { 681 case SuspendStmt::Generator: return make_generator_suspend(stmt); 682 case SuspendStmt::Coroutine: return make_coroutine_suspend(stmt); 683 default: abort(); 684 } 685 } 686 687 Statement * SuspendKeyword::make_generator_suspend( SuspendStmt * stmt ) { 688 assert(in_generator); 689 // Target code is : 690 // gen.__generator_state = X; 691 // { THEN } 692 // return; 693 // __gen_X:; 694 695 // Save the location and delete the old statement, we only need the location from this point on 696 auto loc = stmt->location; 697 698 // Build the label and get its index 699 auto label = make_label(); 700 701 // Create the context saving statement 702 auto save = new ExprStmt( new UntypedExpr( 703 new NameExpr( "?=?" ), 704 { 705 new UntypedMemberExpr( 706 new NameExpr("__generator_state"), 707 new VariableExpr( in_generator ) 708 ), 709 new ConstantExpr( 710 Constant::from_int( label.idx ) 711 ) 712 } 713 )); 714 assert(save->expr); 715 save->location = loc; 716 stmtsToAddBefore.push_back( save ); 717 718 // if we have a then add it here 719 auto then = stmt->then; 720 stmt->then = nullptr; 721 delete stmt; 722 if(then) stmtsToAddBefore.push_back( then ); 723 724 // Create the return statement 725 auto ret = new ReturnStmt( nullptr ); 726 ret->location = loc; 727 stmtsToAddBefore.push_back( ret ); 728 729 // Create the null statement with the created label 730 auto noop = new NullStmt({ label.obj }); 731 noop->location = loc; 732 733 // Return the null statement to take the place of the previous statement 734 return noop; 735 } 736 737 Statement * SuspendKeyword::make_coroutine_suspend( SuspendStmt * stmt ) { 738 if(stmt->then) SemanticError( stmt->location, "Compound statement following coroutines is not implemented."); 739 740 // Save the location and delete the old statement, we only need the location from this point on 741 auto loc = stmt->location; 742 delete stmt; 743 744 // Create the call expression 745 if(!decl_suspend) SemanticError( loc, "suspend keyword applied to coroutines requires coroutines to be in scope, add #include <coroutine.hfa>\n"); 746 auto expr = new UntypedExpr( VariableExpr::functionPointer( decl_suspend ) ); 747 expr->location = loc; 748 749 // Change this statement into a regular expr 750 assert(expr); 751 auto nstmt = new ExprStmt( expr ); 752 nstmt->location = loc; 753 return nstmt; 754 } 755 451 756 452 757 //============================================================================================= -
src/Parser/ParseNode.h
r87f572e r5b544a6 428 428 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr ); 429 429 Statement * build_directive( std::string * directive ); 430 SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None); 430 431 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when ); 431 432 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing ); -
src/Parser/StatementNode.cc
r87f572e r5b544a6 249 249 } // build_finally 250 250 251 SuspendStmt * build_suspend( StatementNode * then, SuspendStmt::Type type ) { 252 auto node = new SuspendStmt(); 253 254 node->type = type; 255 256 std::list< Statement * > stmts; 257 buildMoveList< Statement, StatementNode >( then, stmts ); 258 if(!stmts.empty()) { 259 assert( stmts.size() == 1 ); 260 node->then = dynamic_cast< CompoundStmt * >( stmts.front() ); 261 } 262 263 return node; 264 } 265 251 266 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when ) { 252 267 auto node = new WaitForStmt(); -
src/Parser/TypeData.cc
r87f572e r5b544a6 769 769 case AggregateDecl::Struct: 770 770 case AggregateDecl::Coroutine: 771 case AggregateDecl::Generator: 771 772 case AggregateDecl::Monitor: 772 773 case AggregateDecl::Thread: -
src/Parser/lex.ll
r87f572e r5b544a6 65 65 #define FLOATXX(v) KEYWORD_RETURN(v); 66 66 #else 67 #define FLOATXX(v) IDENTIFIER_RETURN(); 67 #define FLOATXX(v) IDENTIFIER_RETURN(); 68 68 #endif // HAVE_KEYWORDS_FLOATXX 69 69 … … 301 301 _Static_assert { KEYWORD_RETURN(STATICASSERT); } // C11 302 302 struct { KEYWORD_RETURN(STRUCT); } 303 /* suspend { KEYWORD_RETURN(SUSPEND); } // CFA */ 303 suspend { KEYWORD_RETURN(SUSPEND); } // CFA 304 304 switch { KEYWORD_RETURN(SWITCH); } 305 305 thread { KEYWORD_RETURN(THREAD); } // C11 -
src/Parser/parser.yy
r87f572e r5b544a6 278 278 %token OTYPE FTYPE DTYPE TTYPE TRAIT // CFA 279 279 %token SIZEOF OFFSETOF 280 // %token SUSPEND RESUME // CFA 280 // %token RESUME // CFA 281 %token SUSPEND // CFA 281 282 %token ATTRIBUTE EXTENSION // GCC 282 283 %token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN … … 1259 1260 | RETURN '{' initializer_list_opt comma_opt '}' ';' 1260 1261 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } 1261 // | SUSPEND ';' 1262 // { SemanticError( yylloc, "Suspend expression is currently unimplemented." ); $$ = nullptr; } 1263 // | SUSPEND compound_statement ';' 1264 // { SemanticError( yylloc, "Suspend expression is currently unimplemented." ); $$ = nullptr; } 1262 | SUSPEND ';' 1263 { $$ = new StatementNode( build_suspend( nullptr ) ); } 1264 | SUSPEND compound_statement 1265 { $$ = new StatementNode( build_suspend( $2 ) ); } 1266 | SUSPEND COROUTINE ';' 1267 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); } 1268 | SUSPEND COROUTINE compound_statement 1269 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); } 1270 | SUSPEND GENERATOR ';' 1271 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); } 1272 | SUSPEND GENERATOR compound_statement 1273 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); } 1265 1274 | THROW assignment_expression_opt ';' // handles rethrow 1266 1275 { $$ = new StatementNode( build_throw( $2 ) ); } … … 2077 2086 aggregate_control: // CFA 2078 2087 GENERATOR 2079 { SemanticError( yylloc, "generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }2088 { yyy = true; $$ = AggregateDecl::Generator; } 2080 2089 | MONITOR GENERATOR 2081 2090 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } -
src/SynTree/Declaration.h
r87f572e r5b544a6 302 302 303 303 bool is_coroutine() { return kind == Coroutine; } 304 bool is_monitor() { return kind == Monitor; } 305 bool is_thread() { return kind == Thread; } 304 bool is_generator() { return kind == Generator; } 305 bool is_monitor () { return kind == Monitor ; } 306 bool is_thread () { return kind == Thread ; } 306 307 307 308 virtual StructDecl * clone() const override { return new StructDecl( *this ); } -
src/SynTree/Mutator.h
r87f572e r5b544a6 51 51 virtual Statement * mutate( CatchStmt * catchStmt ) = 0; 52 52 virtual Statement * mutate( FinallyStmt * catchStmt ) = 0; 53 virtual Statement * mutate( SuspendStmt * suspendStmt ) = 0; 53 54 virtual Statement * mutate( WaitForStmt * waitforStmt ) = 0; 54 55 virtual Declaration * mutate( WithStmt * withStmt ) = 0; -
src/SynTree/Statement.cc
r87f572e r5b544a6 420 420 } 421 421 422 SuspendStmt::SuspendStmt( const SuspendStmt & other ) 423 : Statement( other ) 424 , then( maybeClone(other.then) ) 425 {} 426 427 SuspendStmt::~SuspendStmt() { 428 delete then; 429 } 430 431 void SuspendStmt::print( std::ostream & os, Indenter indent ) const { 432 os << "Suspend Statement"; 433 switch (type) { 434 case None : os << " with implicit target"; break; 435 case Generator: os << " for generator" ; break; 436 case Coroutine: os << " for coroutine" ; break; 437 } 438 os << endl; 439 indent += 1; 440 441 if(then) { 442 os << indent << " with post statement :" << endl; 443 then->print( os, indent + 1); 444 } 445 } 446 422 447 WaitForStmt::WaitForStmt() : Statement() { 423 448 timeout.time = nullptr; -
src/SynTree/Statement.h
r87f572e r5b544a6 422 422 }; 423 423 424 class SuspendStmt : public Statement { 425 public: 426 CompoundStmt * then = nullptr; 427 enum Type { None, Coroutine, Generator } type = None; 428 429 SuspendStmt() = default; 430 SuspendStmt( const SuspendStmt & ); 431 virtual ~SuspendStmt(); 432 433 virtual SuspendStmt * clone() const override { return new SuspendStmt( *this ); } 434 virtual void accept( Visitor & v ) override { v.visit( this ); } 435 virtual void accept( Visitor & v ) const override { v.visit( this ); } 436 virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 437 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 438 }; 439 424 440 class WaitForStmt : public Statement { 425 441 public: -
src/SynTree/SynTree.h
r87f572e r5b544a6 54 54 class CatchStmt; 55 55 class FinallyStmt; 56 class SuspendStmt; 56 57 class WaitForStmt; 57 58 class WithStmt; -
src/SynTree/Visitor.h
r87f572e r5b544a6 78 78 virtual void visit( FinallyStmt * node ) { visit( const_cast<const FinallyStmt *>(node) ); } 79 79 virtual void visit( const FinallyStmt * finallyStmt ) = 0; 80 virtual void visit( SuspendStmt * node ) { visit( const_cast<const SuspendStmt *>(node) ); } 81 virtual void visit( const SuspendStmt * suspendStmt ) = 0; 80 82 virtual void visit( WaitForStmt * node ) { visit( const_cast<const WaitForStmt *>(node) ); } 81 83 virtual void visit( const WaitForStmt * waitforStmt ) = 0;
Note: See TracChangeset
for help on using the changeset viewer.