Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/GenPoly.cc

    r3606fe4 rc19edd1  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Sep 14  9:24:00 2022
    13 // Update Count     : 15
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jun 29 21:45:53 2016
     13// Update Count     : 14
    1414//
    1515
     
    8383                }
    8484
    85                 bool hasDynParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) {
    86                         for ( ast::ptr<ast::Expr> const & param : params ) {
    87                                 auto paramType = param.as<ast::TypeExpr>();
    88                                 assertf( paramType, "Aggregate parameters should be type expressions." );
    89                                 if ( isDynType( paramType->type, tyVars, typeSubs ) ) {
    90                                         return true;
    91                                 }
    92                         }
    93                         return false;
    94                 }
    95 
    9685                /// Checks a parameter list for inclusion of polymorphic parameters; will substitute according to env if present
    9786                bool includesPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) {
     
    209198                }
    210199                return 0;
    211         }
    212 
    213         const ast::BaseInstType *isDynType( const ast::Type *type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) {
    214                 type = replaceTypeInst( type, typeSubs );
    215 
    216                 if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) {
    217                         auto var = tyVars.find( inst->name );
    218                         if ( var != tyVars.end() && var->second.isComplete ) {
    219                                 return inst;
    220                         }
    221                 } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) {
    222                         if ( hasDynParams( inst->params, tyVars, typeSubs ) ) {
    223                                 return inst;
    224                         }
    225                 } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) {
    226                         if ( hasDynParams( inst->params, tyVars, typeSubs ) ) {
    227                                 return inst;
    228                         }
    229                 }
    230                 return nullptr;
    231200        }
    232201
     
    409378                inline D* as( B* p ) { return reinterpret_cast<D*>(p); }
    410379
    411                 template<typename D, typename B>
    412                 inline D const * as( B const * p ) {
    413                         return reinterpret_cast<D const *>( p );
    414                 }
    415 
    416380                /// Flattens a declaration list
    417381                template<typename Output>
     
    427391                        for ( Type* ty : src ) {
    428392                                ResolvExpr::flatten( ty, out );
    429                         }
    430                 }
    431 
    432                 void flattenList( vector<ast::ptr<ast::Type>> const & src,
    433                                 vector<ast::ptr<ast::Type>> & out ) {
    434                         for ( auto const & type : src ) {
    435                                 ResolvExpr::flatten( type, out );
    436393                        }
    437394                }
     
    452409                                // if ( is<VoidType>( aparam->get_type() ) || is<VoidType>( bparam->get_type() ) ) continue;
    453410                                if ( ! typesPolyCompatible( aparam->get_type(), bparam->get_type() ) ) return false;
    454                         }
    455 
    456                         return true;
    457                 }
    458 
    459                 bool paramListsPolyCompatible(
    460                                 std::vector<ast::ptr<ast::Expr>> const & lparams,
    461                                 std::vector<ast::ptr<ast::Expr>> const & rparams ) {
    462                         if ( lparams.size() != rparams.size() ) {
    463                                 return false;
    464                         }
    465 
    466                         for ( auto lparam = lparams.begin(), rparam = rparams.begin() ;
    467                                         lparam != lparams.end() ; ++lparam, ++rparam ) {
    468                                 ast::TypeExpr const * lexpr = lparam->as<ast::TypeExpr>();
    469                                 assertf( lexpr, "Aggregate parameters should be type expressions" );
    470                                 ast::TypeExpr const * rexpr = rparam->as<ast::TypeExpr>();
    471                                 assertf( rexpr, "Aggregate parameters should be type expressions" );
    472 
    473                                 // xxx - might need to let VoidType be a wildcard here too; could have some voids
    474                                 // stuffed in for dtype-statics.
    475                                 // if ( is<VoidType>( lexpr->type() ) || is<VoidType>( bparam->get_type() ) ) continue;
    476                                 if ( !typesPolyCompatible( lexpr->type, rexpr->type ) ) {
    477                                         return false;
    478                                 }
    479411                        }
    480412
     
    573505        }
    574506
    575 bool typesPolyCompatible( ast::Type const * lhs, ast::Type const * rhs ) {
    576         type_index const lid = typeid(*lhs);
    577 
    578         // Polymorphic types always match:
    579         if ( type_index(typeid(ast::TypeInstType)) == lid ) return true;
    580 
    581         type_index const rid = typeid(*rhs);
    582         if ( type_index(typeid(ast::TypeInstType)) == rid ) return true;
    583 
    584         // All other types only match if they are the same type:
    585         if ( lid != rid ) return false;
    586 
    587         // So remaining types can be examined case by case.
    588         // Recurse through type structure (conditions borrowed from Unify.cc).
    589 
    590         if ( type_index(typeid(ast::BasicType)) == lid ) {
    591                 return as<ast::BasicType>(lhs)->kind == as<ast::BasicType>(rhs)->kind;
    592         } else if ( type_index(typeid(ast::PointerType)) == lid ) {
    593                 ast::PointerType const * l = as<ast::PointerType>(lhs);
    594                 ast::PointerType const * r = as<ast::PointerType>(rhs);
    595 
    596                 // void pointers should match any other pointer type.
    597                 return is<ast::VoidType>( l->base.get() )
    598                         || is<ast::VoidType>( r->base.get() )
    599                         || typesPolyCompatible( l->base.get(), r->base.get() );
    600         } else if ( type_index(typeid(ast::ReferenceType)) == lid ) {
    601                 ast::ReferenceType const * l = as<ast::ReferenceType>(lhs);
    602                 ast::ReferenceType const * r = as<ast::ReferenceType>(rhs);
    603 
    604                 // void references should match any other reference type.
    605                 return is<ast::VoidType>( l->base.get() )
    606                         || is<ast::VoidType>( r->base.get() )
    607                         || typesPolyCompatible( l->base.get(), r->base.get() );
    608         } else if ( type_index(typeid(ast::ArrayType)) == lid ) {
    609                 ast::ArrayType const * l = as<ast::ArrayType>(lhs);
    610                 ast::ArrayType const * r = as<ast::ArrayType>(rhs);
    611 
    612                 if ( l->isVarLen ) {
    613                         if ( !r->isVarLen ) return false;
    614                 } else {
    615                         if ( r->isVarLen ) return false;
    616 
    617                         auto lc = l->dimension.as<ast::ConstantExpr>();
    618                         auto rc = r->dimension.as<ast::ConstantExpr>();
    619                         if ( lc && rc && lc->intValue() != rc->intValue() ) {
    620                                 return false;
    621                         }
    622                 }
    623 
    624                 return typesPolyCompatible( l->base.get(), r->base.get() );
    625         } else if ( type_index(typeid(ast::FunctionType)) == lid ) {
    626                 ast::FunctionType const * l = as<ast::FunctionType>(lhs);
    627                 ast::FunctionType const * r = as<ast::FunctionType>(rhs);
    628 
    629                 std::vector<ast::ptr<ast::Type>> lparams, rparams;
    630                 flattenList( l->params, lparams );
    631                 flattenList( r->params, rparams );
    632                 if ( lparams.size() != rparams.size() ) return false;
    633                 for ( unsigned i = 0; i < lparams.size(); ++i ) {
    634                         if ( !typesPolyCompatible( lparams[i], rparams[i] ) ) return false;
    635                 }
    636 
    637                 std::vector<ast::ptr<ast::Type>> lrets, rrets;
    638                 flattenList( l->returns, lrets );
    639                 flattenList( r->returns, rrets );
    640                 if ( lrets.size() != rrets.size() ) return false;
    641                 for ( unsigned i = 0; i < lrets.size(); ++i ) {
    642                         if ( !typesPolyCompatible( lrets[i], rrets[i] ) ) return false;
    643                 }
    644                 return true;
    645         } else if ( type_index(typeid(ast::StructInstType)) == lid ) {
    646                 ast::StructInstType const * l = as<ast::StructInstType>(lhs);
    647                 ast::StructInstType const * r = as<ast::StructInstType>(rhs);
    648 
    649                 if ( l->name != r->name ) return false;
    650                 return paramListsPolyCompatible( l->params, r->params );
    651         } else if ( type_index(typeid(ast::UnionInstType)) == lid ) {
    652                 ast::UnionInstType const * l = as<ast::UnionInstType>(lhs);
    653                 ast::UnionInstType const * r = as<ast::UnionInstType>(rhs);
    654 
    655                 if ( l->name != r->name ) return false;
    656                 return paramListsPolyCompatible( l->params, r->params );
    657         } else if ( type_index(typeid(ast::EnumInstType)) == lid ) {
    658                 ast::EnumInstType const * l = as<ast::EnumInstType>(lhs);
    659                 ast::EnumInstType const * r = as<ast::EnumInstType>(rhs);
    660 
    661                 return l->name == r->name;
    662         } else if ( type_index(typeid(ast::TraitInstType)) == lid ) {
    663                 ast::TraitInstType const * l = as<ast::TraitInstType>(lhs);
    664                 ast::TraitInstType const * r = as<ast::TraitInstType>(rhs);
    665 
    666                 return l->name == r->name;
    667         } else if ( type_index(typeid(ast::TupleType)) == lid ) {
    668                 ast::TupleType const * l = as<ast::TupleType>(lhs);
    669                 ast::TupleType const * r = as<ast::TupleType>(rhs);
    670 
    671                 std::vector<ast::ptr<ast::Type>> ltypes, rtypes;
    672                 flattenList( l->types, ( ltypes ) );
    673                 flattenList( r->types, ( rtypes ) );
    674                 if ( ltypes.size() != rtypes.size() ) return false;
    675 
    676                 for ( unsigned i = 0 ; i < ltypes.size() ; ++i ) {
    677                         if ( !typesPolyCompatible( ltypes[i], rtypes[i] ) ) return false;
    678                 }
    679                 return true;
    680         // The remaining types (VoidType, VarArgsType, ZeroType & OneType)
    681         // have no variation so will always be equal.
    682         } else {
    683                 return true;
    684         }
    685 }
    686 
    687507        namespace {
    688508                // temporary hack to avoid re-implementing anything related to TyVarMap
Note: See TracChangeset for help on using the changeset viewer.