Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/GenPoly.cc

    r3e5dd913 rd76c588  
    4646                }
    4747
    48                 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const ast::TypeSubstitution * env) {
    49                         for (auto &param : params) {
    50                                 auto paramType = param.strict_as<ast::TypeExpr>();
    51                                 if (isPolyType(paramType->type, env)) return true;
    52                         }
    53                         return false;
    54                 }
    55 
    5648                /// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present
    5749                bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     
    6456                }
    6557
    66                 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {
    67                         for (auto &param : params) {
    68                                 auto paramType = param.strict_as<ast::TypeExpr>();
    69                                 if (isPolyType(paramType->type, tyVars, env)) return true;
    70                         }
    71                         return false;
    72                 }
    73 
    7458                /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present
    7559                bool hasDynParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     
    10892                        Type *newType = env->lookup( typeInst->get_name() );
    10993                        if ( newType ) return newType;
    110                 }
    111                 return type;
    112         }
    113 
    114         const ast::Type * replaceTypeInst(const ast::Type * type, const ast::TypeSubstitution * env) {
    115                 if (!env) return type;
    116                 if (auto typeInst = dynamic_cast<const ast::TypeInstType*> (type)) {
    117                         auto newType = env->lookup(typeInst);
    118                         if (newType) return newType;
    11994                }
    12095                return type;
     
    136111        }
    137112
    138         const ast::Type * isPolyType(const ast::Type * type, const ast::TypeSubstitution * env) {
    139                 type = replaceTypeInst( type, env );
    140 
    141                 if ( dynamic_cast< const ast::TypeInstType * >( type ) ) {
    142                         return type;
    143                 } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {
    144                         return isPolyType( arrayType->base, env );
    145                 } else if ( auto structType = dynamic_cast< const ast::StructInstType* >( type ) ) {
    146                         if ( hasPolyParams( structType->params, env ) ) return type;
    147                 } else if ( auto unionType = dynamic_cast< const ast::UnionInstType* >( type ) ) {
    148                         if ( hasPolyParams( unionType->params, env ) ) return type;
    149                 }
    150                 return 0;
    151         }
    152 
    153113        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
    154114                type = replaceTypeInst( type, env );
     
    166126                }
    167127                return 0;
    168         }
    169 
    170         const ast::Type * isPolyType(const ast::Type * type, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {
    171                 type = replaceTypeInst( type, env );
    172 
    173                 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( type ) ) {
    174                         return tyVars.find(typeInst->typeString()) != tyVars.end() ? type : nullptr;
    175                 } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {
    176                         return isPolyType( arrayType->base, env );
    177                 } else if ( auto structType = dynamic_cast< const ast::StructInstType* >( type ) ) {
    178                         if ( hasPolyParams( structType->params, env ) ) return type;
    179                 } else if ( auto unionType = dynamic_cast< const ast::UnionInstType* >( type ) ) {
    180                         if ( hasPolyParams( unionType->params, env ) ) return type;
    181                 }
    182                 return nullptr;
    183128        }
    184129
     
    504449        }
    505450
    506         namespace {
    507                 // temporary hack to avoid re-implementing anything related to TyVarMap
    508                 // does this work? these two structs have identical definitions.
    509                 inline TypeDecl::Data convData(const ast::TypeDecl::Data & data) {
    510                         return *reinterpret_cast<const TypeDecl::Data *>(&data);
    511                 }
    512         }
    513 
    514451        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) {
    515452                // is parameter is not polymorphic, don't need to box
     
    522459        }
    523460
    524         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TyVarMap &exprTyVars, const ast::TypeSubstitution * env) {
    525                 // is parameter is not polymorphic, don't need to box
    526                 if ( ! isPolyType( param, exprTyVars ) ) return false;
    527                 ast::ptr<ast::Type> newType = arg;
    528                 if ( env ) env->apply( newType );
    529                 // if the argument's type is polymorphic, we don't need to box again!
    530                 return ! isPolyType( newType );
    531         }
    532 
    533461        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) {
    534462                FunctionType * function = getFunctionType( appExpr->function->result );
     
    539467        }
    540468
    541         bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * appExpr, const ast::TypeSubstitution * env) {
    542                 const ast::FunctionType * function = getFunctionType(appExpr->func->result);
    543                 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->func->result ).c_str() );
    544                 TyVarMap exprTyVars(TypeDecl::Data{});
    545                 makeTyVarMap(function, exprTyVars);
    546                 return needsBoxing(param, arg, exprTyVars, env);
    547 
    548         }
    549 
    550469        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
    551                 tyVarMap.insert( tyVar->name, TypeDecl::Data{ tyVar } );
    552         }
    553 
    554         void addToTyVarMap( const ast::TypeInstType * tyVar, TyVarMap & tyVarMap) {
    555                 tyVarMap.insert(tyVar->typeString(), convData(ast::TypeDecl::Data{tyVar->base}));
     470                // xxx - should this actually be insert?
     471                tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar };
    556472        }
    557473
     
    563479                if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
    564480                        makeTyVarMap( pointer->get_base(), tyVarMap );
    565                 }
    566         }
    567 
    568         void makeTyVarMap(const ast::Type * type, TyVarMap & tyVarMap) {
    569                 if (auto ptype = dynamic_cast<const ast::FunctionType *>(type)) {
    570                         for (auto & tyVar : ptype->forall) {
    571                                 assert (tyVar);
    572                                 addToTyVarMap(tyVar, tyVarMap);
    573                         }
    574                 }
    575                 if (auto pointer = dynamic_cast<const ast::PointerType *>(type)) {
    576                         makeTyVarMap(pointer->base, tyVarMap);
    577481                }
    578482        }
Note: See TracChangeset for help on using the changeset viewer.