- Timestamp:
- Sep 13, 2024, 10:05:05 AM (3 months ago)
- Branches:
- master
- Children:
- 5ef4008
- Parents:
- 3733643
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/TranslateEnumRange.cpp
r3733643 r9739c56f 6 6 namespace ControlStruct { 7 7 8 struct addInit { 9 const ast::Stmt * postvisit( const ast::ForStmt * stmt ); 8 namespace { 9 10 struct TranslateEnumRangeCore { 11 const ast::Stmt * postvisit( const ast::ForStmt * stmt ); 10 12 }; 11 13 12 struct translateEnumRangeCore { 13 const ast::Stmt * postvisit( const ast::ForStmt * stmt ); 14 }; 14 const ast::Stmt * TranslateEnumRangeCore::postvisit( const ast::ForStmt * stmt ) { 15 if ( !stmt->range_over ) return stmt; 16 auto mutStmt = ast::mutate( stmt ); 17 auto & location = mutStmt->location; 15 18 16 const ast::Stmt* addInit::postvisit( const ast::ForStmt * stmt ) { 17 if ( stmt->range_over ) { 18 auto inits = stmt->inits; 19 auto init = stmt->inits.front(); 19 if ( auto declStmt = mutStmt->inits.front().as<ast::DeclStmt>() ) { 20 if ( auto objDecl = declStmt->decl.as<ast::ObjectDecl>() ) { 21 if ( !objDecl->init ) { 22 ast::SingleInit * newInit = new ast::SingleInit( location, 23 ast::UntypedExpr::createCall( location, 24 mutStmt->is_inc ? "lowerBound" : "upperBound", {} ), 25 ast::ConstructFlag::MaybeConstruct 26 ); 27 auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit ); 28 auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit ); 29 mutStmt->inits[0] = declWithInit; 30 } 31 } 32 } 20 33 21 if (auto declStmt = init.as<ast::DeclStmt>()) { 22 auto decl = declStmt->decl; 23 if ( auto objDecl = decl.as<ast::ObjectDecl>()) { 24 if ( !objDecl->init ) { 25 auto location = stmt->location; 26 ast::SingleInit * newInit = new ast::SingleInit( location, 27 stmt->is_inc? 28 ast::UntypedExpr::createCall( location, "lowerBound", {} ): 29 ast::UntypedExpr::createCall( location, "upperBound", {} ), 30 ast::ConstructFlag::MaybeConstruct 31 ); 32 auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit ); 33 auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit ); 34 stmt = ast::mutate_field_index( stmt, &ast::ForStmt::inits, 0, declWithInit ); 35 } 36 } 37 } 38 } 39 return stmt; 34 auto declStmt = mutStmt->inits.front().strict_as<ast::DeclStmt>(); 35 auto initDecl = declStmt->decl.strict_as<ast::ObjectDecl>(); 36 auto indexName = initDecl->name; 37 38 // Both inc and dec check if the current posn less than the number of enumerator 39 // for dec, it keeps call pred until it passes 0 (the first enumerator) and underflow, 40 // it wraps around and become unsigned max 41 ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location, 42 mutStmt->is_inc ? "?<=?" : "?>=?", 43 { 44 new ast::NameExpr( location, indexName ), 45 ast::UntypedExpr::createCall( location, 46 mutStmt->is_inc ? "upperBound" : "lowerBound", {} ) 47 } ); 48 auto increment = ast::UntypedExpr::createCall( location, 49 mutStmt->is_inc ? "succ_unsafe" : "pred_unsafe", 50 { new ast::NameExpr( location, indexName ) } ); 51 auto assig = ast::UntypedExpr::createAssign( location, 52 new ast::NameExpr( location, indexName ), increment ); 53 mutStmt->cond = condition; 54 mutStmt->inc = assig; 55 return mutStmt; 40 56 } 41 57 42 const ast::Stmt* translateEnumRangeCore::postvisit( const ast::ForStmt * stmt ) { 43 if ( !stmt->range_over ) return stmt; 44 auto location = stmt->location; 45 auto declStmt = stmt->inits.front().strict_as<ast::DeclStmt>(); 46 auto initDecl = declStmt->decl.strict_as<ast::ObjectDecl>(); 47 auto indexName = initDecl->name; 48 49 // Both inc and dec check if the current posn less than the number of enumerator 50 // for dec, it keeps call pred until it passes 0 (the first enumerator) and underflow, 51 // it wraps around and become unsigned max 52 ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location, 53 stmt->is_inc? "?<=?": "?>=?", 54 { new ast::NameExpr( location, indexName ), 55 stmt->is_inc? 56 ast::UntypedExpr::createCall( location, "upperBound", {} ): 57 ast::UntypedExpr::createCall( location, "lowerBound", {} ) 58 }); 59 auto increment = ast::UntypedExpr::createCall( location, 60 stmt->is_inc? "succ_unsafe": "pred_unsafe", 61 { new ast::NameExpr( location, indexName ) }); 62 auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment ); 63 auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition ); 64 mut = ast::mutate_field(stmt, &ast::ForStmt::inc, assig ); 65 return mut; 66 } 58 } // namespace 67 59 68 60 void translateEnumRange( ast::TranslationUnit & translationUnit ) { 69 ast::Pass<addInit>::run( translationUnit ); 70 ast::Pass<translateEnumRangeCore>::run( translationUnit ); 61 ast::Pass<TranslateEnumRangeCore>::run( translationUnit ); 71 62 } 72 } 63 64 } // namespace ControlStruct
Note: See TracChangeset
for help on using the changeset viewer.