Changeset fca78f1 for src/AST


Ignore:
Timestamp:
Sep 23, 2024, 11:14:56 AM (3 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/AST
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Fwd.hpp

    rb723b63 rfca78f1  
    4949class WhileDoStmt;
    5050class ForStmt;
     51class ForeachStmt;
    5152class SwitchStmt;
    5253class CaseClause;
  • 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;
  • 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
  • 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: ";
  • 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};
  • 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;
Note: See TracChangeset for help on using the changeset viewer.