Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Pass.hpp

    reb211bf ree918356  
    239239private:
    240240
    241         __pass::result1<ast::Stmt> call_accept( const ast::Stmt * );
    242         __pass::result1<ast::Expr> call_accept( const ast::Expr * );
    243 
    244         /// This has a `type` member that is the return type for the
    245         /// generic call_accept if the generic call_accept is defined.
     241        // Regular nodes
    246242        template< typename node_t >
    247         using generic_call_accept_result =
    248                 std::enable_if<
     243        struct result1 {
     244                bool differs;
     245                const node_t * value;
     246
     247                template< typename object_t, typename super_t, typename field_t >
     248                void apply(object_t *, field_t super_t::* field);
     249        };
     250
     251        result1<ast::Stmt> call_accept( const ast::Stmt * );
     252        result1<ast::Expr> call_accept( const ast::Expr * );
     253
     254        template< typename node_t >
     255        auto call_accept( const node_t * node )
     256                -> typename std::enable_if<
    249257                                !std::is_base_of<ast::Expr, node_t>::value &&
    250258                                !std::is_base_of<ast::Stmt, node_t>::value
    251                         , __pass::result1<
    252                                 typename std::remove_pointer< typename std::result_of<
    253                                         decltype(&node_t::accept)(node_t*, type&) >::type >::type
     259                        , result1<
     260                                typename std::remove_pointer< decltype( node->accept(*this) ) >::type
    254261                        >
    255                 >;
    256 
    257         template< typename node_t >
    258         auto call_accept( const node_t * node )
    259                 -> typename generic_call_accept_result<node_t>::type;
     262                >::type;
    260263
    261264        // requests WithStmtsToAdd directly add to this statement, as if it is a compound.
    262         __pass::result1<ast::Stmt> call_accept_as_compound(const ast::Stmt *);
    263 
     265        result1<ast::Stmt> call_accept_as_compound(const ast::Stmt *);
     266
     267        // Container of statements
    264268        template< template <class...> class container_t >
    265         __pass::resultNstmt<container_t> call_accept( const container_t< ptr<Stmt> > & );
    266 
     269        struct resultNstmt {
     270                struct delta {
     271                        ptr<Stmt> nval;
     272                        ssize_t old_idx;
     273                        bool is_old;
     274
     275                        delta(const Stmt * s, ssize_t i, bool old) : nval{s}, old_idx{i}, is_old{old} {}
     276                };
     277
     278                bool differs;
     279                container_t< delta > values;
     280
     281                resultNstmt() : differs(false), values{} {}
     282                resultNstmt(bool diff, container_t< delta > && vals) : differs(diff), values(vals) {}
     283
     284                template< typename object_t, typename super_t, typename field_t >
     285                void apply(object_t *, field_t super_t::* field);
     286
     287                template< template <class...> class incontainer_t >
     288                void take_all( incontainer_t<ast::ptr<ast::Stmt>> * stmts ) {
     289                        if(!stmts || stmts->empty()) return;
     290
     291                        std::transform(stmts->begin(), stmts->end(), std::back_inserter( values ), [](ast::ptr<ast::Stmt>& decl) -> delta {
     292                                        return delta( decl.release(), -1, false );
     293                                });
     294                        stmts->clear();
     295                        differs = true;
     296                }
     297
     298                template< template <class...> class incontainer_t >
     299                void take_all( incontainer_t<ast::ptr<ast::Decl>> * decls ) {
     300                        if(!decls || decls->empty()) return;
     301
     302                        std::transform(decls->begin(), decls->end(), std::back_inserter( values ), [](ast::ptr<ast::Decl>& decl) -> auto {
     303                                        auto loc = decl->location;
     304                                        auto stmt = new DeclStmt( loc, decl.release() );
     305                                        return delta( stmt, -1, false );
     306                                });
     307                        decls->clear();
     308                        differs = true;
     309                }
     310        };
     311
     312        template< template <class...> class container_t >
     313        resultNstmt<container_t> call_accept( const container_t< ptr<Stmt> > & );
     314
     315        // Container of something
    267316        template< template <class...> class container_t, typename node_t >
    268         __pass::resultN< container_t, node_t > call_accept( const container_t< ptr<node_t> > & container );
     317        struct resultN {
     318                bool differs;
     319                container_t<ptr<node_t>> values;
     320
     321                template< typename object_t, typename super_t, typename field_t >
     322                void apply(object_t *, field_t super_t::* field);
     323        };
     324
     325        template< template <class...> class container_t, typename node_t >
     326        resultN< container_t, node_t > call_accept( const container_t< ptr<node_t> > & container );
    269327
    270328public:
Note: See TracChangeset for help on using the changeset viewer.