Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/PtrsCastable.cc

    r3c89751 r00ac42e  
    1414//
    1515
    16 #include "AST/Decl.hpp"
    17 #include "AST/Pass.hpp"
    18 #include "AST/Type.hpp"
    19 #include "AST/TypeEnvironment.hpp"
    2016#include "Common/PassVisitor.h"
    2117#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
     
    2723
    2824namespace ResolvExpr {
    29         struct PtrsCastable_old : public WithShortCircuiting  {
     25        struct PtrsCastable : public WithShortCircuiting  {
    3026          public:
    31                 PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     27                PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    3228
    3329                int get_result() const { return result; }
     
    9086                        return objectCast( src, env, indexer );
    9187                } else {
    92                         PassVisitor<PtrsCastable_old> ptrs( dest, env, indexer );
     88                        PassVisitor<PtrsCastable> ptrs( dest, env, indexer );
    9389                        src->accept( ptrs );
    9490                        return ptrs.pass.get_result();
     
    9692        }
    9793
    98         PtrsCastable_old::PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
     94        PtrsCastable::PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
    9995                : dest( dest ), result( 0 ), env( env ), indexer( indexer )     {
    10096        }
    10197
    102         void PtrsCastable_old::postvisit( VoidType * ) {
     98        void PtrsCastable::postvisit( VoidType * ) {
    10399                result = objectCast( dest, env, indexer );
    104100        }
    105101
    106         void PtrsCastable_old::postvisit( BasicType * ) {
     102        void PtrsCastable::postvisit( BasicType * ) {
    107103                result = objectCast( dest, env, indexer );
    108104        }
    109105
    110         void PtrsCastable_old::postvisit( PointerType * ) {
     106        void PtrsCastable::postvisit( PointerType * ) {
    111107                result = objectCast( dest, env, indexer );
    112108        }
    113109
    114         void PtrsCastable_old::postvisit( ArrayType * ) {
     110        void PtrsCastable::postvisit( ArrayType * ) {
    115111                result = objectCast( dest, env, indexer );
    116112        }
    117113
    118         void PtrsCastable_old::postvisit( FunctionType * ) {
     114        void PtrsCastable::postvisit( FunctionType * ) {
    119115                // result = -1;
    120116                result = functionCast( dest, env, indexer );
    121117        }
    122118
    123         void PtrsCastable_old::postvisit( StructInstType * ) {
     119        void PtrsCastable::postvisit( StructInstType * ) {
    124120                result = objectCast( dest, env, indexer );
    125121        }
    126122
    127         void PtrsCastable_old::postvisit( UnionInstType * ) {
     123        void PtrsCastable::postvisit( UnionInstType * ) {
    128124                result = objectCast( dest, env, indexer );
    129125        }
    130126
    131         void PtrsCastable_old::postvisit( EnumInstType * ) {
     127        void PtrsCastable::postvisit( EnumInstType * ) {
    132128                if ( dynamic_cast< EnumInstType* >( dest ) ) {
    133129                        result = 1;
     
    143139        }
    144140
    145         void PtrsCastable_old::postvisit( TraitInstType * ) {}
     141        void PtrsCastable::postvisit( TraitInstType * ) {}
    146142
    147         void PtrsCastable_old::postvisit(TypeInstType *inst ) {
     143        void PtrsCastable::postvisit(TypeInstType *inst) {
    148144                //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1;
    149145                result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1;
    150146        }
    151147
    152         void PtrsCastable_old::postvisit( TupleType * ) {
     148        void PtrsCastable::postvisit( TupleType * ) {
    153149                result = objectCast( dest, env, indexer );
    154150        }
    155151
    156         void PtrsCastable_old::postvisit( VarArgsType * ) {
     152        void PtrsCastable::postvisit( VarArgsType * ) {
    157153                result = objectCast( dest, env, indexer );
    158154        }
    159155
    160         void PtrsCastable_old::postvisit( ZeroType * ) {
     156        void PtrsCastable::postvisit( ZeroType * ) {
    161157                result = objectCast( dest, env, indexer );
    162158        }
    163159
    164         void PtrsCastable_old::postvisit( OneType * ) {
     160        void PtrsCastable::postvisit( OneType * ) {
    165161                result = objectCast( dest, env, indexer );
    166162        }
    167 
    168 namespace {
    169         // can this type be cast to an object (1 for yes, -1 for no)
    170         int objectCast(
    171                 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
    172         ) {
    173                 if ( dynamic_cast< const ast::FunctionType * >( src ) ) {
    174                         return -1;
    175                 } else if ( auto inst = dynamic_cast< const ast::TypeInstType * >( src ) ) {
    176                         if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
    177                                 if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( named ) ) {
    178                                         if ( tyDecl->kind == ast::TypeVar::Ftype ) {
    179                                                 return -1;
    180                                         }
    181                                 }
    182                         } else if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) {
    183                                 if ( eqvClass->data.kind == ast::TypeVar::Ftype ) {
    184                                         return -1;
    185                                 }
    186                         }
    187                 }
    188 
    189                 return 1;
    190         }
    191 
    192         // can this type be cast to a function (inverse of objectCast)
    193         int functionCast(
    194                 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
    195         ) {
    196                 return -1 * objectCast( src, env, symtab );
    197         }
    198 
    199         class PtrsCastable_new : public ast::WithShortCircuiting {
    200                 const ast::Type * dst;
    201                 const ast::TypeEnvironment & env;
    202                 const ast::SymbolTable & symtab;
    203         public:
    204                 int result;
    205 
    206                 PtrsCastable_new(
    207                         const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms )
    208                 : dst( d ), env( e ), symtab( syms ), result( 0 ) {}
    209 
    210                 void previsit( const ast::Type * ) { visit_children = false; }
    211 
    212                 void postvisit( const ast::VoidType * ) {
    213                         result = objectCast( dst, env, symtab );
    214                 }
    215 
    216                 void postvisit( const ast::BasicType * ) {
    217                         result = objectCast( dst, env, symtab );
    218                 }
    219 
    220                 void postvisit( const ast::PointerType * ) {
    221                         result = objectCast( dst, env, symtab );
    222                 }
    223 
    224                 void postvisit( const ast::ArrayType * ) {
    225                         result = objectCast( dst, env, symtab );
    226                 }
    227 
    228                 void postvisit( const ast::FunctionType * ) {
    229                         result = functionCast( dst, env, symtab );
    230                 }
    231 
    232                 void postvisit( const ast::StructInstType * ) {
    233                         result = objectCast( dst, env, symtab );
    234                 }
    235 
    236                 void postvisit( const ast::UnionInstType * ) {
    237                         result = objectCast( dst, env, symtab );
    238                 }
    239 
    240                 void postvisit( const ast::EnumInstType * ) {
    241                         if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    242                                 result = 1;
    243                         } else if ( auto bt = dynamic_cast< const ast::BasicType * >( dst ) ) {
    244                                 if ( bt->kind == ast::BasicType::SignedInt ) {
    245                                         result = 0;
    246                                 } else {
    247                                         result = 1;
    248                                 }
    249                         } else {
    250                                 result = objectCast( dst, env, symtab );
    251                         }
    252                 }
    253 
    254                 void postvisit( const ast::TraitInstType * ) {}
    255 
    256                 void postvisit( const ast::TypeInstType * inst ) {
    257                         // check trait and destination type are both object or both function
    258                         result = objectCast( inst, env, symtab ) == objectCast( dst, env, symtab ) ? 1 : -1;
    259                 }
    260 
    261                 void postvisit( const ast::TupleType * ) {
    262                         result = objectCast( dst, env, symtab );
    263                 }
    264 
    265                 void postvisit( const ast::VarArgsType * ) {
    266                         result = objectCast( dst, env, symtab );
    267                 }
    268 
    269                 void postvisit( const ast::ZeroType * ) {
    270                         result = objectCast( dst, env, symtab );
    271                 }
    272 
    273                 void postvisit( const ast::OneType * ) {
    274                         result = objectCast( dst, env, symtab );
    275                 }
    276 
    277         };
    278 } // anonymous namespace
    279 
    280 int ptrsCastable(
    281         const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
    282         const ast::TypeEnvironment & env
    283 ) {
    284         if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
    285                 if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) {
    286                         return ptrsAssignable( src, eqvClass->bound, env );
    287                 }
    288         }
    289 
    290         if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
    291                 return objectCast( src, env, symtab );
    292         } else {
    293                 ast::Pass< PtrsCastable_new > ptrs{ dst, env, symtab };
    294                 src->accept( ptrs );
    295                 return ptrs.pass.result;
    296         }
    297 }
    298 
    299163} // namespace ResolvExpr
    300164
Note: See TracChangeset for help on using the changeset viewer.