Changes in src/ResolvExpr/CurrentObject.cc [699a97d:8f06277]
- File:
-
- 1 edited
-
src/ResolvExpr/CurrentObject.cc (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CurrentObject.cc
r699a97d r8f06277 9 9 // Author : Rob Schluntz 10 10 // Created On : Tue Jun 13 15:28:32 2017 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Apr 10 9:40:00 202313 // Update Count : 1 811 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 1 09:16:01 2022 13 // Update Count : 15 14 14 // 15 15 … … 593 593 594 594 namespace 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 the611 /// 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 init630 /// alternative, but adding designators in operator* creates duplicates.631 virtual std::deque< InitAlternative > first() const = 0;632 };633 634 595 /// create a new MemberIterator that traverses a type correctly 635 596 MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ); … … 671 632 }; 672 633 673 /// Iterates over an indexed type: 674 class IndexIterator : public MemberIterator { 675 protected: 634 /// Iterates array types 635 class ArrayIterator final : public MemberIterator { 676 636 CodeLocation location; 637 const ArrayType * array = nullptr; 638 const Type * base = nullptr; 677 639 size_t index = 0; 678 640 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 } 684 660 685 661 void setPosition( const Expr * expr ) { … … 690 666 auto arg = eval( expr ); 691 667 index = arg.first; 668 return; 692 669 693 670 // if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) { … … 707 684 708 685 void setPosition( 709 std::deque< ast::ptr<ast::Expr>>::const_iterator begin,710 std::deque< ast::ptr<ast::Expr>>::const_iterator end686 std::deque< ptr< Expr > >::const_iterator begin, 687 std::deque< ptr< Expr > >::const_iterator end 711 688 ) override { 712 689 if ( begin == end ) return; … … 719 696 720 697 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 }746 698 747 699 ArrayIterator & bigStep() override { … … 882 834 883 835 const Type * getNext() final { 884 bool hasMember = memberIter && *memberIter; 885 return hasMember ? memberIter->getType() : nullptr; 836 return ( memberIter && *memberIter ) ? memberIter->getType() : nullptr; 886 837 } 887 838 … … 947 898 }; 948 899 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); 963 909 } 964 910 965 911 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 } 969 920 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 {};1004 921 } 1005 922 };
Note:
See TracChangeset
for help on using the changeset viewer.