Changeset 07d867b


Ignore:
Timestamp:
Aug 10, 2020, 7:45:18 PM (16 months ago)
Author:
Fangren Yu <f37yu@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast, new-ast-unique-expr
Children:
22f94a4
Parents:
ba662b9
Message:

attempt to fix inferparams

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    rba662b9 r07d867b  
    588588                assert( tgtResnSlots.empty() );
    589589
    590                 if ( srcInferred.mode == ast::Expr::InferUnion::Params ) {
     590                if ( srcInferred.data.inferParams ) {
    591591                        const ast::InferredParams &srcParams = srcInferred.inferParams();
    592592                        for (auto & srcParam : srcParams) {
    593593                                auto res = tgtInferParams.emplace(srcParam.first, ParamEntry(
    594594                                        srcParam.second.decl,
    595                                         get<Declaration>().accept1(srcParam.second.declptr)->clone(),
    596                                         get<Type>().accept1(srcParam.second.actualType),
    597                                         get<Type>().accept1(srcParam.second.formalType),
    598                                         get<Expression>().accept1(srcParam.second.expr)
     595                                        get<Declaration>().accept1(srcParam.second.declptr),
     596                                        get<Type>().accept1(srcParam.second.actualType)->clone(),
     597                                        get<Type>().accept1(srcParam.second.formalType)->clone(),
     598                                        get<Expression>().accept1(srcParam.second.expr)->clone()
    599599                                ));
    600600                                assert(res.second);
    601601                        }
    602                 } else if ( srcInferred.mode == ast::Expr::InferUnion::Slots  ) {
     602                }
     603                if ( srcInferred.data.resnSlots ) {
    603604                        const ast::ResnSlots &srcSlots = srcInferred.resnSlots();
    604605                        for (auto srcSlot : srcSlots) {
     
    20032004
    20042005                assert( oldInferParams.empty() || oldResnSlots.empty() );
    2005                 assert( newInferred.mode == ast::Expr::InferUnion::Empty );
     2006                // assert( newInferred.mode == ast::Expr::InferUnion::Empty );
    20062007
    20072008                if ( !oldInferParams.empty() ) {
  • src/AST/Expr.hpp

    rba662b9 r07d867b  
    4545struct ParamEntry {
    4646        UniqueId decl;
    47         ptr<Decl> declptr;
     47        readonly<Decl> declptr;
    4848        ptr<Type> actualType;
    4949        ptr<Type> formalType;
     
    6565class Expr : public ParseNode {
    6666public:
    67         /// Saves space (~16 bytes) by combining ResnSlots and InferredParams
     67        /*
     68         * NOTE: the union approach is incorrect until the case of
     69         * partial resolution in InferMatcher is eliminated.
     70         * it is reverted to allow unresolved and resolved parameters
     71         * to coexist in an expression node.
     72         */
    6873        struct InferUnion {
     74                // mode is now unused
    6975                enum { Empty, Slots, Params } mode;
    70                 union data_t {
    71                         char def;
    72                         ResnSlots resnSlots;
    73                         InferredParams inferParams;
    74 
    75                         data_t() : def('\0') {}
    76                         ~data_t() {}
     76                struct data_t {
     77                        // char def;
     78                        ResnSlots * resnSlots;
     79                        InferredParams * inferParams;
     80
     81                        data_t(): resnSlots(nullptr), inferParams(nullptr) {}
     82                        data_t(const data_t &other) = delete;
     83                        ~data_t() {
     84                                delete resnSlots;
     85                                delete inferParams;
     86                        }
    7787                } data;
    7888
    7989                /// initializes from other InferUnion
    8090                void init_from( const InferUnion& o ) {
    81                         switch ( o.mode ) {
    82                         case Empty:  return;
    83                         case Slots:  new(&data.resnSlots) ResnSlots{ o.data.resnSlots }; return;
    84                         case Params: new(&data.inferParams) InferredParams{ o.data.inferParams }; return;
     91                        if (o.data.resnSlots) {
     92                                data.resnSlots = new ResnSlots(*o.data.resnSlots);
     93                        }
     94                        if (o.data.inferParams) {
     95                                data.inferParams = new InferredParams(*o.data.inferParams);
    8596                        }
    8697                }
     
    8899                /// initializes from other InferUnion (move semantics)
    89100                void init_from( InferUnion&& o ) {
    90                         switch ( o.mode ) {
    91                         case Empty:  return;
    92                         case Slots:  new(&data.resnSlots) ResnSlots{ std::move(o.data.resnSlots) }; return;
    93                         case Params:
    94                                 new(&data.inferParams) InferredParams{ std::move(o.data.inferParams) }; return;
    95                         }
    96                 }
    97 
    98                 /// clears variant fields
    99                 void reset() {
    100                         switch( mode ) {
    101                         case Empty:  return;
    102                         case Slots:  data.resnSlots.~ResnSlots(); return;
    103                         case Params: data.inferParams.~InferredParams(); return;
    104                         }
     101                        data.resnSlots = o.data.resnSlots;
     102                        data.inferParams = o.data.inferParams;
     103                        o.data.resnSlots = nullptr;
     104                        o.data.inferParams = nullptr;
    105105                }
    106106
     
    110110                InferUnion& operator= ( const InferUnion& ) = delete;
    111111                InferUnion& operator= ( InferUnion&& ) = delete;
    112                 ~InferUnion() { reset(); }
     112
     113                bool hasSlots() const { return data.resnSlots; }
    113114
    114115                ResnSlots& resnSlots() {
    115                         switch (mode) {
    116                         case Empty: new(&data.resnSlots) ResnSlots{}; mode = Slots; [[fallthrough]];
    117                         case Slots: return data.resnSlots;
    118                         case Params: assertf(false, "Cannot return to resnSlots from Params"); abort();
     116                        if (!data.resnSlots) {
     117                                data.resnSlots = new ResnSlots();
    119118                        }
    120                         assertf(false, "unreachable");
     119                        return *data.resnSlots;
    121120                }
    122121
    123122                const ResnSlots& resnSlots() const {
    124                         if (mode == Slots) {
    125                                 return data.resnSlots;
     123                        if (data.resnSlots) {
     124                                return *data.resnSlots;
    126125                        }
    127126                        assertf(false, "Mode was not already resnSlots");
     
    130129
    131130                InferredParams& inferParams() {
    132                         switch (mode) {
    133                         case Slots: data.resnSlots.~ResnSlots(); [[fallthrough]];
    134                         case Empty: new(&data.inferParams) InferredParams{}; mode = Params; [[fallthrough]];
    135                         case Params: return data.inferParams;
     131                        if (!data.inferParams) {
     132                                data.inferParams = new InferredParams();
    136133                        }
    137                         assertf(false, "unreachable");
     134                        return *data.inferParams;
    138135                }
    139136
    140137                const InferredParams& inferParams() const {
    141                         if (mode == Params) {
    142                                 return data.inferParams;
     138                        if (data.inferParams) {
     139                                return *data.inferParams;
    143140                        }
    144141                        assertf(false, "Mode was not already Params");
     
    146143                }
    147144
    148                 void set_inferParams( InferredParams && ps ) {
    149                         switch(mode) {
    150                         case Slots:
    151                                 data.resnSlots.~ResnSlots();
    152                                 [[fallthrough]];
    153                         case Empty:
    154                                 new(&data.inferParams) InferredParams{ std::move( ps ) };
    155                                 mode = Params;
    156                                 break;
    157                         case Params:
    158                                 data.inferParams = std::move( ps );
    159                                 break;
    160                         }
     145                void set_inferParams( InferredParams * ps ) {
     146                        delete data.resnSlots;
     147                        data.resnSlots = nullptr;
     148                        delete data.inferParams;
     149                        data.inferParams = ps;
    161150                }
    162151
     
    164153                /// and the other is in `Params`.
    165154                void splice( InferUnion && o ) {
    166                         if ( o.mode == Empty ) return;
    167                         if ( mode == Empty ) { init_from( o ); return; }
    168                         assert( mode == o.mode && "attempt to splice incompatible InferUnion" );
    169 
    170                         if ( mode == Slots ){
    171                                 data.resnSlots.insert(
    172                                         data.resnSlots.end(), o.data.resnSlots.begin(), o.data.resnSlots.end() );
    173                         } else if ( mode == Params ) {
    174                                 for ( const auto & p : o.data.inferParams ) {
    175                                         data.inferParams[p.first] = std::move(p.second);
     155                        if (o.data.resnSlots) {
     156                                if (data.resnSlots) {
     157                                        data.resnSlots->insert(
     158                                                data.resnSlots->end(), o.data.resnSlots->begin(), o.data.resnSlots->end() );
     159                                        delete o.data.resnSlots;
    176160                                }
    177                         } else assertf(false, "invalid mode");
     161                                else {
     162                                        data.resnSlots = o.data.resnSlots;
     163                                }
     164                                o.data.resnSlots = nullptr;
     165                        }
     166
     167                        if (o.data.inferParams) {
     168                                if (data.inferParams) {
     169                                        for ( const auto & p : *o.data.inferParams ) {
     170                                                (*data.inferParams)[p.first] = std::move(p.second);
     171                                        }
     172                                        delete o.data.inferParams;
     173                                }
     174                                else {
     175                                        data.inferParams = o.data.inferParams;
     176                                }
     177                                o.data.inferParams = nullptr;
     178                        }
    178179                }
    179180        };
  • src/ResolvExpr/SatisfyAssertions.cpp

    rba662b9 r07d867b  
    188188
    189189                                matches.emplace_back(
    190                                         cdata, adjType, std::move( newEnv ), std::move( newNeed ), std::move( have ),
     190                                        cdata, adjType, std::move( newEnv ), std::move( have ), std::move( newNeed ),
    191191                                        std::move( newOpen ), crntResnSlot );
    192192                        }
     
    231231                const ast::Expr * postvisit( const ast::Expr * expr ) {
    232232                        // Skip if no slots to find
    233                         if ( expr->inferred.mode != ast::Expr::InferUnion::Slots ) return expr;
    234 
     233                        if ( !expr->inferred.hasSlots() ) return expr;
     234                        // if ( expr->inferred.mode != ast::Expr::InferUnion::Slots ) return expr;
     235                        std::vector<UniqueId> missingSlots;
    235236                        // find inferred parameters for resolution slots
    236                         ast::InferredParams newInferred;
     237                        ast::InferredParams * newInferred = new ast::InferredParams();
    237238                        for ( UniqueId slot : expr->inferred.resnSlots() ) {
    238239                                // fail if no matching assertions found
     
    240241                                if ( it == inferred.end() ) {
    241242                                        std::cerr << "missing assertion " << slot << std::endl;
     243                                        missingSlots.push_back(slot);
    242244                                        continue;
    243245                                }
     
    247249                                        // recurse on inferParams of resolved expressions
    248250                                        entry.second.expr = postvisit( entry.second.expr );
    249                                         auto res = newInferred.emplace( entry );
     251                                        auto res = newInferred->emplace( entry );
    250252                                        assert( res.second && "all assertions newly placed" );
    251253                                }
     
    253255
    254256                        ast::Expr * ret = mutate( expr );
    255                         ret->inferred.set_inferParams( std::move( newInferred ) );
     257                        ret->inferred.set_inferParams( newInferred );
     258                        if (!missingSlots.empty()) ret->inferred.resnSlots() = missingSlots;
    256259                        return ret;
    257260                }
  • src/SynTree/ApplicationExpr.cc

    rba662b9 r07d867b  
    3434
    3535ParamEntry::ParamEntry( const ParamEntry &other ) :
    36                 decl( other.decl ), declptr( maybeClone( other.declptr ) ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) ) {
     36                decl( other.decl ), declptr( other.declptr ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) ) {
    3737}
    3838
    3939ParamEntry::~ParamEntry() {
    40         delete declptr;
     40        // delete declptr;
    4141        delete actualType;
    4242        delete formalType;
Note: See TracChangeset for help on using the changeset viewer.