Changeset 3c13c03 for src/Tuples
- Timestamp:
- Sep 17, 2016, 8:27:51 AM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 8c49c0e
- Parents:
- 12bc63a
- Location:
- src/Tuples
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/Tuples/TupleAssignment.cc ¶
r12bc63a r3c13c03 39 39 private: 40 40 void match(); 41 // records for assignment generation42 struct Options {43 void print( std::ostream & );44 int size() const { return options.size(); }45 bool empty() const { return options.empty(); }46 typedef std::list< ResolvExpr::AltList >::iterator iterator;47 iterator begin() { return options.begin(); }48 iterator end() { return options.end(); }49 50 std::list< ResolvExpr::AltList > options;51 };52 41 53 42 struct Matcher { 54 43 public: 55 Matcher( TupleAssignSpotter &spotter, Expression *_lhs, Expression *_rhs );44 Matcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs ); 56 45 virtual ~Matcher() {} 57 46 virtual void match( std::list< Expression * > &out ) = 0; 58 std::list< Expression * >lhs, rhs;47 ResolvExpr::AltList lhs, rhs; 59 48 TupleAssignSpotter &spotter; 60 49 std::list< ObjectDecl * > tmpDecls; … … 63 52 struct MassAssignMatcher : public Matcher { 64 53 public: 65 MassAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) { 66 this->rhs.push_back( rhs ); 67 } 54 MassAssignMatcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs ); 68 55 virtual void match( std::list< Expression * > &out ); 69 56 }; … … 71 58 struct MultipleAssignMatcher : public Matcher { 72 59 public: 73 MultipleAssignMatcher( TupleAssignSpotter &spot, Expression *lhs, Expression *rhs );60 MultipleAssignMatcher( TupleAssignSpotter &spot, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs ); 74 61 virtual void match( std::list< Expression * > &out ); 75 62 }; … … 78 65 // Expression *rhs, *lhs; 79 66 Matcher *matcher = nullptr; 80 Options options;81 67 }; 82 83 bool isTupleVar( DeclarationWithType *decl ) {84 return dynamic_cast< TupleType * >( decl->get_type() );85 }86 68 87 69 /// true if expr is an expression of tuple type, i.e. a tuple expression, tuple variable, or MRV (multiple-return-value) function … … 89 71 if ( ! expr ) return false; 90 72 assert( expr->has_result() ); 91 // xxx - used to include cast to varExpr and call to isTupleVar, but this doesn't seem like it should be necessary92 73 return dynamic_cast<TupleExpr *>(expr) || expr->get_result()->size() > 1; 93 74 } … … 101 82 } 102 83 103 bool isTupleExpr( Expression *expr ) {104 assert( expr->has_result() );105 return expr->get_result()->size() > 1;106 }107 108 84 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) { 109 85 TupleAssignSpotter spotter( currentFinder ); … … 116 92 void TupleAssignSpotter::spot( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) { 117 93 if ( NameExpr *assgnop = dynamic_cast< NameExpr * >(expr->get_function()) ) { 118 if ( assgnop->get_name() == std::string("?=?")) {94 if ( assgnop->get_name() == "?=?" ) { 119 95 for ( std::list<ResolvExpr::AltList>::iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) { 120 assert( ali->size() == 2 );121 ResolvExpr::Alternative op1 = ali->front(), op2 = ali->back();122 123 MultipleAssignMatcher multiMatcher( *this, op1.expr, op2.expr );124 MassAssignMatcher massMatcher( *this, op1.expr, op2.expr);125 if ( pointsToTuple(op1.expr) ) { // also handles tuple vars126 if ( isTuple( op2.expr ) ) {96 if ( ali->size() != 2 ) continue; // what does it mean if an assignment takes >2 arguments? grab args 2-N and group into a TupleExpr, then proceed? 97 ResolvExpr::Alternative & alt1 = ali->front(), & alt2 = ali->back(); 98 99 if ( pointsToTuple(alt1.expr) ) { 100 MultipleAssignMatcher multiMatcher( *this, alt1, alt2 ); 101 MassAssignMatcher massMatcher( *this, alt1, alt2 ); 102 if ( isTuple( alt2.expr ) ) { 127 103 matcher = &multiMatcher; 128 104 } else { … … 131 107 } 132 108 match(); 133 } else if ( isTuple( op2.expr ) ) {109 } else if ( isTuple( alt2.expr ) ) { 134 110 throw SemanticError("Cannot assign a tuple value into a non-tuple lvalue.", expr); 135 111 } … … 170 146 } 171 147 172 TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : spotter(spotter) { 173 // xxx - shouldn't need to be &<tuple-expr>, just &<lvalue-tuple-type> 174 if (AddressExpr *addr = dynamic_cast<AddressExpr *>(lhs) ) 175 if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(addr->get_arg()) ) 176 std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(this->lhs) ); 177 } 178 179 TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) { 180 181 if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(rhs) ) 182 std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(this->rhs) ); 148 TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs ) : spotter(spotter) { 149 if (AddressExpr *addr = dynamic_cast<AddressExpr *>(lhs.expr) ) { 150 // xxx - not every assignment NEEDS to have the first argument as address-taken, e.g. a manual call to assignment. What to do in this case? skip it as a possibility for TupleAssignment, since the type will always be T*, where T can never be a tuple? Is this true? 151 152 // explode the lhs so that each field of the tuple-valued-expr is assigned. 153 ResolvExpr::Alternative lhsAlt( addr->get_arg()->clone(), lhs.env, lhs.cost, lhs.cvtCost ); 154 explode( lhsAlt, back_inserter(this->lhs) ); 155 } 156 } 157 158 TupleAssignSpotter::MassAssignMatcher::MassAssignMatcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs ) : Matcher( spotter, lhs, rhs ) { 159 this->rhs.push_back( rhs ); 160 } 161 162 TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs ) : Matcher( spotter, lhs, rhs ) { 163 164 // explode the rhs so that each field of the tuple-valued-expr is assigned. 165 explode( rhs, back_inserter(this->rhs) ); 183 166 } 184 167 … … 201 184 assert ( ! lhs.empty() && rhs.size() == 1); 202 185 203 ObjectDecl * rtmp = newObject( rhsNamer, rhs.front() );204 for ( Expression * l: lhs ) {205 ObjectDecl * ltmp = newObject( lhsNamer, new AddressExpr( l ) );186 ObjectDecl * rtmp = newObject( rhsNamer, rhs.front().expr ); 187 for ( ResolvExpr::Alternative & lhsAlt : lhs ) { 188 ObjectDecl * ltmp = newObject( lhsNamer, new AddressExpr( lhsAlt.expr ) ); 206 189 out.push_back( createAssgn( ltmp, rtmp ) ); 207 190 tmpDecls.push_back( ltmp ); … … 217 200 std::list< ObjectDecl * > ltmp; 218 201 std::list< ObjectDecl * > rtmp; 219 std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( Expression * expr){220 return newObject( lhsNamer, new AddressExpr( expr ) );202 std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( ResolvExpr::Alternative & alt ){ 203 return newObject( lhsNamer, new AddressExpr( alt.expr ) ); 221 204 }); 222 std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( Expression * expr){223 return newObject( rhsNamer, expr );205 std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( ResolvExpr::Alternative & alt ){ 206 return newObject( rhsNamer, alt.expr ); 224 207 }); 225 208 zipWith( ltmp.begin(), ltmp.end(), rtmp.begin(), rtmp.end(), back_inserter(out), createAssgn ); … … 227 210 tmpDecls.splice( tmpDecls.end(), rtmp ); 228 211 } 229 }230 231 void TupleAssignSpotter::Options::print( std::ostream &ostr ) {232 for ( ResolvExpr::AltList & l : options ) {233 for ( ResolvExpr::Alternative & alt : l ) {234 alt.print( ostr );235 ostr << " ";236 }237 ostr << std::endl;238 } // for239 212 } 240 213 } // namespace Tuples -
TabularUnified src/Tuples/TupleExpansion.cc ¶
r12bc63a r3c13c03 23 23 #include "SynTree/Declaration.h" 24 24 #include "SynTree/Type.h" 25 #include "SynTree/Expression.h" 26 #include "SynTree/Initializer.h" 25 27 #include "SymTab/Mangler.h" 26 28 #include "Common/ScopedMap.h" 27 29 28 30 namespace Tuples { 29 class TupleAssignExpander : public Mutator { 30 public: 31 virtual Expression * mutate( TupleAssignExpr * tupleExpr ); 32 }; 31 namespace { 32 class UniqueExprExpander : public GenPoly::DeclMutator { 33 public: 34 typedef GenPoly::DeclMutator Parent; 35 virtual Expression * mutate( UniqueExpr * unqExpr ); 36 std::map< Expression *, ObjectDecl * > decls; 37 }; 33 38 34 class TupleTypeReplacer : public GenPoly::DeclMutator { 35 public: 36 typedef GenPoly::DeclMutator Parent; 39 class TupleAssignExpander : public Mutator { 40 public: 41 typedef Mutator Parent; 42 virtual Expression * mutate( TupleAssignExpr * tupleExpr ); 43 }; 37 44 38 virtual Type * mutate( TupleType * tupleType ); 45 class TupleTypeReplacer : public GenPoly::DeclMutator { 46 public: 47 typedef GenPoly::DeclMutator Parent; 39 48 40 virtual CompoundStmt * mutate( CompoundStmt * stmt ) { 41 typeMap.beginScope(); 42 stmt = Parent::mutate( stmt ); 43 typeMap.endScope(); 44 return stmt; 45 } 46 private: 47 ScopedMap< std::string, StructDecl * > typeMap; 48 }; 49 virtual Type * mutate( TupleType * tupleType ); 50 51 virtual CompoundStmt * mutate( CompoundStmt * stmt ) { 52 typeMap.beginScope(); 53 stmt = Parent::mutate( stmt ); 54 typeMap.endScope(); 55 return stmt; 56 } 57 private: 58 ScopedMap< std::string, StructDecl * > typeMap; 59 }; 60 61 class TupleIndexExpander : public Mutator { 62 public: 63 typedef Mutator Parent; 64 virtual Expression * mutate( TupleIndexExpr * tupleExpr ); 65 }; 66 67 class TupleExprExpander : public Mutator { 68 public: 69 typedef Mutator Parent; 70 virtual Expression * mutate( TupleExpr * tupleExpr ); 71 }; 72 } 49 73 50 74 void expandTuples( std::list< Declaration * > & translationUnit ) { 51 TupleAssignExpander expander; 52 mutateAll( translationUnit, expander ); 75 UniqueExprExpander unqExpander; 76 unqExpander.mutateDeclarationList( translationUnit ); 77 78 TupleAssignExpander assnExpander; 79 mutateAll( translationUnit, assnExpander ); 53 80 54 81 TupleTypeReplacer replacer; 55 82 replacer.mutateDeclarationList( translationUnit ); 83 84 TupleIndexExpander idxExpander; 85 mutateAll( translationUnit, idxExpander ); 86 87 TupleExprExpander exprExpander; 88 mutateAll( translationUnit, exprExpander ); 56 89 } 57 90 58 Expression * TupleAssignExpander::mutate( TupleAssignExpr * tupleExpr ) { 91 Expression * UniqueExprExpander::mutate( UniqueExpr * unqExpr ) { 92 static UniqueName tempNamer( "_unq_expr_" ); 93 unqExpr = safe_dynamic_cast< UniqueExpr * > ( Parent::mutate( unqExpr ) ); 94 if ( ! decls.count( unqExpr->get_expr() ) ) { 95 // xxx - it's possible (likely?) that expressions can appear in the wrong order because of this. Need to ensure they're placed in the correct location. 96 ObjectDecl * decl = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, unqExpr->get_result()->clone(), new SingleInit( unqExpr->get_expr()->clone() ) ); 97 decls[unqExpr->get_expr()] = decl; 98 addDeclaration( decl ); 99 } 100 return new VariableExpr( decls[unqExpr->get_expr()] ); 101 } 102 103 Expression * TupleAssignExpander::mutate( TupleAssignExpr * assnExpr ) { 104 // xxx - Parent::mutate? 59 105 CompoundStmt * compoundStmt = new CompoundStmt( noLabels ); 60 106 std::list< Statement * > & stmts = compoundStmt->get_kids(); 61 for ( ObjectDecl * obj : tupleExpr->get_tempDecls() ) {107 for ( ObjectDecl * obj : assnExpr->get_tempDecls() ) { 62 108 stmts.push_back( new DeclStmt( noLabels, obj ) ); 63 109 } 64 for ( Expression * assign : tupleExpr->get_assigns() ) {65 stmts.push_back( new ExprStmt( noLabels, assign) );66 }67 tupleExpr->get_tempDecls().clear();68 tupleExpr->get_assigns().clear();69 delete tupleExpr;110 TupleExpr * tupleExpr = new TupleExpr( assnExpr->get_assigns() ); 111 assert( tupleExpr->get_result() ); 112 stmts.push_back( new ExprStmt( noLabels, tupleExpr ) ); 113 assnExpr->get_tempDecls().clear(); 114 assnExpr->get_assigns().clear(); 115 delete assnExpr; 70 116 return new StmtExpr( compoundStmt ); 71 117 } … … 90 136 } 91 137 138 Expression * TupleIndexExpander::mutate( TupleIndexExpr * tupleExpr ) { 139 Expression * tuple = maybeMutate( tupleExpr->get_tuple(), *this ); 140 assert( tuple ); 141 tupleExpr->set_tuple( nullptr ); 142 unsigned int idx = tupleExpr->get_index(); 143 delete tupleExpr; 144 145 StructInstType * type = safe_dynamic_cast< StructInstType * >( tuple->get_result() ); 146 StructDecl * structDecl = type->get_baseStruct(); 147 assert( structDecl->get_members().size() > idx ); 148 Declaration * member = *std::next(structDecl->get_members().begin(), idx); 149 return new MemberExpr( safe_dynamic_cast< DeclarationWithType * >( member ), tuple ); 150 } 151 152 Expression * TupleExprExpander::mutate( TupleExpr * tupleExpr ) { 153 assert( tupleExpr->get_result() ); 154 std::list< Initializer * > inits; 155 for ( Expression * expr : tupleExpr->get_exprs() ) { 156 inits.push_back( new SingleInit( expr ) ); 157 } 158 return new CompoundLiteralExpr( tupleExpr->get_result(), new ListInit( inits ) ); 159 } 160 161 TupleType * makeTupleType( const std::list< Expression * > & exprs ) { 162 TupleType *tupleType = new TupleType( Type::Qualifiers(true, true, true, true, true, false) ); 163 Type::Qualifiers &qualifiers = tupleType->get_qualifiers(); 164 for ( Expression * expr : exprs ) { 165 assert( expr->get_result() ); 166 Type * type = expr->get_result()->clone(); 167 tupleType->get_types().push_back( type ); 168 qualifiers &= type->get_qualifiers(); 169 } // for 170 return tupleType; 171 } 92 172 } // namespace Tuples 93 173 -
TabularUnified src/Tuples/Tuples.h ¶
r12bc63a r3c13c03 31 31 // TupleExpansion.cc 32 32 void expandTuples( std::list< Declaration * > & translationUnit ); 33 34 TupleType * makeTupleType( const std::list< Expression * > & exprs ); 33 35 } // namespace Tuples 34 36
Note: See TracChangeset
for help on using the changeset viewer.