Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CurrentObject.cc

    r699a97d r8f06277  
    99// Author           : Rob Schluntz
    1010// Created On       : Tue Jun 13 15:28:32 2017
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Apr 10  9:40:00 2023
    13 // Update Count     : 18
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Jul  1 09:16:01 2022
     13// Update Count     : 15
    1414//
    1515
     
    593593
    594594namespace ast {
    595         /// Iterates members of a type by initializer.
    596         class MemberIterator {
    597         public:
    598                 virtual ~MemberIterator() {}
    599 
    600                 /// Internal set position based on iterator ranges.
    601                 virtual void setPosition(
    602                         std::deque< ptr< Expr > >::const_iterator it,
    603                         std::deque< ptr< Expr > >::const_iterator end ) = 0;
    604 
    605                 /// Walks the current object using the given designators as a guide.
    606                 void setPosition( const std::deque< ptr< Expr > > & designators ) {
    607                         setPosition( designators.begin(), designators.end() );
    608                 }
    609 
    610                 /// Retrieve the list of possible (Type,Designation) pairs for the
    611                 /// current position in the current object.
    612                 virtual std::deque< InitAlternative > operator* () const = 0;
    613 
    614                 /// True if the iterator is not currently at the end.
    615                 virtual operator bool() const = 0;
    616 
    617                 /// Moves the iterator by one member in the current object.
    618                 virtual MemberIterator & bigStep() = 0;
    619 
    620                 /// Moves the iterator by one member in the current subobject.
    621                 virtual MemberIterator & smallStep() = 0;
    622 
    623                 /// The type of the current object.
    624                 virtual const Type * getType() = 0;
    625 
    626                 /// The type of the current subobject.
    627                 virtual const Type * getNext() = 0;
    628 
    629                 /// Helper for operator*; aggregates must add designator to each init
    630                 /// alternative, but adding designators in operator* creates duplicates.
    631                 virtual std::deque< InitAlternative > first() const = 0;
    632         };
    633 
    634595        /// create a new MemberIterator that traverses a type correctly
    635596        MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type );
     
    671632        };
    672633
    673         /// Iterates over an indexed type:
    674         class IndexIterator : public MemberIterator {
    675         protected:
     634        /// Iterates array types
     635        class ArrayIterator final : public MemberIterator {
    676636                CodeLocation location;
     637                const ArrayType * array = nullptr;
     638                const Type * base = nullptr;
    677639                size_t index = 0;
    678640                size_t size = 0;
    679                 std::unique_ptr<MemberIterator> memberIter;
    680         public:
    681                 IndexIterator( const CodeLocation & loc, size_t size ) :
    682                         location( loc ), size( size )
    683                 {}
     641                std::unique_ptr< MemberIterator > memberIter;
     642
     643                void setSize( const Expr * expr ) {
     644                        auto res = eval( expr );
     645                        if ( ! res.second ) {
     646                                SemanticError( location, toString( "Array designator must be a constant expression: ", expr ) );
     647                        }
     648                        size = res.first;
     649                }
     650
     651        public:
     652                ArrayIterator( const CodeLocation & loc, const ArrayType * at ) : location( loc ), array( at ), base( at->base ) {
     653                        PRINT( std::cerr << "Creating array iterator: " << at << std::endl; )
     654                        memberIter.reset( createMemberIterator( loc, base ) );
     655                        if ( at->isVarLen ) {
     656                                SemanticError( location, at, "VLA initialization does not support @=: " );
     657                        }
     658                        setSize( at->dimension );
     659                }
    684660
    685661                void setPosition( const Expr * expr ) {
     
    690666                        auto arg = eval( expr );
    691667                        index = arg.first;
     668                        return;
    692669
    693670                        // if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) {
     
    707684
    708685                void setPosition(
    709                         std::deque<ast::ptr<ast::Expr>>::const_iterator begin,
    710                         std::deque<ast::ptr<ast::Expr>>::const_iterator end
     686                        std::deque< ptr< Expr > >::const_iterator begin,
     687                        std::deque< ptr< Expr > >::const_iterator end
    711688                ) override {
    712689                        if ( begin == end ) return;
     
    719696
    720697                operator bool() const override { return index < size; }
    721         };
    722 
    723         /// Iterates over the members of array types:
    724         class ArrayIterator final : public IndexIterator {
    725                 const ArrayType * array = nullptr;
    726                 const Type * base = nullptr;
    727 
    728                 size_t getSize( const Expr * expr ) {
    729                         auto res = eval( expr );
    730                         if ( !res.second ) {
    731                                 SemanticError( location, toString( "Array designator must be a constant expression: ", expr ) );
    732                         }
    733                         return res.first;
    734                 }
    735 
    736         public:
    737                 ArrayIterator( const CodeLocation & loc, const ArrayType * at ) :
    738                                 IndexIterator( loc, getSize( at->dimension) ),
    739                                 array( at ), base( at->base ) {
    740                         PRINT( std::cerr << "Creating array iterator: " << at << std::endl; )
    741                         memberIter.reset( createMemberIterator( loc, base ) );
    742                         if ( at->isVarLen ) {
    743                                 SemanticError( location, at, "VLA initialization does not support @=: " );
    744                         }
    745                 }
    746698
    747699                ArrayIterator & bigStep() override {
     
    882834
    883835                const Type * getNext() final {
    884                         bool hasMember = memberIter && *memberIter;
    885                         return hasMember ? memberIter->getType() : nullptr;
     836                        return ( memberIter && *memberIter ) ? memberIter->getType() : nullptr;
    886837                }
    887838
     
    947898        };
    948899
    949         /// Iterates across the positions in a tuple:
    950         class TupleIterator final : public IndexIterator {
    951                 ast::TupleType const * const tuple;
    952 
    953                 const ast::Type * typeAtIndex() const {
    954                         assert( index < size );
    955                         return tuple->types[ index ].get();
    956                 }
    957 
    958         public:
    959                 TupleIterator( const CodeLocation & loc, const TupleType * type )
    960                 : IndexIterator( loc, type->size() ), tuple( type ) {
    961                         PRINT( std::cerr << "Creating tuple iterator: " << type << std::endl; )
    962                         memberIter.reset( createMemberIterator( loc, typeAtIndex() ) );
     900        class TupleIterator final : public AggregateIterator {
     901        public:
     902                TupleIterator( const CodeLocation & loc, const TupleType * inst )
     903                : AggregateIterator(
     904                        loc, "TupleIterator", toString("Tuple", inst->size()), inst, inst->members
     905                ) {}
     906
     907                operator bool() const override {
     908                        return curMember != members.end() || (memberIter && *memberIter);
    963909                }
    964910
    965911                TupleIterator & bigStep() override {
    966                         ++index;
    967                         memberIter.reset( index < size ?
    968                                 createMemberIterator( location, typeAtIndex() ) : nullptr );
     912                        PRINT( std::cerr << "bigStep in " << kind << std::endl; )
     913                        atbegin = false;
     914                        memberIter = nullptr;
     915                        curType = nullptr;
     916                        while ( curMember != members.end() ) {
     917                                ++curMember;
     918                                if ( init() ) return *this;
     919                        }
    969920                        return *this;
    970                 }
    971 
    972                 TupleIterator & smallStep() override {
    973                         if ( memberIter ) {
    974                                 PRINT( std::cerr << "has member iter: " << *memberIter << std::endl; )
    975                                 memberIter->smallStep();
    976                                 if ( !memberIter ) {
    977                                         PRINT( std::cerr << "has valid member iter" << std::endl; )
    978                                         return *this;
    979                                 }
    980                         }
    981                         return bigStep();
    982                 }
    983 
    984                 const ast::Type * getType() override {
    985                         return tuple;
    986                 }
    987 
    988                 const ast::Type * getNext() override {
    989                         bool hasMember = memberIter && *memberIter;
    990                         return hasMember ? memberIter->getType() : nullptr;
    991                 }
    992 
    993                 std::deque< InitAlternative > first() const override {
    994                         PRINT( std::cerr << "first in TupleIterator (" << index << "/" << size << ")" << std::endl; )
    995                         if ( memberIter && *memberIter ) {
    996                                 std::deque< InitAlternative > ret = memberIter->first();
    997                                 for ( InitAlternative & alt : ret ) {
    998                                         alt.designation.get_and_mutate()->designators.emplace_front(
    999                                                 ConstantExpr::from_ulong( location, index ) );
    1000                                 }
    1001                                 return ret;
    1002                         }
    1003                         return {};
    1004921                }
    1005922        };
Note: See TracChangeset for help on using the changeset viewer.