Changeset 9739c56f for src/ControlStruct


Ignore:
Timestamp:
Sep 13, 2024, 10:05:05 AM (3 weeks ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
5ef4008
Parents:
3733643
Message:

Clean-up in TranslateEnumRange?.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/TranslateEnumRange.cpp

    r3733643 r9739c56f  
    66namespace ControlStruct {
    77
    8 struct addInit {
    9     const ast::Stmt * postvisit( const ast::ForStmt * stmt );
     8namespace {
     9
     10struct TranslateEnumRangeCore {
     11        const ast::Stmt * postvisit( const ast::ForStmt * stmt );
    1012};
    1113
    12 struct translateEnumRangeCore {
    13     const ast::Stmt * postvisit( const ast::ForStmt * stmt );
    14 };
     14const 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;
    1518
    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        }
    2033
    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;
    4056}
    4157
    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
    6759
    6860void translateEnumRange( ast::TranslationUnit & translationUnit ) {
    69     ast::Pass<addInit>::run( translationUnit );
    70     ast::Pass<translateEnumRangeCore>::run( translationUnit );
     61        ast::Pass<TranslateEnumRangeCore>::run( translationUnit );
    7162}
    72 }
     63
     64} // namespace ControlStruct
Note: See TracChangeset for help on using the changeset viewer.