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]

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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 );
Note: See TracChangeset for help on using the changeset viewer.