Changeset 67cf18c for src


Ignore:
Timestamp:
May 26, 2017, 6:37:49 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
01b9928
Parents:
ff03f5c
git-author:
Rob Schluntz <rschlunt@…> (05/26/17 18:34:50)
git-committer:
Rob Schluntz <rschlunt@…> (05/26/17 18:37:49)
Message:

implement default type arguments for generic types [closes #13]

Location:
src
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    rff03f5c r67cf18c  
    5757        variable.tyClass = NoTypeClass;
    5858        variable.assertions = nullptr;
     59        variable.initializer = nullptr;
    5960
    6061//      attr.name = nullptr;
     
    7071//      delete variable.name;
    7172        delete variable.assertions;
     73        delete variable.initializer;
    7274
    7375        delete type;
     
    101103        newnode->variable.tyClass = variable.tyClass;
    102104        newnode->variable.assertions = maybeClone( variable.assertions );
     105        newnode->variable.initializer = maybeClone( variable.initializer );
    103106
    104107//      newnode->attr.name = attr.name ? new string( *attr.name ) : nullptr;
     
    857860}
    858861
     862DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) {
     863        assertf( variable.tyClass != NoTypeClass, "Called addTypeInitializer on something that isn't a type variable." );
     864        variable.initializer = init;
     865        return this;
     866}
     867
    859868DeclarationNode * DeclarationNode::cloneType( string * newName ) {
    860869        DeclarationNode * newnode = new DeclarationNode;
     
    10141023                assertf( sizeof(kindMap)/sizeof(kindMap[0] == NoTypeClass-1), "DeclarationNode::build: kindMap is out of sync." );
    10151024                assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
    1016                 TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ] );
     1025                TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.initializer ? variable.initializer->buildType() : nullptr );
    10171026                buildList( variable.assertions, ret->get_assertions() );
    10181027                return ret;
  • src/Parser/ParseNode.h

    rff03f5c r67cf18c  
    274274        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
    275275        DeclarationNode * addInitializer( InitializerNode * init );
     276        DeclarationNode * addTypeInitializer( DeclarationNode * init );
    276277
    277278        DeclarationNode * cloneType( std::string * newName );
     
    301302                DeclarationNode::TypeClass tyClass;
    302303                DeclarationNode * assertions;
     304                DeclarationNode * initializer;
    303305        };
    304306        Variable_t variable;
  • src/Parser/parser.yy

    rff03f5c r67cf18c  
    16061606
    16071607typegen_name:                                                                                   // CFA
    1608         TYPEGENname '(' type_list ')'
     1608        TYPEGENname '(' ')'
     1609                { $$ = DeclarationNode::newFromTypeGen( $1, nullptr ); }
     1610        | TYPEGENname '(' type_list ')'
    16091611                { $$ = DeclarationNode::newFromTypeGen( $1, $3 ); }
    16101612        ;
     
    19831985
    19841986type_parameter_list:                                                                    // CFA
    1985         type_parameter type_initializer_opt
    1986         | type_parameter_list ',' type_parameter type_initializer_opt
     1987        type_parameter
     1988                { $$ = $1; }
     1989        | type_parameter_list ',' type_parameter
    19871990                { $$ = $1->appendList( $3 ); }
    19881991        ;
     
    19982001        type_class no_attr_identifier_or_type_name
    19992002                { typedefTable.addToEnclosingScope( *$2, TypedefTable::TD ); }
    2000           assertion_list_opt
    2001                 { $$ = DeclarationNode::newTypeParam( $1, $2 )->addAssertions( $4 ); }
     2003          type_initializer_opt assertion_list_opt
     2004                { $$ = DeclarationNode::newTypeParam( $1, $2 )->addTypeInitializer( $4 )->addAssertions( $5 ); }
    20022005        | type_specifier identifier_parameter_declarator
    20032006        ;
  • src/SymTab/Indexer.cc

    rff03f5c r67cf18c  
    285285                addType( typeDecl );
    286286                acceptAll( typeDecl->get_assertions(), *this );
     287                acceptNewScope( typeDecl->get_init(), *this );
    287288        }
    288289
  • src/SymTab/Validate.cc

    rff03f5c r67cf18c  
    506506        void LinkReferenceToTypes::visit( StructDecl *structDecl ) {
    507507                // visit struct members first so that the types of self-referencing members are updated properly
     508                // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and and their defaults)
    508509                Parent::visit( structDecl );
    509510                if ( ! structDecl->get_members().empty() ) {
     
    844845                if ( params != NULL ) {
    845846                        std::list< Expression * > & args = inst->get_parameters();
     847
     848                        // insert defaults arguments when a type argument is missing (currently only supports missing arguments at the end of the list).
     849                        // A substitution is used to ensure that defaults are replaced correctly, e.g.,
     850                        //   forall(otype T, otype alloc = heap_allocator(T)) struct vector;
     851                        //   vector(int) v;
     852                        // after insertion of default values becomes
     853                        //   vector(int, heap_allocator(T))
     854                        // and the substitution is built with T=int so that after substitution, the result is
     855                        //   vector(int, heap_allocator(int))
     856                        TypeSubstitution sub;
     857                        auto paramIter = params->begin();
     858                        for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) {
     859                                if ( i < args.size() ) {
     860                                        TypeExpr * expr = safe_dynamic_cast< TypeExpr * >( *std::next( args.begin(), i ) );
     861                                        sub.add( (*paramIter)->get_name(), expr->get_type()->clone() );
     862                                } else if ( i == args.size() ) {
     863                                        Type * defaultType = (*paramIter)->get_init();
     864                                        if ( defaultType ) {
     865                                                args.push_back( new TypeExpr( defaultType->clone() ) );
     866                                                sub.add( (*paramIter)->get_name(), defaultType->clone() );
     867                                        }
     868                                }
     869                        }
     870
     871                        sub.apply( inst );
    846872                        if ( args.size() < params->size() ) throw SemanticError( "Too few type arguments in generic type ", inst );
    847873                        if ( args.size() > params->size() ) throw SemanticError( "Too many type arguments in generic type ", inst );
  • src/SynTree/Declaration.h

    rff03f5c r67cf18c  
    194194        };
    195195
    196         TypeDecl( const std::string &name, Type::StorageClasses scs, Type *type, Kind kind );
     196        TypeDecl( const std::string &name, Type::StorageClasses scs, Type *type, Kind kind, Type * init = nullptr );
    197197        TypeDecl( const TypeDecl &other );
     198        virtual ~TypeDecl();
    198199
    199200        Kind get_kind() const { return kind; }
     201
     202        Type * get_init() const { return init; }
     203        TypeDecl * set_init( Type * newValue ) { init = newValue; return this; }
    200204
    201205        bool isComplete() const { return kind == Any || sized; }
     
    209213        virtual void accept( Visitor &v ) { v.visit( this ); }
    210214        virtual TypeDecl *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     215        virtual void print( std::ostream &os, int indent = 0 ) const;
     216
    211217  private:
    212218        Kind kind;
     219        Type * init;
    213220        bool sized;
    214221};
  • src/SynTree/Mutator.cc

    rff03f5c r67cf18c  
    7777TypeDecl *Mutator::mutate( TypeDecl *typeDecl ) {
    7878        handleNamedTypeDecl( typeDecl );
     79        typeDecl->set_init( maybeMutate( typeDecl->get_init(), *this ) );
    7980        return typeDecl;
    8081}
  • src/SynTree/TypeDecl.cc

    rff03f5c r67cf18c  
    1818#include "Common/utility.h"
    1919
    20 TypeDecl::TypeDecl( const std::string &name, Type::StorageClasses scs, Type *type, Kind kind ) : Parent( name, scs, type ), kind( kind ), sized( kind == Any || kind == Ttype ) {
     20TypeDecl::TypeDecl( const std::string &name, Type::StorageClasses scs, Type *type, Kind kind, Type * init ) : Parent( name, scs, type ), kind( kind ), init( init ), sized( kind == Any || kind == Ttype ) {
    2121}
    2222
    23 TypeDecl::TypeDecl( const TypeDecl &other ) : Parent( other ), kind( other.kind ), sized( other.sized ) {
     23TypeDecl::TypeDecl( const TypeDecl &other ) : Parent( other ), kind( other.kind ), init( maybeClone( other.init ) ), sized( other.sized ) {
     24}
     25
     26TypeDecl::~TypeDecl() {
     27  delete init;
    2428}
    2529
     
    3438}
    3539
     40void TypeDecl::print( std::ostream &os, int indent ) const {
     41  NamedTypeDecl::print( os, indent );
     42  if ( init ) {
     43    os << std::endl << std::string( indent, ' ' ) << "with type initializer: ";
     44    init->print( os, indent + 2 );
     45  }
     46}
     47
     48
    3649std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data ) {
    3750  return os << data.kind << ", " << data.isComplete;
  • src/SynTree/Visitor.cc

    rff03f5c r67cf18c  
    6767void Visitor::visit( TypeDecl *typeDecl ) {
    6868        handleNamedTypeDecl( static_cast< NamedTypeDecl* >( typeDecl ) );
     69        maybeAccept( typeDecl->get_init(), *this );
    6970}
    7071
  • src/libcfa/containers/vector

    rff03f5c r67cf18c  
    2222
    2323//------------------------------------------------------------------------------
     24//Allocator
     25forall(otype T)
     26struct heap_allocator
     27{
     28        T* storage;
     29        size_t capacity;
     30};
     31
     32forall(otype T)
     33void ?{}(heap_allocator(T)* this);
     34
     35forall(otype T)
     36void ?{}(heap_allocator(T)* this, heap_allocator(T) rhs);
     37
     38forall(otype T)
     39heap_allocator(T) ?=?(heap_allocator(T)* this, heap_allocator(T) rhs);
     40
     41forall(otype T)
     42void ^?{}(heap_allocator(T)* this);
     43
     44forall(otype T)
     45void realloc_storage(heap_allocator(T)* this, size_t size);
     46
     47forall(otype T)
     48static inline T* data(heap_allocator(T)* this)
     49{
     50        return this->storage;
     51}
     52
     53//------------------------------------------------------------------------------
    2454//Declaration
    2555trait allocator_c(otype T, otype allocator_t)
     
    2959};
    3060
    31 forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
     61forall(otype T, otype allocator_t = heap_allocator(T) | allocator_c(T, allocator_t))
    3262struct vector;
    3363
     
    4676void ^?{}(vector(T, allocator_t)* this);
    4777
    48 forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
     78forall(otype T, otype allocator_t = heap_allocator(T) | allocator_c(T, allocator_t))
    4979struct vector
    5080{
     
    136166// }
    137167
    138 //------------------------------------------------------------------------------
    139 //Allocator
    140 forall(otype T)
    141 struct heap_allocator
    142 {
    143         T* storage;
    144         size_t capacity;
    145 };
    146 
    147 forall(otype T)
    148 void ?{}(heap_allocator(T)* this);
    149 
    150 forall(otype T)
    151 void ?{}(heap_allocator(T)* this, heap_allocator(T) rhs);
    152 
    153 forall(otype T)
    154 heap_allocator(T) ?=?(heap_allocator(T)* this, heap_allocator(T) rhs);
    155 
    156 forall(otype T)
    157 void ^?{}(heap_allocator(T)* this);
    158 
    159 forall(otype T)
    160 void realloc_storage(heap_allocator(T)* this, size_t size);
    161 
    162 forall(otype T)
    163 static inline T* data(heap_allocator(T)* this)
    164 {
    165         return this->storage;
    166 }
    167 
    168168#endif // VECTOR_H
    169169
  • src/tests/libcfa_vector.c

    rff03f5c r67cf18c  
    2727
    2828int main() {
    29         vector( int, heap_allocator(int) ) iv;
     29        vector( int ) iv;
    3030
    3131        assert( empty( &iv ) );
Note: See TracChangeset for help on using the changeset viewer.