Ignore:
Timestamp:
Sep 23, 2024, 11:14:56 AM (6 weeks ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
738a9b4
Parents:
b723b63
Message:

Added ForeachStmt? (felt better than ForEachStmt?). This new node is a bit optimistic in that currently it is covering a very narrow case, but with improvements to it and RangeExpr?, it could handle many more kind of loops.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/TranslateEnumRange.cpp

    rb723b63 rfca78f1  
    99
    1010struct TranslateEnumRangeCore {
    11         const ast::Stmt * postvisit( const ast::ForStmt * stmt );
     11        const ast::Stmt * postvisit( const ast::ForeachStmt * stmt );
    1212};
    1313
    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;
     14const ast::Stmt * TranslateEnumRangeCore::postvisit( const ast::ForeachStmt * stmt ) {
     15        auto & location = stmt->location;
    1816
    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                 }
     17        assert( stmt->inits.size() == 1 );
     18        ast::DeclStmt const * initialize = stmt->inits.front().strict_as<ast::DeclStmt>();
     19
     20        auto objDecl = initialize->decl.strict_as<ast::ObjectDecl>();
     21        if ( !objDecl->init ) {
     22                ast::SingleInit * init = new ast::SingleInit( location,
     23                        ast::UntypedExpr::createCall( location,
     24                                stmt->isIncreasing ? "lowerBound" : "upperBound", {} ),
     25                        ast::ConstructFlag::MaybeConstruct
     26                );
     27                objDecl = ast::mutate_field( objDecl, &ast::ObjectDecl::init, init );
     28                initialize = ast::mutate_field( initialize, &ast::DeclStmt::decl, objDecl );
    3229        }
    3330
    34         auto declStmt = mutStmt->inits.front().strict_as<ast::DeclStmt>();
    35         auto initDecl = declStmt->decl.strict_as<ast::ObjectDecl>();
    36         auto indexName = initDecl->name;
     31        auto indexName = objDecl->name;
    3732
    3833        // Both inc and dec check if the current posn less than the number of enumerator
     
    4035        // it wraps around and become unsigned max
    4136        ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location,
    42                 mutStmt->is_inc ? "?<=?" : "?>=?",
     37                stmt->isIncreasing ? "?<=?" : "?>=?",
    4338                {
    4439                        new ast::NameExpr( location, indexName ),
    4540                        ast::UntypedExpr::createCall( location,
    46                                 mutStmt->is_inc ? "upperBound" : "lowerBound", {} )
     41                                stmt->isIncreasing ? "upperBound" : "lowerBound", {} )
    4742                } );
    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;
     43        ast::UntypedExpr * increment = ast::UntypedExpr::createAssign( location,
     44                new ast::NameExpr( location, indexName ),
     45                ast::UntypedExpr::createCall( location,
     46                        stmt->isIncreasing ? "succ_unsafe" : "pred_unsafe",
     47                        { new ast::NameExpr( location, indexName ) } ) );
     48
     49        return new ast::ForStmt(
     50                stmt->location,
     51                { initialize },
     52                condition,
     53                increment,
     54                stmt->body,
     55                stmt->else_,
     56                copy( stmt->labels )
     57        );
    5658}
    5759
Note: See TracChangeset for help on using the changeset viewer.