Changeset 24d6572 for src/ResolvExpr/CurrentObject.cc
- Timestamp:
- Jun 12, 2023, 2:45:32 PM (2 years ago)
- Branches:
- ast-experimental, master
- Children:
- 62d62db
- Parents:
- 34b4268 (diff), 251ce80 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CurrentObject.cc
r34b4268 r24d6572 9 9 // Author : Rob Schluntz 10 10 // Created On : Tue Jun 13 15:28:32 2017 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Jul 1 09:16:01 202213 // Update Count : 1 511 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Apr 10 9:40:00 2023 13 // Update Count : 18 14 14 // 15 15 … … 26 26 #include "AST/Init.hpp" // for Designation 27 27 #include "AST/Node.hpp" // for readonly 28 #include "AST/Print.hpp" 28 #include "AST/Print.hpp" // for readonly 29 29 #include "AST/Type.hpp" 30 #include "Common/Eval.h" // for eval 30 31 #include "Common/Indenter.h" // for Indenter, operator<< 31 32 #include "Common/SemanticError.h" // for SemanticError … … 592 593 593 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 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 594 634 /// create a new MemberIterator that traverses a type correctly 595 635 MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ); … … 631 671 }; 632 672 633 /// Iterates array types 634 class ArrayIterator final : public MemberIterator { 673 /// Iterates over an indexed type: 674 class IndexIterator : public MemberIterator { 675 protected: 635 676 CodeLocation location; 636 const ArrayType * array = nullptr;637 const Type * base = nullptr;638 677 size_t index = 0; 639 678 size_t size = 0; 640 std::unique_ptr< MemberIterator > memberIter; 641 642 void setSize( const Expr * expr ) { 643 auto res = eval( expr ); 644 if ( ! res.second ) { 645 SemanticError( location, toString( "Array designator must be a constant expression: ", expr ) ); 646 } 647 size = res.first; 648 } 649 650 public: 651 ArrayIterator( const CodeLocation & loc, const ArrayType * at ) : location( loc ), array( at ), base( at->base ) { 652 PRINT( std::cerr << "Creating array iterator: " << at << std::endl; ) 653 memberIter.reset( createMemberIterator( loc, base ) ); 654 if ( at->isVarLen ) { 655 SemanticError( location, at, "VLA initialization does not support @=: " ); 656 } 657 setSize( at->dimension ); 658 } 679 std::unique_ptr<MemberIterator> memberIter; 680 public: 681 IndexIterator( const CodeLocation & loc, size_t size ) : 682 location( loc ), size( size ) 683 {} 659 684 660 685 void setPosition( const Expr * expr ) { … … 665 690 auto arg = eval( expr ); 666 691 index = arg.first; 667 return;668 692 669 693 // if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) { … … 683 707 684 708 void setPosition( 685 std::deque< ptr< Expr >>::const_iterator begin,686 std::deque< ptr< Expr >>::const_iterator end709 std::deque<ast::ptr<ast::Expr>>::const_iterator begin, 710 std::deque<ast::ptr<ast::Expr>>::const_iterator end 687 711 ) override { 688 712 if ( begin == end ) return; … … 695 719 696 720 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 } 697 746 698 747 ArrayIterator & bigStep() override { … … 833 882 834 883 const Type * getNext() final { 835 return ( memberIter && *memberIter ) ? memberIter->getType() : nullptr; 884 bool hasMember = memberIter && *memberIter; 885 return hasMember ? memberIter->getType() : nullptr; 836 886 } 837 887 … … 897 947 }; 898 948 899 class TupleIterator final : public AggregateIterator { 900 public: 901 TupleIterator( const CodeLocation & loc, const TupleType * inst ) 902 : AggregateIterator( 903 loc, "TupleIterator", toString("Tuple", inst->size()), inst, inst->members 904 ) {} 905 906 operator bool() const override { 907 return curMember != members.end() || (memberIter && *memberIter); 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() ) ); 908 963 } 909 964 910 965 TupleIterator & bigStep() override { 911 PRINT( std::cerr << "bigStep in " << kind << std::endl; ) 912 atbegin = false; 913 memberIter = nullptr; 914 curType = nullptr; 915 while ( curMember != members.end() ) { 916 ++curMember; 917 if ( init() ) return *this; 918 } 966 ++index; 967 memberIter.reset( index < size ? 968 createMemberIterator( location, typeAtIndex() ) : nullptr ); 919 969 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 {}; 920 1004 } 921 1005 };
Note:
See TracChangeset
for help on using the changeset viewer.