Ignore:
Timestamp:
Jun 7, 2019, 4:14:48 PM (5 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
05d55ff
Parents:
5684736
git-author:
Aaron Moss <a3moss@…> (06/07/19 16:14:40)
git-committer:
Aaron Moss <a3moss@…> (06/07/19 16:14:48)
Message:

More resolver porting; mostly CurrentObject?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CurrentObject.cc

    r5684736 r60aaa51d  
    1616#include <stddef.h>                    // for size_t
    1717#include <cassert>                     // for assertf, assert, safe_dynamic_...
     18#include <deque>
    1819#include <iostream>                    // for ostream, operator<<, basic_ost...
    1920#include <stack>                       // for stack
     
    2122
    2223#include "AST/Expr.hpp"                // for InitAlternative
     24#include "AST/GenericSubstitution.hpp" // for genericSubstitution
    2325#include "AST/Init.hpp"                // for Designation
    2426#include "AST/Node.hpp"                // for readonly
     27#include "AST/Type.hpp"
    2528#include "Common/Indenter.h"           // for Indenter, operator<<
    2629#include "Common/SemanticError.h"      // for SemanticError
     
    583586
    584587namespace ast {
    585 
    586         /// Iterates members of a type by initializer
    587         class MemberIterator {
    588         public:
    589                 virtual ~MemberIterator() {}
    590 
    591                 /// retrieve the list of possible (Type,Designation) pairs for the current position in the
    592                 /// current object
    593                 virtual std::vector< InitAlternative > operator* () const = 0;
    594        
    595         protected:
    596                 /// helper for operator*; aggregates must add designator to each init alternative, but
    597                 /// adding designators in operator* creates duplicates
    598                 virtual std::vector< InitAlternative > first() const = 0;
    599         };
     588        /// create a new MemberIterator that traverses a type correctly
     589        MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type );
    600590
    601591        /// Iterates "other" types (e.g. basic, pointer) which do not change at list initializer entry
     
    606596                SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {}
    607597
    608                 std::vector< InitAlternative > operator* () const override { return first(); }
    609 
    610         protected:
    611                 std::vector< InitAlternative > first() const override {
     598                void setPosition(
     599                        std::deque< ptr< Expr > >::const_iterator begin,
     600                        std::deque< ptr< Expr > >::const_iterator end
     601                ) override {
     602                        if ( begin != end ) {
     603                                SemanticError( location, "Un-designated initializer given non-empty designator" );
     604                        }
     605                }
     606
     607                std::deque< InitAlternative > operator* () const override { return first(); }
     608
     609                operator bool() const override { return type; }
     610
     611                SimpleIterator & bigStep() override { return smallStep(); }
     612                SimpleIterator & smallStep() override {
     613                        type = nullptr;  // empty on increment because no members
     614                        return *this;
     615                }
     616
     617                const Type * getType() override { return type; }
     618
     619                const Type * getNext() override { return type; }
     620
     621                std::deque< InitAlternative > first() const override {
    612622                        if ( type ) return { InitAlternative{ type, new Designation{ location } } };
    613623                        return {};
     
    615625        };
    616626
     627        /// Iterates array types
     628        class ArrayIterator final : public MemberIterator {
     629                CodeLocation location;
     630                readonly< ArrayType > array = nullptr;
     631                readonly< Type > base = nullptr;
     632                size_t index = 0;
     633                size_t size = 0;
     634                std::unique_ptr< MemberIterator > memberIter;
     635
     636                void setSize( const Expr * expr ) {
     637                        auto res = eval(expr);
     638                        if ( ! res.second ) {
     639                                SemanticError( location,
     640                                        toString("Array designator must be a constant expression: ", expr ) );
     641                        }
     642                        size = res.first;
     643                }
     644
     645        public:
     646                ArrayIterator( const CodeLocation & loc, const ArrayType * at )
     647                : location( loc ), array( at ), base( at->base ) {
     648                        PRINT( std::cerr << "Creating array iterator: " << at << std::endl; )
     649                        memberIter.reset( createMemberIterator( loc, base ) );
     650                        if ( at->isVarLen ) {
     651                                SemanticError( location, at, "VLA initialization does not support @=: " );
     652                        }
     653                        setSize( at->dimension );
     654                }
     655
     656                void setPosition( const Expr * expr ) {
     657                        // need to permit integer-constant-expressions, including: integer constants,
     658                        // enumeration constants, character constants, sizeof expressions, alignof expressions,
     659                        // cast expressions
     660                        if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) {
     661                                try {
     662                                        index = constExpr->intValue();
     663                                } catch ( SemanticErrorException & ) {
     664                                        SemanticError( expr,
     665                                                "Constant expression of non-integral type in array designator: " );
     666                                }
     667                        } else if ( auto castExpr = dynamic_cast< const CastExpr * >( expr ) ) {
     668                                setPosition( castExpr->arg );
     669                        } else if (
     670                                dynamic_cast< const SizeofExpr * >( expr )
     671                                || dynamic_cast< const AlignofExpr * >( expr )
     672                        ) {
     673                                index = 0;
     674                        } else {
     675                                assertf( false,
     676                                        "bad designator given to ArrayIterator: %s", toString( expr ).c_str() );
     677                        }
     678                }
     679
     680                void setPosition(
     681                        std::deque< ptr< Expr > >::const_iterator begin,
     682                        std::deque< ptr< Expr > >::const_iterator end
     683                ) override {
     684                        if ( begin == end ) return;
     685
     686                        setPosition( *begin );
     687                        memberIter->setPosition( ++begin, end );
     688                }
     689
     690                std::deque< InitAlternative > operator* () const override { return first(); }
     691
     692                operator bool() const override { return index < size; }
     693
     694                ArrayIterator & bigStep() override {
     695                        PRINT( std::cerr << "bigStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; )
     696                        ++index;
     697                        memberIter.reset( index < size ? createMemberIterator( location, base ) : nullptr );
     698                        return *this;
     699                }
     700
     701                ArrayIterator & smallStep() override {
     702                        PRINT( std::cerr << "smallStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; )
     703                        if ( memberIter ) {
     704                                PRINT( std::cerr << "has member iter: " << *memberIter << std::endl; )
     705                                memberIter->smallStep();
     706                                if ( *memberIter ) {
     707                                        PRINT( std::cerr << "has valid member iter" << std::endl; )
     708                                        return *this;
     709                                }
     710                        }
     711                        return bigStep();
     712                }
     713
     714                const Type * getType() override { return array; }
     715
     716                const Type * getNext() override { return base; }
     717
     718                std::deque< InitAlternative > first() const override {
     719                        PRINT( std::cerr << "first in ArrayIterator (" << index << "/" << size << ")" << std::endl; )
     720                        if ( memberIter && *memberIter ) {
     721                                std::deque< InitAlternative > ret = memberIter->first();
     722                                for ( InitAlternative & alt : ret ) {
     723                                        alt.designation.get_and_mutate()->designators.emplace_front(
     724                                                ConstantExpr::from_ulong( location, index ) );
     725                                }
     726                                return ret;
     727                        }
     728                        return {};
     729                }
     730        };
     731
     732        class AggregateIterator : public MemberIterator {
     733        protected:
     734                using MemberList = std::vector< ptr< Decl > >;
     735
     736                CodeLocation location;
     737                std::string kind;  // for debug
     738                std::string name;
     739                const Type * inst;
     740                const MemberList & members;
     741                MemberList::const_iterator curMember;
     742                bool atbegin = true;  // false at first {small,big}Step
     743                const Type * curType = nullptr;
     744                std::unique_ptr< MemberIterator > memberIter = nullptr;
     745                TypeSubstitution sub;
     746
     747                bool init() {
     748                        PRINT( std::cerr << "--init()--" << members.size() << std::endl; )
     749                        if ( curMember != members.end() ) {
     750                                if ( auto field = curMember->as< ObjectDecl >() ) {
     751                                        PRINT( std::cerr << "incremented to field: " << field << std::endl; )
     752                                        curType = field->get_type();
     753                                        memberIter.reset( createMemberIterator( location, curType ) );
     754                                        return true;
     755                                }
     756                        }
     757                        return false;
     758                }
     759
     760                AggregateIterator(
     761                        const CodeLocation & loc, const std::string k, const std::string & n, const Type * i,
     762                        const MemberList & ms )
     763                : location( loc ), kind( k ), name( n ), inst( i ), members( ms ), curMember( ms.begin() ),
     764                  sub( genericSubstitution( i ) ) {
     765                        PRINT( std::cerr << "Creating " << kind << "(" << name << ")"; )
     766                        init();
     767                }
     768
     769        public:
     770                void setPosition(
     771                        std::deque< ptr< Expr > >::const_iterator begin,
     772                        std::deque< ptr< Expr > >::const_iterator end
     773                ) final {
     774                        if ( begin == end ) return;
     775
     776                        if ( auto varExpr = begin->as< VariableExpr >() ) {
     777                                for ( curMember = members.begin(); curMember != members.end(); ++curMember ) {
     778                                        if ( *curMember != varExpr->var ) continue;
     779
     780                                        ++begin;
     781
     782                                        memberIter.reset( createMemberIterator( location, varExpr->result ) );
     783                                        curType = varExpr->result;
     784                                        atbegin = curMember == members.begin() && begin == end;
     785                                        memberIter->setPosition( begin, end );
     786                                        return;
     787                                }
     788                                assertf( false,
     789                                        "could not find member in %s: %s", kind.c_str(), toString( varExpr ).c_str() );
     790                        } else {
     791                                assertf( false,
     792                                        "bad designator given to %s: %s", kind.c_str(), toString( *begin ).c_str() );
     793                        }
     794                }
     795
     796                std::deque< InitAlternative > operator* () const final {
     797                        if ( memberIter && *memberIter ) {
     798                                std::deque< InitAlternative > ret = memberIter->first();
     799                                PRINT( std::cerr << "sub: " << sub << std::endl; )
     800                                for ( InitAlternative & alt : ret ) {
     801                                        PRINT( std::cerr << "iterating and adding designators" << std::endl; )
     802                                        alt.designation.get_and_mutate()->designators.emplace_front(
     803                                                new VariableExpr{ location, curMember->strict_as< ObjectDecl >() } );
     804                                        // need to substitute for generic types so that casts are to concrete types
     805                                        PRINT( std::cerr << "  type is: " << alt.type; )
     806                                        sub.apply( alt.type ); // also apply to designation??
     807                                        PRINT( std::cerr << " ==> " << alt.type << std::endl; )
     808                                }
     809                                return ret;
     810                        }
     811                        return {};
     812                }
     813
     814                AggregateIterator & smallStep() final {
     815                        PRINT( std::cerr << "smallStep in " << kind << std::endl; )
     816                        atbegin = false;
     817                        if ( memberIter ) {
     818                                PRINT( std::cerr << "has member iter, incrementing..." << std::endl; )
     819                                memberIter->smallStep();
     820                                if ( *memberIter ) {
     821                                        PRINT( std::cerr << "success!" << std::endl; )
     822                                        return *this;
     823                                }
     824                        }
     825                        return bigStep();
     826                }
     827
     828                AggregateIterator & bigStep() override = 0;
     829
     830                const Type * getType() final { return inst; }
     831
     832                const Type * getNext() final {
     833                        return ( memberIter && *memberIter ) ? memberIter->getType() : nullptr;
     834                }
     835
     836                std::deque< InitAlternative > first() const final {
     837                        std::deque< InitAlternative > ret;
     838                        PRINT( std::cerr << "first " << kind << std::endl; )
     839                        if ( memberIter && *memberIter ) {
     840                                PRINT( std::cerr << "adding children" << std::endl; )
     841                                ret = memberIter->first();
     842                                for ( InitAlternative & alt : ret ) {
     843                                        PRINT( std::cerr << "iterating and adding designators" << std::endl; )
     844                                        alt.designation.get_and_mutate()->designators.emplace_front(
     845                                                new VariableExpr{ location, curMember->strict_as< ObjectDecl >() } );
     846                                }
     847                        }
     848                        if ( atbegin ) {
     849                                // only add self if at the very beginning of the structure
     850                                PRINT( std::cerr << "adding self" << std::endl; )
     851                                ret.emplace_front( inst, new Designation{ location } );
     852                        }
     853                        return ret;
     854                }
     855        };
     856
     857        class StructIterator final : public AggregateIterator {
     858        public:
     859                StructIterator( const CodeLocation & loc, const StructInstType * inst )
     860                : AggregateIterator( loc, "StructIterator", inst->name, inst, inst->base->members ) {}
     861
     862                operator bool() const override {
     863                        return curMember != members.end() || (memberIter && *memberIter);
     864                }
     865
     866                StructIterator & bigStep() override {
     867                        PRINT( std::cerr << "bigStep in " << kind << std::endl; )
     868                        atbegin = false;
     869                        memberIter = nullptr;
     870                        curType = nullptr;
     871                        while ( curMember != members.end() ) {
     872                                ++curMember;
     873                                if ( init() ) return *this;
     874                        }
     875                        return *this;
     876                }
     877        };
     878
     879        class UnionIterator final : public AggregateIterator {
     880        public:
     881                UnionIterator( const CodeLocation & loc, const UnionInstType * inst )
     882                : AggregateIterator( loc, "UnionIterator", inst->name, inst, inst->base->members ) {}
     883
     884                operator bool() const override { return memberIter && *memberIter; }
     885
     886                UnionIterator & bigStep() override {
     887                        // unions only initialize one member
     888                        PRINT( std::cerr << "bigStep in " << kind << std::endl; )
     889                        atbegin = false;
     890                        memberIter = nullptr;
     891                        curType = nullptr;
     892                        curMember = members.end();
     893                        return *this;
     894                }
     895        };
     896
     897        class TupleIterator final : public AggregateIterator {
     898        public:
     899                TupleIterator( const CodeLocation & loc, const TupleType * inst )
     900                : AggregateIterator(
     901                        loc, "TupleIterator", toString("Tuple", inst->size()), inst, inst->members
     902                ) {}
     903
     904                operator bool() const override {
     905                        return curMember != members.end() || (memberIter && *memberIter);
     906                }
     907
     908                TupleIterator & bigStep() override {
     909                        PRINT( std::cerr << "bigStep in " << kind << std::endl; )
     910                        atbegin = false;
     911                        memberIter = nullptr;
     912                        curType = nullptr;
     913                        while ( curMember != members.end() ) {
     914                                ++curMember;
     915                                if ( init() ) return *this;
     916                        }
     917                        return *this;
     918                }
     919        };
     920
     921        MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ) {
     922                if ( auto aggr = dynamic_cast< const ReferenceToType * >( type ) ) {
     923                        if ( auto sit = dynamic_cast< const StructInstType * >( aggr ) ) {
     924                                return new StructIterator{ loc, sit };
     925                        } else if ( auto uit = dynamic_cast< const UnionInstType * >( aggr ) ) {
     926                                return new UnionIterator{ loc, uit };
     927                        } else {
     928                                assertf(
     929                                        dynamic_cast< const EnumInstType * >( aggr )
     930                                                || dynamic_cast< const TypeInstType * >( aggr ),
     931                                        "Encountered unhandled ReferenceToType in createMemberIterator: %s",
     932                                                toString( type ).c_str() );
     933                                return new SimpleIterator{ loc, type };
     934                        }
     935                } else if ( auto at = dynamic_cast< const ArrayType * >( type ) ) {
     936                        return new ArrayIterator{ loc, at };
     937                } else if ( auto tt = dynamic_cast< const TupleType * >( type ) ) {
     938                        return new TupleIterator{ loc, tt };
     939                } else {
     940                        return new SimpleIterator{ loc, type };
     941                }
     942        }
     943
    617944        CurrentObject::CurrentObject( const CodeLocation & loc, const Type * type ) : objStack() {
    618945                objStack.emplace_back( new SimpleIterator{ loc, type } );
    619946        }
    620947
    621         std::vector< InitAlternative > CurrentObject::getOptions() {
     948        void CurrentObject::setNext( const ast::Designation * designation ) {
     949                PRINT( std::cerr << "____setNext" << designation << std::endl; )
     950                assertf( ! objStack.empty(), "obj stack empty in setNext" );
     951                objStack.back()->setPosition( designation->designators );
     952        }
     953
     954        void CurrentObject::increment() {
     955                PRINT( std::cerr << "____increment" << std::endl; )
     956                if ( objStack.empty() ) return;
     957                PRINT( std::cerr << *objStack.back() << std::endl; )
     958                objStack.back()->smallStep();
     959        }
     960
     961        void CurrentObject::enterListInit( const CodeLocation & loc ) {
     962                PRINT( std::cerr << "____entering list init" << std::endl; )
     963                assertf( ! objStack.empty(), "empty obj stack entering list init" );
     964                const ast::Type * type = objStack.back()->getNext();
     965                assert( type );
     966                objStack.emplace_back( createMemberIterator( loc, type ) );
     967        }
     968
     969        void CurrentObject::exitListInit() {
     970                PRINT( std::cerr << "____exiting list init" << std::endl; )
     971                assertf( ! objStack.empty(), "objstack empty" );
     972                objStack.pop_back();
     973                if ( ! objStack.empty() ) {
     974                        PRINT( std::cerr << *objStack.back() << std::endl; )
     975                        objStack.back()->bigStep();
     976                }
     977        }
     978
     979        std::deque< InitAlternative > CurrentObject::getOptions() {
    622980                PRINT( std::cerr << "____getting current options" << std::endl; )
    623981                assertf( ! objStack.empty(), "objstack empty in getOptions" );
    624982                return **objStack.back();
     983        }
     984
     985        const Type * CurrentObject::getCurrentType() {
     986                PRINT( std::cerr << "____getting current type" << std::endl; )
     987                assertf( ! objStack.empty(), "objstack empty in getCurrentType" );
     988                return objStack.back()->getNext();
    625989        }
    626990}
Note: See TracChangeset for help on using the changeset viewer.