Changeset fca78f1


Ignore:
Timestamp:
Sep 23, 2024, 11:14:56 AM (5 months 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.

Location:
src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified src/AST/Fwd.hpp

    rb723b63 rfca78f1  
    4949class WhileDoStmt;
    5050class ForStmt;
     51class ForeachStmt;
    5152class SwitchStmt;
    5253class CaseClause;
  • TabularUnified src/AST/Pass.hpp

    rb723b63 rfca78f1  
    138138        const ast::Stmt *             visit( const ast::WhileDoStmt          * ) override final;
    139139        const ast::Stmt *             visit( const ast::ForStmt              * ) override final;
     140        const ast::Stmt *             visit( const ast::ForeachStmt          * ) override final;
    140141        const ast::Stmt *             visit( const ast::SwitchStmt           * ) override final;
    141142        const ast::CaseClause *       visit( const ast::CaseClause           * ) override final;
  • TabularUnified src/AST/Pass.impl.hpp

    rb723b63 rfca78f1  
    803803                maybe_accept_top( node, &ForStmt::cond  );
    804804                maybe_accept_top( node, &ForStmt::inc   );
    805                 maybe_accept_top( node, &ForStmt::range_over );
    806805                maybe_accept_as_compound( node, &ForStmt::body  );
    807806                maybe_accept_as_compound( node, &ForStmt::else_ );
     807        }
     808
     809        VISIT_END( Stmt, node );
     810}
     811
     812//--------------------------------------------------------------------------
     813// ForeachStmt
     814template< typename core_t >
     815const ast::Stmt * ast::Pass< core_t >::visit( const ast::ForeachStmt * node ) {
     816        VISIT_START( node );
     817
     818        if ( __visit_children() ) {
     819                // for statements introduce a level of scope (for the initialization)
     820                guard_symtab guard { *this };
     821                // xxx - old ast does not create WithStmtsToAdd scope for loop inits. should revisit this later.
     822                maybe_accept( node, &ForeachStmt::inits );
     823                maybe_accept_top( node, &ForeachStmt::range );
     824                maybe_accept_as_compound( node, &ForeachStmt::body  );
     825                maybe_accept_as_compound( node, &ForeachStmt::else_ );
    808826        }
    809827
  • TabularUnified src/AST/Print.cpp

    rb723b63 rfca78f1  
    637637        }
    638638
     639        virtual const ast::Stmt * visit( const ast::ForeachStmt * node ) override final {
     640                os << "Range for Statement" << endl;
     641
     642                if ( ! node->inits.empty() ) {
     643                        os << indent << "... initialization:" << endl;
     644                        ++indent;
     645                        for ( const ast::Stmt * stmt : node->inits ) {
     646                                os << indent+1;
     647                                safe_print( stmt );
     648                        }
     649                        --indent;
     650                }
     651
     652                if ( node->isIncreasing ) {
     653                        os << indent << "increasing" << endl;
     654                } else {
     655                        os << indent << "decreasing" << endl;
     656                }
     657
     658                if ( !node->range ) {
     659                        os << indent << "... over range:" << endl;
     660                        ++indent;
     661                        node->range->accept( *this );
     662                        --indent;
     663                }
     664
     665                if ( node->body ) {
     666                        os << indent << "... with body:" << endl;
     667                        ++indent;
     668                        os << indent;
     669                        node->body->accept( *this );
     670                        --indent;
     671                }
     672
     673                if ( node->else_ ) {
     674                        os << indent << "... with else:" << endl;
     675                        ++indent;
     676                        os << indent;
     677                        node->else_->accept( *this );
     678                        --indent;
     679                }
     680
     681                os << endl;
     682                print( node->labels );
     683
     684                return node;
     685        }
     686
    639687        virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
    640688                os << "Switch on condition: ";
  • TabularUnified src/AST/Stmt.hpp

    rb723b63 rfca78f1  
    237237        ptr<Expr> cond;
    238238        ptr<Expr> inc;
    239         ptr<Expr> range_over;
    240         bool is_inc;
    241239        ptr<Stmt> body;
    242240        ptr<Stmt> else_;
     
    245243                         const Expr * inc, const Stmt * body, const std::vector<Label> && label = {} )
    246244                : Stmt(loc, std::move(label)), inits(std::move(inits)), cond(cond), inc(inc),
    247                         range_over(nullptr), body(body), else_(nullptr) {}
     245                body(body), else_(nullptr) {}
    248246
    249247        ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * cond,
    250248                         const Expr * inc, const Stmt * body, const Stmt * else_, const std::vector<Label> && labels = {} )
    251249                : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc),
    252                         range_over(nullptr), body(body), else_(else_) {}
    253 
    254         ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over, bool is_inc,
    255                          const Stmt * body, const Stmt * else_ )
    256                 : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), is_inc(is_inc),
    257250                body(body), else_(else_) {}
    258251
     
    260253  private:
    261254        ForStmt * clone() const override { return new ForStmt{ *this }; }
     255        MUTATE_FRIEND
     256};
     257
     258enum RangeDirection { DecreasingRange, IncreasingRange };
     259
     260// For-each loop: for (... : ...) ... else ...
     261class ForeachStmt final : public Stmt {
     262  public:
     263        std::vector<ptr<Stmt>> inits;
     264        ptr<Expr> range;
     265        ptr<Stmt> body;
     266        ptr<Stmt> else_;
     267        // This is a property of the range, but there is no place to store it.
     268        RangeDirection isIncreasing;
     269
     270        ForeachStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits,
     271                        const Expr * range_over, RangeDirection isInc, const Stmt * body, const Stmt * else_ )
     272                : Stmt(loc, std::move(labels)), inits(std::move(inits)), range(range_over),
     273                body(body), else_(else_), isIncreasing(isInc) {}
     274
     275        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
     276  private:
     277        ForeachStmt * clone() const override { return new ForeachStmt{ *this }; }
    262278        MUTATE_FRIEND
    263279};
  • TabularUnified src/AST/Visitor.hpp

    rb723b63 rfca78f1  
    4141    virtual const ast::Stmt *             visit( const ast::WhileDoStmt          * ) = 0;
    4242    virtual const ast::Stmt *             visit( const ast::ForStmt              * ) = 0;
     43    virtual const ast::Stmt *             visit( const ast::ForeachStmt          * ) = 0;
    4344    virtual const ast::Stmt *             visit( const ast::SwitchStmt           * ) = 0;
    4445    virtual const ast::CaseClause *       visit( const ast::CaseClause           * ) = 0;
  • TabularUnified src/Common/CodeLocationTools.cpp

    rb723b63 rfca78f1  
    119119    macro(WhileDoStmt, Stmt) \
    120120    macro(ForStmt, Stmt) \
     121    macro(ForeachStmt, Stmt) \
    121122    macro(SwitchStmt, Stmt) \
    122123    macro(CaseClause, CaseClause) \
  • TabularUnified 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
  • TabularUnified src/Parser/StatementNode.cpp

    rb723b63 rfca78f1  
    213213        if ( forctl->range_over ) {
    214214                ast::Expr * range_over = maybeMoveBuild( forctl->range_over );
    215                 auto kind = forctl->kind;                                               // save before delete, used in return
     215                bool isIncreasing = forctl->kind == OperKinds::LEThan;
     216                // Copy all the data needed before the delete.
    216217                delete forctl;
    217                 return new ast::ForStmt( location,
     218                return new ast::ForeachStmt( location,
    218219                        std::move( astinit ),
    219                         range_over, kind == OperKinds::LEThan,
     220                        range_over,
     221                        isIncreasing ? ast::IncreasingRange : ast::DecreasingRange,
    220222                        buildMoveSingle( stmt ),
    221223                        buildMoveOptional( else_ )
Note: See TracChangeset for help on using the changeset viewer.