Ignore:
Timestamp:
Nov 15, 2023, 5:01:36 PM (8 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
f22b170b
Parents:
45a091b
Message:

Major round of clean-up in the GenPoly? directory.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/GenPoly.cc

    r45a091b rb8b5535  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // GenPoly.cc --
     7// GenPoly.cc -- General GenPoly utilities.
    88//
    99// Author           : Richard C. Bilson
     
    3333
    3434namespace GenPoly {
    35         namespace {
    36                 /// Checks a parameter list for polymorphic parameters; will substitute according to env if present
    37                 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const ast::TypeSubstitution * env ) {
    38                         for ( auto &param : params ) {
    39                                 auto paramType = param.as<ast::TypeExpr>();
    40                                 assertf( paramType, "Aggregate parameters should be type expressions" );
    41                                 if ( isPolyType( paramType->type, env ) ) return true;
     35
     36namespace {
     37        /// Checks a parameter list for polymorphic parameters; will substitute according to env if present.
     38        bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const ast::TypeSubstitution * env ) {
     39                for ( auto & param : params ) {
     40                        auto paramType = param.as<ast::TypeExpr>();
     41                        assertf( paramType, "Aggregate parameters should be type expressions" );
     42                        if ( isPolyType( paramType->type, env ) ) return true;
     43                }
     44                return false;
     45        }
     46
     47        /// Checks a parameter list for polymorphic parameters from typeVars; will substitute according to env if present.
     48        bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TypeVarMap & typeVars, const ast::TypeSubstitution * env ) {
     49                for ( auto & param : params ) {
     50                        auto paramType = param.as<ast::TypeExpr>();
     51                        assertf( paramType, "Aggregate parameters should be type expressions" );
     52                        if ( isPolyType( paramType->type, typeVars, env ) ) return true;
     53                }
     54                return false;
     55        }
     56
     57        /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present.
     58        bool hasDynParams(
     59                        const std::vector<ast::ptr<ast::Expr>> & params,
     60                        const TypeVarMap & typeVars,
     61                        const ast::TypeSubstitution * subst ) {
     62                for ( ast::ptr<ast::Expr> const & paramExpr : params ) {
     63                        auto param = paramExpr.as<ast::TypeExpr>();
     64                        assertf( param, "Aggregate parameters should be type expressions." );
     65                        if ( isDynType( param->type.get(), typeVars, subst ) ) {
     66                                return true;
    4267                        }
    43                         return false;
    44                 }
    45 
    46                 /// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present
    47                 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TypeVarMap & typeVars, const ast::TypeSubstitution * env ) {
    48                         for ( auto & param : params ) {
    49                                 auto paramType = param.as<ast::TypeExpr>();
    50                                 assertf( paramType, "Aggregate parameters should be type expressions" );
    51                                 if ( isPolyType( paramType->type, typeVars, env ) ) return true;
    52                         }
    53                         return false;
    54                 }
    55 
    56                 /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present
    57                 bool hasDynParams(
    58                                 const std::vector<ast::ptr<ast::Expr>> & params,
    59                                 const TypeVarMap & typeVars,
    60                                 const ast::TypeSubstitution * subst ) {
    61                         for ( ast::ptr<ast::Expr> const & paramExpr : params ) {
    62                                 auto param = paramExpr.as<ast::TypeExpr>();
    63                                 assertf( param, "Aggregate parameters should be type expressions." );
    64                                 if ( isDynType( param->type.get(), typeVars, subst ) ) {
    65                                         return true;
    66                                 }
    67                         }
    68                         return false;
    69                 }
    70         }
    71 
    72         const ast::Type * replaceTypeInst(const ast::Type * type, const ast::TypeSubstitution * env) {
    73                 if (!env) return type;
    74                 if ( auto typeInst = dynamic_cast<const ast::TypeInstType*>(type) ) {
    75                         auto newType = env->lookup(typeInst);
    76                         if (newType) return newType;
    77                 }
     68                }
     69                return false;
     70        }
     71} // namespace
     72
     73const ast::Type * replaceTypeInst( const ast::Type * type, const ast::TypeSubstitution * env ) {
     74        if ( !env ) return type;
     75        if ( auto typeInst = dynamic_cast<const ast::TypeInstType*>( type ) ) {
     76                if ( auto newType = env->lookup( typeInst ) ) return newType;
     77        }
     78        return type;
     79}
     80
     81const ast::Type * isPolyType( const ast::Type * type, const ast::TypeSubstitution * subst ) {
     82        type = replaceTypeInst( type, subst );
     83
     84        if ( dynamic_cast< const ast::TypeInstType * >( type ) ) {
     85                // This case is where the two variants of isPolyType differ.
    7886                return type;
    79         }
    80 
    81         const ast::Type * isPolyType(const ast::Type * type, const ast::TypeSubstitution * env) {
    82                 type = replaceTypeInst( type, env );
    83 
    84                 if ( dynamic_cast< const ast::TypeInstType * >( type ) ) {
    85                         return type;
    86                 } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {
    87                         return isPolyType( arrayType->base, env );
    88                 } else if ( auto structType = dynamic_cast< const ast::StructInstType* >( type ) ) {
    89                         if ( hasPolyParams( structType->params, env ) ) return type;
    90                 } else if ( auto unionType = dynamic_cast< const ast::UnionInstType* >( type ) ) {
    91                         if ( hasPolyParams( unionType->params, env ) ) return type;
    92                 }
    93                 return 0;
    94         }
     87        } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {
     88                return isPolyType( arrayType->base, subst );
     89        } else if ( auto structType = dynamic_cast< const ast::StructInstType* >( type ) ) {
     90                if ( hasPolyParams( structType->params, subst ) ) return type;
     91        } else if ( auto unionType = dynamic_cast< const ast::UnionInstType* >( type ) ) {
     92                if ( hasPolyParams( unionType->params, subst ) ) return type;
     93        }
     94        return nullptr;
     95}
    9596
    9697const ast::Type * isPolyType( const ast::Type * type,
     
    121122                }
    122123        } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) {
    123                 if ( hasDynParams( inst->params, typeVars, subst ) ) {
    124                         return inst;
    125                 }
     124                if ( hasDynParams( inst->params, typeVars, subst ) ) return inst;
    126125        } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) {
    127                 if ( hasDynParams( inst->params, typeVars, subst ) ) {
    128                         return inst;
    129                 }
     126                if ( hasDynParams( inst->params, typeVars, subst ) ) return inst;
    130127        }
    131128        return nullptr;
     
    190187}
    191188
    192         const ast::FunctionType * getFunctionType( const ast::Type * ty ) {
    193                 if ( auto pty = dynamic_cast< const ast::PointerType * >( ty ) ) {
    194                         return pty->base.as< ast::FunctionType >();
    195                 } else {
    196                         return dynamic_cast< const ast::FunctionType * >( ty );
    197                 }
    198         }
    199 
    200         namespace {
    201                 /// Checks if is a pointer to D
    202                 template<typename D, typename B>
    203                 bool is( const B* p ) { return type_index{typeid(D)} == type_index{typeid(*p)}; }
    204 
    205                 /// Converts to a pointer to D without checking for safety
    206                 template<typename D, typename B>
    207                 inline D* as( B* p ) { return reinterpret_cast<D*>(p); }
    208 
    209                 template<typename D, typename B>
    210                 inline D const * as( B const * p ) {
    211                         return reinterpret_cast<D const *>( p );
    212                 }
    213 
    214                 /// Flattens a list of types.
    215                 // There is another flattenList in Unify.
    216                 void flattenList( vector<ast::ptr<ast::Type>> const & src,
    217                                 vector<ast::ptr<ast::Type>> & out ) {
    218                         for ( auto const & type : src ) {
    219                                 ResolvExpr::flatten( type, out );
    220                         }
    221                 }
    222 
    223                 bool paramListsPolyCompatible(
    224                                 std::vector<ast::ptr<ast::Expr>> const & lparams,
    225                                 std::vector<ast::ptr<ast::Expr>> const & rparams ) {
    226                         if ( lparams.size() != rparams.size() ) {
     189const ast::FunctionType * getFunctionType( const ast::Type * ty ) {
     190        if ( auto pty = dynamic_cast< const ast::PointerType * >( ty ) ) {
     191                return pty->base.as< ast::FunctionType >();
     192        } else {
     193                return dynamic_cast< const ast::FunctionType * >( ty );
     194        }
     195}
     196
     197namespace {
     198        /// Checks if is a pointer to D
     199        template<typename D, typename B>
     200        bool is( const B* p ) { return type_index{typeid(D)} == type_index{typeid(*p)}; }
     201
     202        /// Converts to a pointer to D without checking for safety
     203        template<typename D, typename B>
     204        inline D* as( B* p ) { return reinterpret_cast<D*>(p); }
     205
     206        template<typename D, typename B>
     207        inline D const * as( B const * p ) {
     208                return reinterpret_cast<D const *>( p );
     209        }
     210
     211        /// Flattens a list of types.
     212        void flattenList( vector<ast::ptr<ast::Type>> const & src,
     213                        vector<ast::ptr<ast::Type>> & out ) {
     214                for ( auto const & type : src ) {
     215                        ResolvExpr::flatten( type, out );
     216                }
     217        }
     218
     219        bool paramListsPolyCompatible(
     220                        std::vector<ast::ptr<ast::Expr>> const & lparams,
     221                        std::vector<ast::ptr<ast::Expr>> const & rparams ) {
     222                if ( lparams.size() != rparams.size() ) {
     223                        return false;
     224                }
     225
     226                for ( auto lparam = lparams.begin(), rparam = rparams.begin() ;
     227                                lparam != lparams.end() ; ++lparam, ++rparam ) {
     228                        ast::TypeExpr const * lexpr = lparam->as<ast::TypeExpr>();
     229                        assertf( lexpr, "Aggregate parameters should be type expressions" );
     230                        ast::TypeExpr const * rexpr = rparam->as<ast::TypeExpr>();
     231                        assertf( rexpr, "Aggregate parameters should be type expressions" );
     232
     233                        // xxx - might need to let VoidType be a wildcard here too; could have some voids
     234                        // stuffed in for dtype-statics.
     235                        // if ( is<VoidType>( lexpr->type() ) || is<VoidType>( bparam->get_type() ) ) continue;
     236                        if ( !typesPolyCompatible( lexpr->type, rexpr->type ) ) {
    227237                                return false;
    228238                        }
    229 
    230                         for ( auto lparam = lparams.begin(), rparam = rparams.begin() ;
    231                                         lparam != lparams.end() ; ++lparam, ++rparam ) {
    232                                 ast::TypeExpr const * lexpr = lparam->as<ast::TypeExpr>();
    233                                 assertf( lexpr, "Aggregate parameters should be type expressions" );
    234                                 ast::TypeExpr const * rexpr = rparam->as<ast::TypeExpr>();
    235                                 assertf( rexpr, "Aggregate parameters should be type expressions" );
    236 
    237                                 // xxx - might need to let VoidType be a wildcard here too; could have some voids
    238                                 // stuffed in for dtype-statics.
    239                                 // if ( is<VoidType>( lexpr->type() ) || is<VoidType>( bparam->get_type() ) ) continue;
    240                                 if ( !typesPolyCompatible( lexpr->type, rexpr->type ) ) {
    241                                         return false;
    242                                 }
    243                         }
    244 
    245                         return true;
    246                 }
    247         }
     239                }
     240
     241                return true;
     242        }
     243} // namespace
    248244
    249245bool typesPolyCompatible( ast::Type const * lhs, ast::Type const * rhs ) {
     
    378374                const ast::TypeSubstitution * subst ) {
    379375        const ast::FunctionType * function = getFunctionType( expr->func->result );
    380         assertf( function, "ApplicationExpr has non-function type: %s", toString( expr->func->result ).c_str() );
     376        assertf( function, "ApplicationExpr has non-function type: %s", toCString( expr->func->result ) );
    381377        TypeVarMap exprTyVars;
    382378        makeTypeVarMap( function, exprTyVars );
Note: See TracChangeset for help on using the changeset viewer.