Changes in / [2b78949:044ae62]


Ignore:
Location:
src
Files:
35 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r2b78949 r044ae62  
    283283                decl->parent = get<AggregateDecl>().accept1( node->parent );
    284284                declPostamble( decl, node );
    285                 return nullptr; // ??
     285                return nullptr;
    286286        }
    287287
     
    320320                        LinkageSpec::Spec( node->linkage.val ),
    321321                        get<Type>().accept1(node->base)
     322                );
     323                // decl->data_constructors = get<StructDecl>().acceptL( node->data_constructors );
     324                // decl->data_union = get<UnionDecl>().accept1( node->data_union );
     325                // decl->tag = get<EnumDecl>().accept1( node->tag );
     326                // decl->tag_union = get<StructDecl>().accept1( node->tag_union );
     327                return aggregatePostamble( decl, node );
     328        }
     329
     330        const ast::Decl * visit( const ast::AdtDecl * node ) override final {
     331                if ( inCache(node) ) return nullptr;
     332                auto decl = new AdtDecl(
     333                        node->name,
     334                        get<Attribute>().acceptL( node->attributes ),
     335                        LinkageSpec::Spec( node->linkage.val ),
     336                        get<StructDecl>().acceptL( node->data_constructors ),
     337                        get<UnionDecl>().accept1( node->data_union ),
     338                        get<EnumDecl>().accept1( node->tag ),
     339                        get<StructDecl>().accept1( node->tag_union )
    322340                );
    323341                return aggregatePostamble( decl, node );
     
    17901808        }
    17911809
     1810        virtual void visit( const AdtDecl * old ) override final {
     1811                if ( inCache( old ) ) return;
     1812                auto decl = new ast::AdtDecl(
     1813                        old->location,
     1814                        old->name,
     1815                        GET_ACCEPT_V(attributes, Attribute),
     1816                        { old->linkage.val }
     1817                );
     1818                cache.emplace( old, decl );
     1819                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
     1820                decl->body = old->body;
     1821                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
     1822                decl->members = GET_ACCEPT_V(members, Decl);
     1823                decl->extension = old->extension;
     1824                decl->uniqueId = old->uniqueId;
     1825                decl->storage = { old->storageClasses.val };
     1826                decl->data_constructors = GET_ACCEPT_V( data_constructors, StructDecl );
     1827                decl->data_union = GET_ACCEPT_1( data_union, UnionDecl );
     1828                decl->tag = GET_ACCEPT_1( tag, EnumDecl );
     1829                decl->tag_union = GET_ACCEPT_1( tag_union, StructDecl );
     1830                this->node = decl;
     1831        }
     1832
    17921833        virtual void visit( const TraitDecl * old ) override final {
    17931834                if ( inCache( old ) ) return;
  • src/AST/Decl.cpp

    r2b78949 r044ae62  
    132132
    133133// These must harmonize with the corresponding AggregateDecl::Aggregate enumerations.
    134 static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName" };
     134static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName", "adt" };
    135135
    136136const char * AggregateDecl::aggrString( AggregateDecl::Aggregate aggr ) {
  • src/AST/Decl.hpp

    r2b78949 r044ae62  
    248248class AggregateDecl : public Decl {
    249249public:
    250         enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate };
     250        enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate, Adt };
    251251        static const char * aggrString( Aggregate aggr );
    252252
     
    286286        bool is_monitor  () const { return kind == Monitor  ; }
    287287        bool is_thread   () const { return kind == Thread   ; }
     288        bool is_adt              () const { return kind == Adt          ; }
    288289
    289290        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
     
    322323        EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false,
    323324                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall,
    324                 Type const * base = nullptr, EnumHiding hide = EnumHiding::Hide,
     325                Type const * base = nullptr, EnumHiding hide = EnumHiding::Visible,
    325326                std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() )
    326327        : AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), hide(hide), enumValues(enumValues) {}
     
    343344};
    344345
     346class AdtDecl final : public AggregateDecl {
     347public:
     348        std::vector<ptr<StructDecl>> data_constructors; // Todo: members?
     349        ptr<UnionDecl> data_union;
     350        ptr<EnumDecl> tag;
     351        ptr<StructDecl> tag_union;
     352
     353        AdtDecl( const CodeLocation& loc, const std::string& name,
     354                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
     355        : AggregateDecl( loc, name, std::move(attrs), linkage ) {}
     356
     357        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
     358
     359        const char * typeString() const override { return aggrString( Adt ); }
     360
     361private:
     362        AdtDecl * clone() const override { return new AdtDecl{ *this }; }
     363        MUTATE_FRIEND
     364};
     365
    345366/// trait declaration `trait Foo( ... ) { ... };`
    346367class TraitDecl final : public AggregateDecl {
     
    351372
    352373        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
    353 
    354374        const char * typeString() const override { return "trait"; }
    355375
  • src/AST/Fwd.hpp

    r2b78949 r044ae62  
    3232class UnionDecl;
    3333class EnumDecl;
     34class AdtDecl;
    3435class TraitDecl;
    3536class NamedTypeDecl;
  • src/AST/Node.cpp

    r2b78949 r044ae62  
    128128template class ast::ptr_base< ast::EnumDecl, ast::Node::ref_type::weak >;
    129129template class ast::ptr_base< ast::EnumDecl, ast::Node::ref_type::strong >;
     130template class ast::ptr_base< ast::AdtDecl, ast::Node::ref_type::weak >;
     131template class ast::ptr_base< ast::AdtDecl, ast::Node::ref_type::strong >;
    130132template class ast::ptr_base< ast::TraitDecl, ast::Node::ref_type::weak >;
    131133template class ast::ptr_base< ast::TraitDecl, ast::Node::ref_type::strong >;
  • src/AST/Pass.hpp

    r2b78949 r044ae62  
    139139        const ast::Decl *             visit( const ast::UnionDecl            * ) override final;
    140140        const ast::Decl *             visit( const ast::EnumDecl             * ) override final;
     141        const ast::Decl *                         visit( const ast::AdtDecl                              * ) override final;
    141142        const ast::Decl *             visit( const ast::TraitDecl            * ) override final;
    142143        const ast::Decl *             visit( const ast::TypeDecl             * ) override final;
  • src/AST/Pass.impl.hpp

    r2b78949 r044ae62  
    620620                        maybe_accept( node, &EnumDecl::members    );
    621621                        maybe_accept( node, &EnumDecl::attributes );
     622
     623                        // maybe_accept( node, &EnumDecl::data_constructors );
     624                        // maybe_accept( node, &EnumDecl::data_union );
     625                        // maybe_accept( node, &EnumDecl::tag );
     626                        // maybe_accept( node, &EnumDecl::tag_union );
    622627                } else {
    623628                        maybe_accept( node, &EnumDecl::base );
     
    625630                        maybe_accept( node, &EnumDecl::members    );
    626631                        maybe_accept( node, &EnumDecl::attributes );
    627                 }
     632
     633                        // maybe_accept( node, &EnumDecl::data_constructors );
     634                        // maybe_accept( node, &EnumDecl::data_union );
     635                        // maybe_accept( node, &EnumDecl::tag );
     636                        // maybe_accept( node, &EnumDecl::tag_union );
     637                }
     638        }
     639
     640        VISIT_END( Decl, node );
     641}
     642
     643template< typename core_t >
     644const ast::Decl * ast::Pass< core_t >::visit( const ast::AdtDecl * node ) {
     645        VISIT_START( node );
     646
     647        __pass::symtab::addAdt( core, 0, node );
     648
     649        if ( __visit_children() ) {
     650                guard_symtab guard { *this };
     651                maybe_accept( node, &AdtDecl::params );
     652                maybe_accept( node, &AdtDecl::members );
     653                maybe_accept( node, &AdtDecl::attributes );
     654
     655                maybe_accept( node, &AdtDecl::data_constructors );
     656                maybe_accept( node, &AdtDecl::data_union );
     657                maybe_accept( node, &AdtDecl::tag );
     658                maybe_accept( node, &AdtDecl::tag_union );
    628659        }
    629660
  • src/AST/Pass.proto.hpp

    r2b78949 r044ae62  
    458458        SYMTAB_FUNC1( addStruct , const StructDecl *    );
    459459        SYMTAB_FUNC1( addEnum   , const EnumDecl *      );
     460        SYMTAB_FUNC1( addAdt    , const AdtDecl *           );
    460461        SYMTAB_FUNC1( addUnion  , const UnionDecl *     );
    461462        SYMTAB_FUNC1( addTrait  , const TraitDecl *     );
     
    488489
    489490        template<typename core_t>
     491        static inline auto addAdtFwd( core_t & core, int, const ast::AdtDecl * decl ) -> decltype( core.symtab.addAdt( decl ), void() ) {
     492                ast::AdtDecl * fwd = new ast::AdtDecl( decl->location, decl->name );
     493                for ( const auto & param : decl->params ) {
     494                        fwd->params.push_back( deepCopy( param.get() ) );
     495                }
     496                // Experimental
     497                for ( const auto & ctor : decl->data_constructors ) {
     498                        addStructFwd( core, 0, ctor  );
     499                }
     500                core.symtab.addAdt( fwd );
     501        }
     502
     503        template<typename core_t>
     504        static inline auto addAdtFwd( core_t &, long, const ast::AdtDecl) {}
     505
     506        template<typename core_t>
    490507        static inline auto addStruct( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addStruct( str ), void() ) {
    491508                if ( ! core.symtab.lookupStruct( str ) ) {
  • src/AST/Print.cpp

    r2b78949 r044ae62  
    438438        }
    439439
     440        virtual const ast::Decl * visit( const ast::AdtDecl * node ) override final {
     441                print(node);
     442                return node;
     443        }
     444
    440445        virtual const ast::Decl * visit( const ast::TraitDecl * node ) override final {
    441446                print(node);
  • src/AST/SymbolTable.cpp

    r2b78949 r044ae62  
    358358}
    359359
     360void SymbolTable::addAdt( const AdtDecl *decl ) {
     361        ++*stats().add_calls;
     362        const std::string &id = decl->name;
     363
     364        if ( ! adtTable ) {
     365                adtTable = AdtTable::new_ptr();
     366        } else {
     367                ++*stats().map_lookups;
     368                auto existing = adtTable->find( id );
     369                if ( existing != adtTable->end()
     370                        && existing->second.scope == scope
     371                        && addedDeclConflicts( existing->second.decl, decl ) ) return;
     372       
     373        }
     374
     375        lazyInitScope();
     376        ++*stats().map_mutations;
     377        adtTable = adtTable->set( id, scoped<AdtDecl>{ decl, scope });
     378}
     379
    360380void SymbolTable::addUnion( const std::string &id ) {
    361381        addUnion( new UnionDecl( CodeLocation(), id ) );
  • src/AST/SymbolTable.hpp

    r2b78949 r044ae62  
    7272        using StructTable = PersistentMap< std::string, scoped<StructDecl> >;
    7373        using EnumTable = PersistentMap< std::string, scoped<EnumDecl> >;
     74        using AdtTable = PersistentMap< std::string, scoped<AdtDecl> >;
    7475        using UnionTable = PersistentMap< std::string, scoped<UnionDecl> >;
    7576        using TraitTable = PersistentMap< std::string, scoped<TraitDecl> >;
     
    8081        EnumTable::Ptr enumTable;      ///< enum namespace
    8182        UnionTable::Ptr unionTable;    ///< union namespace
     83        AdtTable::Ptr adtTable;            ///< adt namespace
    8284        TraitTable::Ptr traitTable;    ///< trait namespace
    8385        IdTable::Ptr specialFunctionTable[NUMBER_OF_KINDS];
     
    138140        /// Adds an enum declaration to the symbol table
    139141        void addEnum( const EnumDecl * decl );
     142        /// Adds an adt declaration to the symbol table
     143        void addAdt( const AdtDecl * decl );
    140144        /// Adds a union declaration to the symbol table by name
    141145        void addUnion( const std::string & id );
  • src/AST/Visitor.hpp

    r2b78949 r044ae62  
    2727    virtual const ast::Decl *             visit( const ast::UnionDecl            * ) = 0;
    2828    virtual const ast::Decl *             visit( const ast::EnumDecl             * ) = 0;
     29    virtual const ast::Decl *             visit( const ast::AdtDecl              * ) = 0;
    2930    virtual const ast::Decl *             visit( const ast::TraitDecl            * ) = 0;
    3031    virtual const ast::Decl *             visit( const ast::TypeDecl             * ) = 0;
  • src/CodeGen/CodeGenerator.cc

    r2b78949 r044ae62  
    295295        }
    296296
     297        void CodeGenerator::handleData( EnumDecl * ) {
     298                // output << " /** data type */" << endl;
     299                // for ( StructDecl * decl : dataDecl->data_constructors ) {
     300                //      postvisit(decl);
     301                //      output << ";" << endl;
     302                // }
     303                // postvisit( dataDecl->data_union );
     304                // output << ";" << endl;
     305                // postvisit( dataDecl->tag );
     306                // output << ";" << endl;
     307                // postvisit( dataDecl->tag_union );
     308                // output << ";" << endl;
     309                assert(false);
     310        }
     311
    297312        void CodeGenerator::postvisit( EnumDecl * enumDecl ) {
    298                 extension( enumDecl );
     313                // if ( enumDecl->data_constructors.size() > 0 ) return handleData( enumDecl );
     314                extension( enumDecl );
    299315                std::list< Declaration* > &memb = enumDecl->get_members();
    300316                if (enumDecl->base && ! memb.empty()) {
     
    332348                        } // if
    333349                } // if
     350        }
     351
     352        void CodeGenerator::postvisit( AdtDecl * ) {
     353                // TODO
    334354        }
    335355
  • src/CodeGen/CodeGenerator.h

    r2b78949 r044ae62  
    5353                void postvisit( UnionDecl * aggregateDecl );
    5454                void postvisit( EnumDecl * aggregateDecl );
     55                void postvisit( AdtDecl * AggregateDecl );
    5556                void postvisit( TraitDecl * aggregateDecl );
    5657                void postvisit( TypedefDecl * typeDecl );
     
    165166                void handleTypedef( NamedTypeDecl *namedType );
    166167                std::string mangleName( DeclarationWithType * decl );
     168
     169                void handleData( EnumDecl * EnumDecl );
    167170        }; // CodeGenerator
    168171
  • src/Common/CodeLocationTools.cpp

    r2b78949 r044ae62  
    105105    macro(UnionDecl, Decl) \
    106106    macro(EnumDecl, Decl) \
     107        macro(AdtDecl, Decl) \
    107108    macro(TraitDecl, Decl) \
    108109    macro(TypeDecl, Decl) \
  • src/Common/PassVisitor.h

    r2b78949 r044ae62  
    6969        virtual void visit( EnumDecl * aggregateDecl ) override final;
    7070        virtual void visit( const EnumDecl * aggregateDecl ) override final;
     71        virtual void visit( AdtDecl * aggregateDecl ) override final;
     72        virtual void visit( const AdtDecl * AggregateDecl ) override final;
    7173        virtual void visit( TraitDecl * aggregateDecl ) override final;
    7274        virtual void visit( const TraitDecl * aggregateDecl ) override final;
     
    269271        virtual Declaration * mutate( UnionDecl * aggregateDecl ) override final;
    270272        virtual Declaration * mutate( EnumDecl * aggregateDecl ) override final;
     273        virtual Declaration * mutate( AdtDecl * aggregateDecl ) override final;
    271274        virtual Declaration * mutate( TraitDecl * aggregateDecl ) override final;
    272275        virtual Declaration * mutate( TypeDecl * typeDecl ) override final;
     
    439442        void indexerAddStructFwd( const StructDecl          * node  ) { indexer_impl_addStructFwd( pass, 0, node ); }
    440443        void indexerAddEnum     ( const EnumDecl            * node  ) { indexer_impl_addEnum     ( pass, 0, node ); }
     444        void indexerAddAdt              ( const AdtDecl                         * node  ) { indexer_impl_addAdt          ( pass, 0, node ); }
     445        void indexerAddAdtFwd   ( const AdtDecl                         * node  ) { indexer_impl_addAdtFwd   ( pass, 0, node  ); }
    441446        void indexerAddUnion    ( const std::string         & id    ) { indexer_impl_addUnion    ( pass, 0, id   ); }
    442447        void indexerAddUnion    ( const UnionDecl           * node  ) { indexer_impl_addUnion    ( pass, 0, node ); }
  • src/Common/PassVisitor.impl.h

    r2b78949 r044ae62  
    754754
    755755        // unlike structs, traits, and unions, enums inject their members into the global scope
    756         // if ( node->base ) maybeAccept_impl( node->base, *this ); // Need this? Maybe not?
    757756        maybeAccept_impl( node->parameters, *this );
    758757        maybeAccept_impl( node->members   , *this );
     
    783782
    784783        // unlike structs, traits, and unions, enums inject their members into the global scope
     784        maybeMutate_impl( node->parameters, *this );
     785        maybeMutate_impl( node->members   , *this );
     786        maybeMutate_impl( node->attributes, *this );
     787
     788        MUTATE_END( Declaration, node );
     789}
     790
     791template< typename pass_type >
     792void PassVisitor< pass_type >::visit( AdtDecl * node ) {
     793        VISIT_START( node );
     794
     795        indexerAddAdtFwd( node );
     796
     797        // unlike structs, traits, and unions, enums inject their members into the global scope
     798        maybeAccept_impl( node->data_constructors, *this );
     799        maybeAccept_impl( node->data_union, *this );
     800        maybeAccept_impl( node->tag, *this );
     801
     802        maybeAccept_impl( node->parameters, *this );
     803        maybeAccept_impl( node->members   , *this );
     804        maybeAccept_impl( node->attributes, *this );
     805
     806        VISIT_END( node );
     807}
     808
     809template< typename pass_type >
     810void PassVisitor< pass_type >::visit( const AdtDecl * node ) {
     811        VISIT_START( node );
     812
     813        indexerAddAdtFwd( node );
     814
     815        maybeAccept_impl( node->data_constructors, *this );
     816        maybeAccept_impl( node->data_union, *this );
     817        maybeAccept_impl( node->tag, *this );
     818
     819        maybeAccept_impl( node->parameters, *this );
     820        maybeAccept_impl( node->members   , *this );
     821        maybeAccept_impl( node->attributes, *this );
     822
     823
     824        VISIT_END( node );
     825
     826
     827template< typename pass_type >
     828Declaration * PassVisitor< pass_type >::mutate( AdtDecl * node ) {
     829        MUTATE_START( node );
     830       
     831        indexerAddAdtFwd( node );
     832
     833        maybeMutate_impl( node->data_constructors, *this );
     834        maybeMutate_impl( node->data_union, *this );
     835        maybeMutate_impl( node->tag, *this );
     836
    785837        maybeMutate_impl( node->parameters, *this );
    786838        maybeMutate_impl( node->members   , *this );
  • src/Common/PassVisitor.proto.h

    r2b78949 r044ae62  
    233233INDEXER_FUNC1( addStruct , const StructDecl *                );
    234234INDEXER_FUNC1( addEnum   , const EnumDecl *                  );
     235INDEXER_FUNC1( addAdt    , const AdtDecl *                                       );
    235236INDEXER_FUNC1( addUnion  , const UnionDecl *                 );
    236237INDEXER_FUNC1( addTrait  , const TraitDecl *                 );
     
    251252
    252253template<typename pass_type>
     254static inline auto indexer_impl_addAdtFwd( pass_type & pass, int, const AdtDecl * decl ) -> decltype( pass.indexer.addAdt( decl ), void() ) {
     255        AdtDecl * fwd = new AdtDecl( decl->name );
     256        cloneAll( decl->parameters, fwd->parameters );
     257
     258        // Experimental
     259        for ( const StructDecl * ctor : fwd->data_constructors ) {
     260                indexer_impl_addStructFwd( pass, 0, ctor );
     261        }
     262
     263        pass.indexer.addAdt( fwd );
     264}
     265
     266template<typename pass_type>
     267static inline auto indexer_impl_addAdtFwd( pass_type &, long, const AdtDecl * ) {}
     268
     269template<typename pass_type>
    253270static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, const UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
    254271        UnionDecl * fwd = new UnionDecl( decl->name );
  • src/Parser/DeclarationNode.cc

    r2b78949 r044ae62  
    279279} // DeclarationNode::newEnum
    280280
     281DeclarationNode * DeclarationNode::newAdt( const string * name, DeclarationNode * constructors ) {
     282        assert( name );
     283        DeclarationNode * newnode = new DeclarationNode;
     284        newnode->type = new TypeData( TypeData::Adt );
     285        newnode->type->adt.name = name;
     286        newnode->type->adt.data_constructors = constructors;
     287        return newnode;
     288} // DeclarationNode::newAdt
     289
     290
    281291DeclarationNode * DeclarationNode::newName( const string * name ) {
    282292        DeclarationNode * newnode = new DeclarationNode;
     
    305315        } // if
    306316} // DeclarationNode::newEnumValueGeneric
     317
     318DeclarationNode * DeclarationNode::newDataConstructor( const string * name ) {
     319        DeclarationNode * newnode = newName(name);
     320        return newnode;
     321}
    307322
    308323DeclarationNode * DeclarationNode::newEnumInLine( const string name ) {
     
    10831098        }
    10841099        return nullptr;
     1100}
     1101
     1102std::vector<ast::ptr<ast::StructDecl>> buildDataConstructors( DeclarationNode * firstNode ) {
     1103        std::vector<ast::ptr<ast::StructDecl>> outputList;
     1104        std::back_insert_iterator<std::vector<ast::ptr<ast::StructDecl>>> out( outputList );
     1105        for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur ) ) {
     1106                // td->kind == TypeData::Symbolic
     1107                assert( cur->type->kind == TypeData::Symbolic );
     1108                const std::string * name = cur->name;
     1109                auto ctor = new ast::StructDecl( cur->location,
     1110                        std::string(*name),
     1111                        ast::AggregateDecl::Aggregate::Struct
     1112                );
     1113                ctor->set_body(true);
     1114                TypeData * td = cur->type;
     1115                TypeData::Symbolic_t st = td->symbolic;
     1116                DeclarationNode * params = st.params;
     1117               
     1118                if ( params ) {
     1119                        buildList( params, ctor->members );
     1120                }
     1121
     1122                for ( std::size_t i = 0; i < ctor->members.size(); ++i ) {
     1123                        assert(ctor->members[i]->name == "");
     1124                        ast::Decl * member = ctor->members[i].get_and_mutate();
     1125                        member->name = "field_" + std::to_string(i);
     1126                }
     1127                *out++ = ctor;         
     1128        }
     1129        return outputList;
     1130}
     1131
     1132ast::UnionDecl * buildDataUnion( const CodeLocation & loc, const std::vector<ast::ptr<ast::StructDecl>> & typeList ) {
     1133        ast::UnionDecl * out = new ast::UnionDecl( loc, "temp_data_union" );
     1134        // size_t index = 0;
     1135        if ( typeList.size() > 0 ) out->set_body( true );
     1136        size_t i = 0;
     1137        for (const ast::ptr<ast::StructDecl> structDecl : typeList ) {
     1138                ast::StructInstType * inst = new ast::StructInstType(structDecl);
     1139                ast::ObjectDecl * instObj = new ast::ObjectDecl(
     1140                        structDecl->location,
     1141                        "option_" + std::to_string(i),
     1142                        inst
     1143                );
     1144                i++;
     1145                out->members.push_back( instObj );
     1146
     1147        }
     1148        return out;
     1149}
     1150
     1151ast::EnumDecl * buildTag( const CodeLocation & loc, std::vector<ast::ptr<ast::StructDecl>> & typeList ) {
     1152        ast::EnumDecl * out = new ast::EnumDecl( loc, "temp_data_tag" );
     1153        if ( typeList.size() > 0 ) out->set_body( true );
     1154        for ( const ast::ptr<ast::StructDecl> structDecl : typeList ) {
     1155                ast::EnumInstType * inst = new ast::EnumInstType( out );
     1156                assert( inst->base != nullptr );
     1157                ast::ObjectDecl * instObj = new ast::ObjectDecl(
     1158                        structDecl->location,
     1159                        structDecl->name,
     1160                        inst
     1161                );
     1162                out->members.push_back( instObj );
     1163        }
     1164        return out;
     1165}
     1166
     1167ast::StructDecl * buildTaggedUnions( const TypeData * data, const ast::EnumDecl * tags, const ast::UnionDecl * data_union ) {
     1168        assert( tags->members.size() == data_union->members.size() );
     1169        ast::StructDecl * out = new ast::StructDecl( data->location, *(data->adt.name) );
     1170        out->kind = ast::AggregateDecl::Adt;
     1171
     1172        out->set_body( true );
     1173
     1174        ast::EnumInstType * tag = new ast::EnumInstType( tags );
     1175        ast::ObjectDecl * tag_obj = new ast::ObjectDecl(
     1176                data->location,
     1177                "tag",
     1178                tag
     1179        );
     1180        ast::UnionInstType * value = new ast::UnionInstType( data_union );
     1181        ast::ObjectDecl * value_obj = new ast::ObjectDecl(
     1182                data->location,
     1183                "value",
     1184                value
     1185        );
     1186
     1187        out->members.push_back( value_obj );
     1188        out->members.push_back( tag_obj );
     1189        return out;
    10851190}
    10861191
  • src/Parser/DeclarationNode.h

    r2b78949 r044ae62  
    7676        static DeclarationNode * newStaticAssert( ExpressionNode * condition, ast::Expr * message );
    7777
     78        // Experimental algebric data type
     79        static DeclarationNode * newAdt( const std::string * name, DeclarationNode * constructors );
     80        static DeclarationNode * newDataConstructor( const std::string * name );
     81        // static DeclarationNode * newDataConstructor( const std::string * name, DeclarationNode * typeSpecifiers );
     82
    7883        DeclarationNode();
    7984        ~DeclarationNode();
     
    156161        ExpressionNode * bitfieldWidth = nullptr;
    157162        std::unique_ptr<ExpressionNode> enumeratorValue;
     163
    158164        bool hasEllipsis = false;
    159165        ast::Linkage::Spec linkage;
     
    211217void buildTypeList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Type>> & outputList );
    212218
     219std::vector<ast::ptr<ast::StructDecl>> buildDataConstructors( DeclarationNode * firstNode );
     220ast::UnionDecl * buildDataUnion( const CodeLocation & loc, const std::vector<ast::ptr<ast::StructDecl>> & typeList );
     221ast::EnumDecl * buildTag( const CodeLocation & loc, std::vector<ast::ptr<ast::StructDecl>> & typeList );
     222ast::StructDecl * buildTaggedUnions( const TypeData * data, const ast::EnumDecl * tag, const ast::UnionDecl * data_union );
     223
    213224template<typename AstType, typename NodeType,
    214225                template<typename, typename...> class Container, typename... Args>
  • src/Parser/TypeData.cc

    r2b78949 r044ae62  
    5959                enumeration.anon = false;
    6060                break;
     61        case Adt:
     62                adt.name = nullptr;
     63                adt.data_constructors = nullptr;
     64                break;
    6165        case Aggregate:
    6266                aggregate.kind = ast::AggregateDecl::NoAggregate;
     
    160164                delete qualified.child;
    161165                break;
     166        case Adt:
     167                delete adt.data_constructors;
     168                delete adt.name;
     169                break;
    162170        } // switch
    163171} // TypeData::~TypeData
     
    217225                newtype->enumeration.body = enumeration.body;
    218226                newtype->enumeration.anon = enumeration.anon;
     227                newtype->enumeration.data_constructors = maybeClone( enumeration.data_constructors );
     228                break;
     229        case Adt:
     230                newtype->adt.data_constructors = maybeClone( enumeration.data_constructors );
     231                newtype->adt.name = new string ( *adt.name );
    219232                break;
    220233        case Symbolic:
     
    459472        case Enum:
    460473                return enumeration.name;
     474        case Adt:
     475                return adt.name;
    461476        case Symbolic:
    462477        case SymbolicInst:
     
    822837        case TypeData::Symbolic:
    823838        case TypeData::Enum:
     839        case TypeData::Adt:
    824840        case TypeData::Aggregate:
    825841                assert( false );
     
    12601276        );
    12611277        buildList( td->enumeration.constants, ret->members );
     1278        if ( td->enumeration.data_constructors != nullptr ) {
     1279                assert( false );
     1280                // ret->data_constructors = buildDataConstructors( td->enumeration.data_constructors );
     1281                // ret->data_union = buildDataUnion( td->location, ret->data_constructors );
     1282                // ret->tag = buildTag( td->location, ret->data_constructors );
     1283                // ret->tag_union = buildTaggedUnions( td, ret->tag.get(), ret->data_union.get() );
     1284        }
     1285
     1286        // if ( ret->data_constructors.size() > 0 ) ret->isData = true;
    12621287        auto members = ret->members.begin();
    12631288        ret->hide = td->enumeration.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
     
    12861311        return ret;
    12871312} // buildEnum
     1313
     1314ast::AdtDecl * buildAdt(const TypeData * td,
     1315        std::vector<ast::ptr<ast::Attribute>> && attributes,
     1316        ast::Linkage::Spec linkage ) {
     1317        assert( td->kind == TypeData::Adt );
     1318        ast::AdtDecl * ret = new ast::AdtDecl( td->location, *(td->adt.name) );
     1319        ret->data_constructors = buildDataConstructors( td->adt.data_constructors );
     1320        ret->data_union = buildDataUnion( td->location, ret->data_constructors );
     1321        ret->tag = buildTag( td->location, ret->data_constructors );
     1322        ret->tag_union = buildTaggedUnions( td, ret->tag.get(), ret->data_union.get() );
     1323        return ret;
     1324}
    12881325
    12891326
     
    14291466        } else if ( td->kind == TypeData::Enum ) {
    14301467                return buildEnum( td, std::move( attributes ), linkage );
     1468        } else if ( td->kind == TypeData::Adt) {
     1469                return buildAdt( td, std::move( attributes), linkage );
    14311470        } else if ( td->kind == TypeData::Symbolic ) {
    14321471                return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
  • src/Parser/TypeData.h

    r2b78949 r044ae62  
    2525struct TypeData {
    2626        enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
    27                                 SymbolicInst, Tuple, Basetypeof, Typeof, Vtable, Builtin, GlobalScope, Qualified, Unknown };
     27                                SymbolicInst, Tuple, Basetypeof, Typeof, Vtable, Builtin, GlobalScope, Qualified, Adt, Ctor, Unknown };
    2828
    2929        struct Aggregate_t {
     
    5858                bool typed;
    5959                EnumHiding hiding;
     60                bool isData = false;
     61
     62                DeclarationNode * data_constructors = nullptr;
     63        };
     64
     65        struct ADT_t {
     66                const std::string * name = nullptr;
     67                DeclarationNode * data_constructors;
    6068        };
    6169
     
    98106        Array_t array;
    99107        Enumeration_t enumeration;
     108        ADT_t adt;
     109
    100110        Function_t function;
    101111        Symbolic_t symbolic;
     
    124134ast::TypeDecl * buildVariable( const TypeData * );
    125135ast::EnumDecl * buildEnum( const TypeData *, std::vector<ast::ptr<ast::Attribute>> &&, ast::Linkage::Spec );
     136ast::EnumDecl * buildAst( const TypeData *, std::vector<ast::ptr<ast::Attribute>> &&, ast::Linkage::Spec );
    126137ast::TypeInstType * buildSymbolicInst( const TypeData * );
    127138ast::TupleType * buildTuple( const TypeData * );
  • src/Parser/lex.ll

    r2b78949 r044ae62  
    353353with                    { KEYWORD_RETURN(WITH); }                               // CFA
    354354zero_t                  { NUMERIC_RETURN(ZERO_T); }                             // CFA
     355_DATA_            { KEYWORD_RETURN(DATA); }                             // Experimental
    355356
    356357                                /* identifier */
  • src/Parser/parser.yy

    r2b78949 r044ae62  
    340340%token SIZEOF TYPEOF VA_LIST VA_ARG AUTO_TYPE                   // GCC
    341341%token OFFSETOF BASETYPEOF TYPEID                                               // CFA
    342 %token ENUM STRUCT UNION
     342%token ENUM STRUCT UNION DATA
    343343%token EXCEPTION                                                                                // CFA
    344344%token GENERATOR COROUTINE MONITOR THREAD                               // CFA
     
    455455%type<decl> enumerator_list enum_type enum_type_nobody
    456456%type<init> enumerator_value_opt
     457
     458%type<decl> value_list
     459%type<decl> data_constructor type_specifier_list
    457460
    458461%type<decl> external_definition external_definition_list external_definition_list_opt
     
    24492452                }
    24502453        | enum_type
     2454        /* | algebric_data_type */
    24512455        ;
    24522456
     
    27022706                }
    27032707        | enum_type_nobody
    2704         ;
     2708        | DATA identifier
     2709        { typedefTable.makeTypedef( *$2 ); }
     2710         '{' value_list '}'
     2711         {
     2712                $$ = DeclarationNode::newAdt( $2, $5 );
     2713         }
     2714        ;
     2715
     2716value_list:
     2717        data_constructor
     2718        {
     2719                $$ = $1;
     2720        }
     2721        /* | identifier_or_type_name '(' type_specifier ')'
     2722        {
     2723                $$ = DeclarationNode::newEnumValueGeneric( $1, nullptr );
     2724        } */
     2725        /* | data_constructor '|' value_list   */
     2726        | value_list '|' data_constructor
     2727        {
     2728                 { $$ = $1->appendList( $3 ); }
     2729        }
     2730        ;
     2731
     2732data_constructor:
     2733        identifier_or_type_name
     2734        {
     2735                typedefTable.makeTypedef( *$1 );
     2736                $$ =  DeclarationNode::newTypeDecl( $1, nullptr );;
     2737        }
     2738        | identifier_or_type_name '(' type_specifier_list ')'
     2739        {
     2740                typedefTable.makeTypedef( *$1 );
     2741                $$ = DeclarationNode::newTypeDecl( $1, $3 );
     2742        }
     2743
     2744type_specifier_list:
     2745        type_specifier
     2746        /* | type_specifier ',' type_specifier_list  */
     2747        | type_specifier_list ',' type_specifier
     2748        {
     2749                $$ = $1->appendList($3);
     2750        }
     2751        ;
     2752
    27052753
    27062754hide_opt:
  • src/SymTab/Indexer.cc

    r2b78949 r044ae62  
    606606        }
    607607
     608        void Indexer::addAdt( const AdtDecl * decl ) {
     609                ++*stats().add_calls;
     610                const std::string & id = decl->name;
     611
     612                if ( ! adtTable ) {
     613                        adtTable = AdtTable::new_ptr();
     614                } else {
     615                        ++* stats().map_lookups;
     616                        auto existing = adtTable->find( id );
     617                        if ( existing != adtTable->end()
     618                                && existing->second.scope == scope
     619                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
     620
     621                }
     622
     623                lazyInitScope();
     624                ++* stats().map_mutations;
     625                adtTable = adtTable->set( id, Scoped<AdtDecl>{ decl, scope} );
     626        }
     627
    608628        void Indexer::addUnion( const std::string & id ) {
    609629                addUnion( new UnionDecl( id ) );
  • src/SymTab/Indexer.h

    r2b78949 r044ae62  
    8989                void addStruct( const StructDecl * decl );
    9090                void addEnum( const EnumDecl * decl );
     91                void addAdt( const AdtDecl * decl );
    9192                void addUnion( const std::string & id );
    9293                void addUnion( const UnionDecl * decl );
     
    124125                using UnionTable = PersistentMap< std::string, Scoped<UnionDecl> >;
    125126                using TraitTable = PersistentMap< std::string, Scoped<TraitDecl> >;
     127                using AdtTable = PersistentMap< std::string, Scoped<AdtDecl> >;
    126128
    127129                IdTable::Ptr idTable;          ///< identifier namespace
     
    131133                UnionTable::Ptr unionTable;    ///< union namespace
    132134                TraitTable::Ptr traitTable;    ///< trait namespace
     135                AdtTable::Ptr adtTable;            ///< adt namespace
    133136
    134137                Ptr prevScope;                 ///< reference to indexer for parent scope
  • src/SynTree/AggregateDecl.cc

    r2b78949 r044ae62  
    2929
    3030// These must harmonize with the corresponding AggregateDecl::Aggregate enumerations.
    31 static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName" };
     31static const char * aggregateNames[] = { "struct", "union", "enum", "exception", "trait", "generator", "coroutine", "monitor", "thread", "NoAggregateName", "data" };
    3232
    3333const char * AggregateDecl::aggrString( AggregateDecl::Aggregate aggr ) {
  • src/SynTree/Declaration.h

    r2b78949 r044ae62  
    268268        typedef Declaration Parent;
    269269  public:
    270         enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate };
     270        enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate, ADT };
    271271        static const char * aggrString( Aggregate aggr );
    272272
     
    362362};
    363363
     364class AdtDecl : public AggregateDecl {
     365        typedef AggregateDecl Parent;
     366  public:
     367        std::list<StructDecl*> data_constructors;
     368        UnionDecl * data_union;
     369        EnumDecl * tag;
     370        StructDecl * tag_union;
     371
     372        AdtDecl( const std::string & name,
     373         const std::list< Attribute * > & attributes = std::list< class Attribute * >(),
     374         LinkageSpec::Spec linkage = LinkageSpec::Cforall,
     375         const std::list< StructDecl* > data_constructors = std::list< StructDecl * >(),
     376         UnionDecl * data_union = nullptr, EnumDecl * tag = nullptr, StructDecl * tag_union = nullptr )
     377         : Parent( name, attributes, linkage ), data_constructors(data_constructors),
     378         data_union( data_union ), tag( tag ), tag_union( tag_union ) {}
     379
     380        AdtDecl( const AdtDecl & other )
     381         : Parent( other ) {}
     382
     383        virtual AdtDecl * clone() const override { return new AdtDecl( *this ); }
     384        virtual void accept( Visitor & v ) override { v.visit( this ); }
     385        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     386
     387        virtual Declaration * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     388        virtual void print( std::ostream & os, Indenter indent = {} ) const override final {
     389                os << "AdtDecl ... " << indent;
     390        }
     391       
     392private:
     393        virtual const char * typeString() const override {
     394                return "AdtDecl";
     395        }
     396};
     397
    364398class TraitDecl : public AggregateDecl {
    365399        typedef AggregateDecl Parent;
  • src/SynTree/Mutator.h

    r2b78949 r044ae62  
    3030        virtual Declaration * mutate( UnionDecl * aggregateDecl ) = 0;
    3131        virtual Declaration * mutate( EnumDecl * aggregateDecl ) = 0;
     32        virtual Declaration * mutate( AdtDecl * aggregateDecl ) = 0;
    3233        virtual Declaration * mutate( TraitDecl * aggregateDecl ) = 0;
    3334        virtual Declaration * mutate( TypeDecl * typeDecl ) = 0;
  • src/SynTree/SynTree.h

    r2b78949 r044ae62  
    3131class UnionDecl;
    3232class EnumDecl;
     33class AdtDecl;
    3334class TraitDecl;
    3435class NamedTypeDecl;
  • src/SynTree/Visitor.h

    r2b78949 r044ae62  
    3737        virtual void visit( EnumDecl * node ) { visit( const_cast<const EnumDecl *>(node) ); }
    3838        virtual void visit( const EnumDecl * aggregateDecl ) = 0;
     39        virtual void visit( AdtDecl * node ) { visit( const_cast<const AdtDecl *>(node) ); }
     40        virtual void visit( const AdtDecl * node ) = 0;
    3941        virtual void visit( TraitDecl * node ) { visit( const_cast<const TraitDecl *>(node) ); }
    4042        virtual void visit( const TraitDecl * aggregateDecl ) = 0;
  • src/Validate/Autogen.cpp

    r2b78949 r044ae62  
    125125        // Built-ins do not use autogeneration.
    126126        bool shouldAutogen() const final { return !decl->linkage.is_builtin && !structHasFlexibleArray(decl); }
     127        void genADTFuncs();
     128        void getADTFuncBody(const ast::ObjectDecl * lhs, ast::FunctionDecl * func);
    127129private:
    128130        void genFuncBody( ast::FunctionDecl * decl ) final;
     
    238240        if ( !enumDecl->body ) return;
    239241
    240         // if ( auto enumBaseType = enumDecl->base ) {
    241         //      if ( auto enumBaseTypeAsStructInst = dynamic_cast<const ast::StructInstType *>(enumBaseType.get()) ) {
    242         //              const ast::StructDecl * structDecl = enumBaseTypeAsStructInst->base.get();
    243         //              this->previsit( structDecl );
    244         //      }
    245         // }
    246 
    247242        ast::EnumInstType enumInst( enumDecl->name );
    248243        enumInst.base = enumDecl;
     
    264259        }
    265260        StructFuncGenerator gen( structDecl, &structInst, functionNesting );
     261
     262        gen.genADTFuncs();
    266263        gen.generateAndAppendFunctions( declsToAddAfter );
    267264}
     
    475472                }
    476473                produceDecl( decl );
     474        }
     475}
     476
     477void StructFuncGenerator::getADTFuncBody(
     478                const ast::ObjectDecl * lhs,
     479                ast::FunctionDecl * func
     480        ) {
     481        const CodeLocation& location = func->location;
     482        assert( decl->members.size() == 2 );
     483        auto first = (decl->members[0]).as<ast::ObjectDecl>();
     484        assert(first != nullptr);
     485        auto firstType = first->type;
     486        auto unionInstDecl = firstType.as<ast::UnionInstType>();
     487        assert(unionInstDecl != nullptr);
     488
     489        auto unionDecl = unionInstDecl->base;
     490       
     491        const ast::ObjectDecl * dstParam =
     492                        func->params.front().strict_as<ast::ObjectDecl>();
     493        const ast::ObjectDecl * srcParam =
     494                        func->params.back().strict_as<ast::ObjectDecl>();
     495       
     496        ast::Expr * srcSelect = new ast::VariableExpr( location, srcParam );
     497
     498        ast::CompoundStmt * stmts = new ast::CompoundStmt( location );
     499
     500        InitTweak::InitExpander_new srcParamTweak( srcSelect );
     501        ast::Expr * dstSelect =
     502        new ast::MemberExpr(
     503                location,
     504                lhs,
     505                new ast::MemberExpr(
     506                        location,
     507                        first,
     508                        new ast::CastExpr(
     509                                location,
     510                                new ast::VariableExpr( location, dstParam ),
     511                                dstParam->type.strict_as<ast::ReferenceType>()->base
     512                        )
     513                )
     514        );
     515        auto stmt = genImplicitCall(
     516                srcParamTweak, dstSelect, location, func->name,
     517                first, SymTab::LoopForward
     518        );
     519        stmts->push_back( stmt );
     520        func->stmts = stmts;
     521}
     522
     523void StructFuncGenerator::genADTFuncs() {
     524        if ( decl->kind != ast::AggregateDecl::Adt ) return;
     525        assert( decl->members.size() == 2 );
     526        auto first = (decl->members[0]).as<ast::ObjectDecl>();
     527        assert(first != nullptr);
     528        auto firstType = first->type;
     529        auto unionInstDecl = firstType.as<ast::UnionInstType>();
     530        assert(unionInstDecl != nullptr);
     531        auto unionDecl = unionInstDecl->base;
     532
     533        // for (auto mem: unionDecl->members) {
     534        for ( std::size_t i = 0; i < unionDecl->members.size(); ++i ) {
     535                auto mem = unionDecl->members[i];
     536                const ast::ObjectDecl * mem_as_obj = mem.as<ast::ObjectDecl>();
     537                assert( mem_as_obj );
     538                auto mem_type = mem_as_obj->type.as<ast::StructInstType>();
     539                assert( mem_type );
     540                auto location = getLocation();
     541                ast::FunctionDecl * func = new ast::FunctionDecl(
     542                        getLocation(),
     543                        "?{}", // name
     544                        {}, //forall
     545                        { dstParam(), new ast::ObjectDecl( getLocation(), "_src", ast::deepCopy( mem_type ) ) }, // params
     546                        {}, // returns
     547                        {}, // statements
     548                        // Use static storage if we are at the top level.
     549                        (0 < functionNesting) ? ast::Storage::Classes() : ast::Storage::Static,
     550                        proto_linkage,
     551                        std::vector<ast::ptr<ast::Attribute>>(),
     552                        // Auto-generated routines are inline to avoid conflicts.
     553                        ast::Function::Specs( ast::Function::Inline )
     554                );
     555                getADTFuncBody(mem_as_obj, func);
     556                func->fixUniqueId();
     557                produceForwardDecl(func);
     558                if ( CodeGen::isAssignment( func->name ) ) {
     559                        appendReturnThis( func );
     560                }
     561                produceDecl( func );
    477562        }
    478563}
  • src/Validate/HoistStruct.cpp

    r2b78949 r044ae62  
    138138}
    139139
     140void hoistAdt( [[maybe_unused]] ast::TranslationUnit & trnaslationUnit ) {
     141       
     142}
     143
    140144} // namespace Validate
    141145
  • src/Validate/HoistStruct.hpp

    r2b78949 r044ae62  
    2424/// Flattens nested type declarations. (Run right after Fix Qualified Types.)
    2525void hoistStruct( ast::TranslationUnit & translationUnit );
     26void hoistAdt( ast::TranslationUnit & trnaslationUnit );
    2627
    2728}
  • src/Validate/NoIdSymbolTable.hpp

    r2b78949 r044ae62  
    4444        FORWARD_1( addStruct, const ast::StructDecl *    )
    4545        FORWARD_1( addEnum  , const ast::EnumDecl *      )
     46        FORWARD_1( addAdt,    const ast::AdtDecl *               )
    4647        FORWARD_1( addUnion , const ast::UnionDecl *     )
    4748        FORWARD_1( addTrait , const ast::TraitDecl *     )
Note: See TracChangeset for help on using the changeset viewer.