Ignore:
Timestamp:
Jun 12, 2023, 2:45:32 PM (2 years ago)
Author:
Fangren Yu <f37yu@…>
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.
Message:

Merge branch 'master' into ast-experimental

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CurrentObject.cc

    r34b4268 r24d6572  
    99// Author           : Rob Schluntz
    1010// Created On       : Tue Jun 13 15:28:32 2017
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  1 09:16:01 2022
    13 // Update Count     : 15
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Apr 10  9:40:00 2023
     13// Update Count     : 18
    1414//
    1515
     
    2626#include "AST/Init.hpp"                // for Designation
    2727#include "AST/Node.hpp"                // for readonly
    28 #include "AST/Print.hpp"                // for readonly
     28#include "AST/Print.hpp"               // for readonly
    2929#include "AST/Type.hpp"
     30#include "Common/Eval.h"               // for eval
    3031#include "Common/Indenter.h"           // for Indenter, operator<<
    3132#include "Common/SemanticError.h"      // for SemanticError
     
    592593
    593594namespace 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
    594634        /// create a new MemberIterator that traverses a type correctly
    595635        MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type );
     
    631671        };
    632672
    633         /// Iterates array types
    634         class ArrayIterator final : public MemberIterator {
     673        /// Iterates over an indexed type:
     674        class IndexIterator : public MemberIterator {
     675        protected:
    635676                CodeLocation location;
    636                 const ArrayType * array = nullptr;
    637                 const Type * base = nullptr;
    638677                size_t index = 0;
    639678                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                {}
    659684
    660685                void setPosition( const Expr * expr ) {
     
    665690                        auto arg = eval( expr );
    666691                        index = arg.first;
    667                         return;
    668692
    669693                        // if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) {
     
    683707
    684708                void setPosition(
    685                         std::deque< ptr< Expr > >::const_iterator begin,
    686                         std::deque< ptr< Expr > >::const_iterator end
     709                        std::deque<ast::ptr<ast::Expr>>::const_iterator begin,
     710                        std::deque<ast::ptr<ast::Expr>>::const_iterator end
    687711                ) override {
    688712                        if ( begin == end ) return;
     
    695719
    696720                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                }
    697746
    698747                ArrayIterator & bigStep() override {
     
    833882
    834883                const Type * getNext() final {
    835                         return ( memberIter && *memberIter ) ? memberIter->getType() : nullptr;
     884                        bool hasMember = memberIter && *memberIter;
     885                        return hasMember ? memberIter->getType() : nullptr;
    836886                }
    837887
     
    897947        };
    898948
    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() ) );
    908963                }
    909964
    910965                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 );
    919969                        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 {};
    9201004                }
    9211005        };
Note: See TracChangeset for help on using the changeset viewer.