Changeset 7870799 for src/Tuples
- Timestamp:
- Jul 12, 2019, 10:49:02 AM (6 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:
- ef5b828
- Parents:
- ee6dbae
- Location:
- src/Tuples
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/Explode.h
ree6dbae r7870799 51 51 template<typename OutputIterator> 52 52 void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env, 53 const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need, 53 const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need, 54 54 const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) { 55 55 *out++ = ResolvExpr::Alternative{ expr, env, openVars, need, cost, cvtCost }; … … 58 58 /// Append alternative to an ExplodedActual 59 59 static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr, 60 const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&, 60 const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&, 61 61 const ResolvExpr::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) { 62 62 ea.exprs.emplace_back( expr ); … … 111 111 } else { 112 112 // atomic (non-tuple) type - output a clone of the expression in a new alternative 113 append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need, 113 append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need, 114 114 alt.cost, alt.cvtCost ); 115 115 } … … 174 174 template< typename Output > 175 175 void explodeRecursive( 176 const ast::CastExpr * expr, const ResolvExpr::Candidate & arg,177 const ast::SymbolTable & symtab, Output && out176 const ast::CastExpr *, const ResolvExpr::Candidate &, 177 const ast::SymbolTable &, Output && 178 178 ) { 179 179 } … … 240 240 /// explode list of candidates into flattened list of candidates 241 241 template< typename Output > 242 void explode( 243 const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out, 242 void explode( 243 const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out, 244 244 bool isTupleAssign = false 245 245 ) { -
src/Tuples/TupleAssignment.cc
ree6dbae r7870799 67 67 struct Matcher { 68 68 public: 69 Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs, 69 Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs, 70 70 const ResolvExpr::AltList& rhs ); 71 71 virtual ~Matcher() {} 72 72 73 73 virtual void match( std::list< Expression * > &out ) = 0; 74 74 ObjectDecl * newObject( UniqueName & namer, Expression * expr ); … … 83 83 for ( const ResolvExpr::Alternative& alt : alts ) { combineState( alt ); } 84 84 } 85 85 86 86 ResolvExpr::AltList lhs, rhs; 87 87 TupleAssignSpotter_old &spotter; … … 264 264 } 265 265 266 // extract expressions from the assignment alternatives to produce a list of assignments 266 // extract expressions from the assignment alternatives to produce a list of assignments 267 267 // that together form a single alternative 268 268 std::list< Expression *> solved_assigns; … … 271 271 matcher->combineState( alt ); 272 272 } 273 273 274 274 // xxx -- was push_front 275 275 currentFinder.get_alternatives().push_back( ResolvExpr::Alternative{ 276 new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv, 277 matcher->openVars, 278 ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ), 276 new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv, 277 matcher->openVars, 278 ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ), 279 279 ResolvExpr::sumCost( current ) + matcher->baseCost } ); 280 280 } … … 284 284 : lhs(lhs), rhs(rhs), spotter(spotter), 285 285 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) { 286 combineState( lhs ); 286 combineState( lhs ); 287 287 combineState( rhs ); 288 288 } … … 390 390 return dynamic_cast< const ast::TupleType * >( expr->result->stripReferences() ); 391 391 } 392 392 393 393 /// true if `expr` is of tuple type or a reference to one 394 394 bool refToTuple( const ast::Expr * expr ) { … … 421 421 } 422 422 423 Matcher( 423 Matcher( 424 424 TupleAssignSpotter_new & s, const CodeLocation & loc, 425 425 const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r ) 426 : lhs( l ), rhs( r ), spotter( s ), location( loc ), 427 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ), tmpDecls(), 426 : lhs( l ), rhs( r ), spotter( s ), location( loc ), 427 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ), tmpDecls(), 428 428 env(), open(), need() { 429 429 for ( auto & cand : lhs ) combineState( *cand ); 430 430 for ( auto & cand : rhs ) combineState( *cand ); 431 431 } 432 virtual ~Matcher() = default; 432 433 433 434 virtual std::vector< ast::ptr< ast::Expr > > match() = 0; 434 435 435 /// removes environments from subexpressions within statement expressions, which could 436 /// throw off later passes like those in Box which rely on PolyMutator, and adds the 436 /// removes environments from subexpressions within statement expressions, which could 437 /// throw off later passes like those in Box which rely on PolyMutator, and adds the 437 438 /// bindings to the env 438 439 struct EnvRemover { … … 455 456 ast::ObjectDecl * newObject( UniqueName & namer, const ast::Expr * expr ) { 456 457 assert( expr->result && ! expr->result->isVoid() ); 457 458 ast::ObjectDecl * ret = new ast::ObjectDecl{ 459 location, namer.newName(), expr->result, new ast::SingleInit{ location, expr }, 458 459 ast::ObjectDecl * ret = new ast::ObjectDecl{ 460 location, namer.newName(), expr->result, new ast::SingleInit{ location, expr }, 460 461 ast::Storage::Classes{}, ast::Linkage::Cforall }; 461 462 462 463 // if expression type is a reference, just need an initializer, otherwise construct 463 464 if ( ! expr->result.as< ast::ReferenceType >() ) { 464 465 // resolve ctor/dtor for the new object 465 ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 466 ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 466 467 InitTweak::genCtorInit( location, ret ), spotter.crntFinder.symtab ); 467 468 // remove environments from subexpressions of stmtExpr … … 474 475 } 475 476 476 ast::UntypedExpr * createFunc( 477 const std::string & fname, const ast::ObjectDecl * left, 478 const ast::ObjectDecl * right 477 ast::UntypedExpr * createFunc( 478 const std::string & fname, const ast::ObjectDecl * left, 479 const ast::ObjectDecl * right 479 480 ) { 480 481 assert( left ); … … 486 487 args.front() = new ast::AddressExpr{ location, args.front() }; 487 488 if ( right ) { args.back() = new ast::AddressExpr{ location, args.back() }; } 488 return new ast::UntypedExpr{ 489 return new ast::UntypedExpr{ 489 490 location, new ast::NameExpr{ location, "?=?" }, std::move(args) }; 490 491 } else { 491 return new ast::UntypedExpr{ 492 return new ast::UntypedExpr{ 492 493 location, new ast::NameExpr{ location, fname }, std::move(args) }; 493 494 } … … 498 499 struct MassAssignMatcher final : public Matcher { 499 500 MassAssignMatcher( 500 TupleAssignSpotter_new & s, const CodeLocation & loc, 501 TupleAssignSpotter_new & s, const CodeLocation & loc, 501 502 const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r ) 502 503 : Matcher( s, loc, l, r ) {} … … 508 509 assert( lhs.empty() ? rhs.empty() : rhs.size() <= 1 ); 509 510 510 ast::ptr< ast::ObjectDecl > rtmp = 511 ast::ptr< ast::ObjectDecl > rtmp = 511 512 rhs.size() == 1 ? newObject( rhsNamer, rhs.front()->expr ) : nullptr; 512 513 513 514 std::vector< ast::ptr< ast::Expr > > out; 514 515 for ( ResolvExpr::CandidateRef & lhsCand : lhs ) { 515 // create a temporary object for each value in the LHS and create a call 516 // create a temporary object for each value in the LHS and create a call 516 517 // involving the RHS 517 518 ast::ptr< ast::ObjectDecl > ltmp = newObject( lhsNamer, lhsCand->expr ); … … 528 529 struct MultipleAssignMatcher final : public Matcher { 529 530 MultipleAssignMatcher( 530 TupleAssignSpotter_new & s, const CodeLocation & loc, 531 TupleAssignSpotter_new & s, const CodeLocation & loc, 531 532 const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r ) 532 533 : Matcher( s, loc, l, r ) {} … … 538 539 if ( lhs.size() != rhs.size() ) return {}; 539 540 540 // produce a new temporary object for each value in the LHS and RHS and pairwise 541 // produce a new temporary object for each value in the LHS and RHS and pairwise 541 542 // create the calls 542 543 std::vector< ast::ptr< ast::ObjectDecl > > ltmp, rtmp; … … 547 548 ResolvExpr::CandidateRef & rhsCand = rhs[i]; 548 549 549 // convert RHS to LHS type minus one reference -- important for case where LHS 550 // convert RHS to LHS type minus one reference -- important for case where LHS 550 551 // is && and RHS is lvalue 551 552 auto lhsType = lhsCand->expr->result.strict_as< ast::ReferenceType >(); … … 557 558 rtmp.emplace_back( std::move( robj ) ); 558 559 559 // resolve the cast expression so that rhsCand return type is bound by the cast 560 // resolve the cast expression so that rhsCand return type is bound by the cast 560 561 // type as needed, and transfer the resulting environment 561 562 ResolvExpr::CandidateFinder finder{ spotter.crntFinder.symtab, env }; … … 564 565 env = std::move( finder.candidates.front()->env ); 565 566 } 566 567 567 568 splice( tmpDecls, ltmp ); 568 569 splice( tmpDecls, rtmp ); 569 570 570 571 return out; 571 572 } … … 575 576 std::string fname; 576 577 std::unique_ptr< Matcher > matcher; 577 578 578 579 public: 579 TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f ) 580 TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f ) 580 581 : crntFinder( f ), fname(), matcher() {} 581 582 582 583 // find left- and right-hand-sides for mass or multiple assignment 583 void spot( 584 const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args 584 void spot( 585 const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args 585 586 ) { 586 587 if ( auto op = expr->func.as< ast::NameExpr >() ) { … … 599 600 if ( ! refToTuple( lhsCand->expr ) ) continue; 600 601 601 // explode is aware of casts - ensure every LHS is sent into explode with a 602 // explode is aware of casts - ensure every LHS is sent into explode with a 602 603 // reference cast 603 604 if ( ! lhsCand->expr.as< ast::CastExpr >() ) { 604 lhsCand->expr = new ast::CastExpr{ 605 lhsCand->expr = new ast::CastExpr{ 605 606 lhsCand->expr, new ast::ReferenceType{ lhsCand->expr->result } }; 606 607 } … … 610 611 explode( *lhsCand, crntFinder.symtab, back_inserter(lhs), true ); 611 612 for ( ResolvExpr::CandidateRef & cand : lhs ) { 612 // each LHS value must be a reference - some come in with a cast, if not 613 // each LHS value must be a reference - some come in with a cast, if not 613 614 // just cast to reference here 614 615 if ( ! cand->expr->result.as< ast::ReferenceType >() ) { … … 629 630 // multiple assignment 630 631 explode( *rhsCand, crntFinder.symtab, back_inserter(rhs), true ); 631 matcher.reset( 632 matcher.reset( 632 633 new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } ); 633 634 } else { 634 635 // mass assignment 635 636 rhs.emplace_back( rhsCand ); 636 matcher.reset( 637 matcher.reset( 637 638 new MassAssignMatcher{ *this, expr->location, lhs, rhs } ); 638 639 } … … 642 643 // expand all possible RHS possibilities 643 644 std::vector< ResolvExpr::CandidateList > rhsCands; 644 combos( 645 combos( 645 646 std::next( args.begin(), 1 ), args.end(), back_inserter( rhsCands ) ); 646 647 for ( const ResolvExpr::CandidateList & rhsCand : rhsCands ) { … … 648 649 ResolvExpr::CandidateList rhs; 649 650 explode( rhsCand, crntFinder.symtab, back_inserter(rhs), true ); 650 matcher.reset( 651 matcher.reset( 651 652 new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } ); 652 653 match(); … … 663 664 664 665 if ( ! ( matcher->lhs.empty() && matcher->rhs.empty() ) ) { 665 // if both LHS and RHS are empty than this is the empty tuple case, wherein it's 666 // okay for newAssigns to be empty. Otherwise, return early so that no new 666 // if both LHS and RHS are empty than this is the empty tuple case, wherein it's 667 // okay for newAssigns to be empty. Otherwise, return early so that no new 667 668 // candidates are generated 668 669 if ( newAssigns.empty() ) return; … … 692 693 } 693 694 694 // extract expressions from the assignment candidates to produce a list of assignments 695 // extract expressions from the assignment candidates to produce a list of assignments 695 696 // that together form a sigle candidate 696 697 std::vector< ast::ptr< ast::Expr > > solved; … … 701 702 702 703 crntFinder.candidates.emplace_back( std::make_shared< ResolvExpr::Candidate >( 703 new ast::TupleAssignExpr{ 704 matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) }, 705 std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ), 704 new ast::TupleAssignExpr{ 705 matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) }, 706 std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ), 706 707 ResolvExpr::sumCost( crnt ) + matcher->baseCost ) ); 707 708 } … … 709 710 } // anonymous namespace 710 711 711 void handleTupleAssignment( 712 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 712 void handleTupleAssignment( 713 ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign, 713 714 std::vector< ResolvExpr::CandidateFinder > & args 714 715 ) {
Note: See TracChangeset
for help on using the changeset viewer.