Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    rb6fe7e6 r77971f6  
    3838#include "SynTree/TypeSubstitution.h"
    3939#include "SymTab/Validate.h"
    40 #include "Tuples/TupleAssignment.h"
    41 #include "Tuples/NameMatcher.h"
     40#include "Tuples/Tuples.h"
    4241#include "Common/utility.h"
    4342#include "InitTweak/InitTweak.h"
     43#include "InitTweak/GenInit.h"
    4444#include "ResolveTypeof.h"
    4545
     
    6464        }
    6565
     66        Cost sumCost( const AltList &in ) {
     67                Cost total;
     68                for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
     69                        total += i->cost;
     70                }
     71                return total;
     72        }
     73
    6674        namespace {
    6775                void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
     
    7684                                out.push_back( i->expr->clone() );
    7785                        }
    78                 }
    79 
    80                 Cost sumCost( const AltList &in ) {
    81                         Cost total;
    82                         for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
    83                                 total += i->cost;
    84                         }
    85                         return total;
    8686                }
    8787
     
    101101                                PruneStruct current( candidate );
    102102                                std::string mangleName;
    103                                 for ( std::list< Type* >::const_iterator retType = candidate->expr->get_results().begin(); retType != candidate->expr->get_results().end(); ++retType ) {
    104                                         Type *newType = (*retType)->clone();
     103                                {
     104                                        Type * newType = candidate->expr->get_result()->clone();
    105105                                        candidate->env.apply( newType );
    106                                         mangleName += SymTab::Mangler::mangle( newType );
     106                                        mangleName = SymTab::Mangler::mangle( newType );
    107107                                        delete newType;
    108108                                }
     
    133133                                if ( ! target->second.isAmbiguous ) {
    134134                                        Alternative &alt = *target->second.candidate;
    135                                         for ( std::list< Type* >::iterator result = alt.expr->get_results().begin(); result != alt.expr->get_results().end(); ++result ) {
    136                                                 alt.env.applyFree( *result );
    137                                         }
     135                                        alt.env.applyFree( alt.expr->get_result() );
    138136                                        *out++ = alt;
    139137                                }
    140138                        }
    141 
    142                 }
    143 
    144                 template< typename InputIterator, typename OutputIterator >
    145                 void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
    146                         AltList alternatives;
    147 
    148                         // select the alternatives that have the minimum parameter cost
    149                         Cost minCost = Cost::infinity;
    150                         for ( AltList::iterator i = begin; i != end; ++i ) {
    151                                 if ( i->cost < minCost ) {
    152                                         minCost = i->cost;
    153                                         i->cost = i->cvtCost;
    154                                         alternatives.clear();
    155                                         alternatives.push_back( *i );
    156                                 } else if ( i->cost == minCost ) {
    157                                         i->cost = i->cvtCost;
    158                                         alternatives.push_back( *i );
    159                                 }
    160                         }
    161                         std::copy( alternatives.begin(), alternatives.end(), out );
    162                 }
    163 
    164                 template< typename InputIterator >
    165                 void simpleCombineEnvironments( InputIterator begin, InputIterator end, TypeEnvironment &result ) {
    166                         while ( begin != end ) {
    167                                 result.simpleCombine( (*begin++).env );
    168                         }
    169139                }
    170140
    171141                void renameTypes( Expression *expr ) {
    172                         for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
    173                                 (*i)->accept( global_renamer );
    174                         }
     142                        expr->get_result()->accept( global_renamer );
    175143                }
    176144        }
     
    204172                for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
    205173                        if ( adjust ) {
    206                                 adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
     174                                adjustExprType( i->expr->get_result(), i->env, indexer );
    207175                        }
    208176                }
     
    240208        }
    241209
     210        // std::unordered_map< Expression *, UniqueExpr * > ;
     211
    242212        template< typename StructOrUnionType >
    243         void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) {
     213        void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
     214                // by this point, member must be a name expr
     215                NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member );
     216                const std::string & name = nameExpr->get_name();
    244217                std::list< Declaration* > members;
    245218                aggInst->lookup( name, members );
     
    254227        }
    255228
     229        void AlternativeFinder::addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
     230                if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
     231                        // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
     232                        // xxx - this should be improved by memoizing the value of constant exprs
     233                        // during parsing and reusing that information here.
     234                        std::stringstream ss( constantExpr->get_constant()->get_value() );
     235                        int val;
     236                        std::string tmp;
     237                        if ( ss >> val && ! (ss >> tmp) ) {
     238                                if ( val >= 0 && (unsigned int)val < tupleType->size() ) {
     239                                        alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
     240                                } // if
     241                        } // if
     242                } // if
     243        }
     244
    256245        void AlternativeFinder::visit( ApplicationExpr *applicationExpr ) {
    257246                alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
     
    259248
    260249        Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
    261                 ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( alt.expr );
    262                 assert( appExpr );
    263                 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
    264                 assert( pointer );
    265                 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
    266                 assert( function );
     250                ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
     251                PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
     252                FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
    267253
    268254                Cost convCost( 0, 0, 0 );
     
    270256                std::list< DeclarationWithType* >::iterator formal = formals.begin();
    271257                std::list< Expression* >& actuals = appExpr->get_args();
     258
     259                std::list< Type * > formalTypes;
     260                std::list< Type * >::iterator formalType = formalTypes.end();
     261
    272262                for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
     263
    273264                        PRINT(
    274265                                std::cerr << "actual expression:" << std::endl;
    275266                                (*actualExpr)->print( std::cerr, 8 );
    276267                                std::cerr << "--- results are" << std::endl;
    277                                 printAll( (*actualExpr)->get_results(), std::cerr, 8 );
     268                                (*actualExpr)->get_result()->print( std::cerr, 8 );
    278269                        )
    279270                        std::list< DeclarationWithType* >::iterator startFormal = formal;
    280271                        Cost actualCost;
    281                         for ( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) {
    282                                 if ( formal == formals.end() ) {
    283                                         if ( function->get_isVarArgs() ) {
    284                                                 convCost += Cost( 1, 0, 0 );
    285                                                 break;
    286                                         } else {
    287                                                 return Cost::infinity;
     272                        std::list< Type * > flatActualTypes;
     273                        flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) );
     274                        for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) {
     275
     276
     277                                // tuple handling code
     278                                if ( formalType == formalTypes.end() ) {
     279                                        // the type of the formal parameter may be a tuple type. To make this easier to work with,
     280                                        // flatten the tuple type and traverse the resulting list of types, incrementing the formal
     281                                        // iterator once its types have been extracted. Once a particular formal parameter's type has
     282                                        // been exhausted load the next formal parameter's type.
     283                                        if ( formal == formals.end() ) {
     284                                                if ( function->get_isVarArgs() ) {
     285                                                        convCost += Cost( 1, 0, 0 );
     286                                                        break;
     287                                                } else {
     288                                                        return Cost::infinity;
     289                                                }
    288290                                        }
     291                                        formalTypes.clear();
     292                                        flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
     293                                        formalType = formalTypes.begin();
     294                                        ++formal;
    289295                                }
     296
    290297                                PRINT(
    291298                                        std::cerr << std::endl << "converting ";
    292                                         (*actual)->print( std::cerr, 8 );
     299                                        (*actualType)->print( std::cerr, 8 );
    293300                                        std::cerr << std::endl << " to ";
    294301                                        (*formal)->get_type()->print( std::cerr, 8 );
    295302                                )
    296                                 Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
     303                                Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
    297304                                PRINT(
    298305                                        std::cerr << std::endl << "cost is" << newCost << std::endl;
     
    305312                                actualCost += newCost;
    306313
    307                                 convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
    308 
    309                                 formal++;
     314                                convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
     315
     316                                formalType++;
    310317                        }
    311318                        if ( actualCost != Cost( 0, 0, 0 ) ) {
     
    356363        /// Adds type variables to the open variable set and marks their assertions
    357364        void makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions ) {
    358                 for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
     365                for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    359366                        unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind();
    360367                        for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
     
    365372        }
    366373
    367         bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) {
     374        /// instantiate a single argument by matching actuals from [actualIt, actualEnd) against formalType,
     375        /// producing expression(s) in out and their total cost in cost.
     376        template< typename AltIterator, typename OutputIterator >
     377        bool instantiateArgument( Type * formalType, Initializer * defaultValue, AltIterator & actualIt, AltIterator actualEnd, OpenVarSet & openVars, TypeEnvironment & resultEnv, AssertionSet & resultNeed, AssertionSet & resultHave, const SymTab::Indexer & indexer, Cost & cost, OutputIterator out ) {
     378                if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) {
     379                        // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType
     380                        TupleExpr * tupleExpr = new TupleExpr();
     381                        for ( Type * type : *tupleType ) {
     382                                if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) {
     383                                        delete tupleExpr;
     384                                        return false;
     385                                }
     386                        }
     387                        tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) );
     388                        *out++ = tupleExpr;
     389                } else if ( actualIt != actualEnd ) {
     390                        // both actualType and formalType are atomic (non-tuple) types - if they unify
     391                        // then accept actual as an argument, otherwise return false (fail to instantiate argument)
     392                        Expression * actual = actualIt->expr;
     393                        Type * actualType = actual->get_result();
     394                        PRINT(
     395                                std::cerr << "formal type is ";
     396                                formalType->print( std::cerr );
     397                                std::cerr << std::endl << "actual type is ";
     398                                actualType->print( std::cerr );
     399                                std::cerr << std::endl;
     400                        )
     401                        if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
     402                                return false;
     403                        }
     404                        // move the expression from the alternative to the output iterator
     405                        *out++ = actual;
     406                        actualIt->expr = nullptr;
     407                        cost += actualIt->cost;
     408                        ++actualIt;
     409                } else {
     410                        // End of actuals - Handle default values
     411                        if ( SingleInit *si = dynamic_cast<SingleInit *>( defaultValue )) {
     412                                // so far, only constant expressions are accepted as default values
     413                                if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) {
     414                                        if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) {
     415                                                if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
     416                                                        // xxx - Don't know if this is right
     417                                                        *out++ = cnstexpr->clone();
     418                                                        return true;
     419                                                } // if
     420                                        } // if
     421                                } // if
     422                        } // if
     423                        return false;
     424                } // if
     425                return true;
     426        }
     427
     428        bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ) {
    368429                simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
    369430                // make sure we don't widen any existing bindings
     
    373434                resultEnv.extractOpenVars( openVars );
    374435
    375                 /*
    376                   Tuples::NameMatcher matcher( formals );
    377                   try {
    378                   matcher.match( actuals );
    379                   } catch ( Tuples::NoMatch &e ) {
    380                   std::cerr << "Alternative doesn't match: " << e.message << std::endl;
    381                   }
    382                 */
    383                 std::list< DeclarationWithType* >::iterator formal = formals.begin();
    384                 for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    385                         for ( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) {
    386                                 if ( formal == formals.end() ) {
    387                                         return isVarArgs;
    388                                 }
    389                                 PRINT(
    390                                         std::cerr << "formal type is ";
    391                                         (*formal)->get_type()->print( std::cerr );
    392                                         std::cerr << std::endl << "actual type is ";
    393                                         (*actual)->print( std::cerr );
    394                                         std::cerr << std::endl;
    395                                 )
    396                                 if ( ! unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    397                                         return false;
    398                                 }
    399                                 formal++;
    400                         }
    401                 }
    402                 // Handling of default values
    403                 while ( formal != formals.end() ) {
    404                         if ( ObjectDecl *od = dynamic_cast<ObjectDecl *>( *formal ) )
    405                                 if ( SingleInit *si = dynamic_cast<SingleInit *>( od->get_init() ))
    406                                         // so far, only constant expressions are accepted as default values
    407                                         if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) )
    408                                                 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) )
    409                                                         if ( unify( (*formal)->get_type(), cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    410                                                                 // XXX Don't know if this is right
    411                                                                 actuals.push_back( Alternative( cnstexpr->clone(), env, Cost::zero ) );
    412                                                                 formal++;
    413                                                                 if ( formal == formals.end()) break;
    414                                                         }
    415                         return false;
     436                // flatten actuals so that each actual has an atomic (non-tuple) type
     437                AltList exploded;
     438                Tuples::explode( actuals, indexer, back_inserter( exploded ) );
     439
     440                AltList::iterator actualExpr = exploded.begin();
     441                AltList::iterator actualEnd = exploded.end();
     442                for ( DeclarationWithType * formal : formals ) {
     443                        // match flattened actuals with formal parameters - actuals will be grouped to match
     444                        // with formals as appropriate
     445                        Cost cost;
     446                        std::list< Expression * > newExprs;
     447                        ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal );
     448                        if ( ! instantiateArgument( obj->get_type(), obj->get_init(), actualExpr, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( newExprs ) ) ) {
     449                                deleteAll( newExprs );
     450                                return false;
     451                        }
     452                        // success - produce argument as a new alternative
     453                        assert( newExprs.size() == 1 );
     454                        out.push_back( Alternative( newExprs.front(), resultEnv, cost ) );
     455                }
     456                if ( actualExpr != actualEnd ) {
     457                        // there are still actuals remaining, but we've run out of formal parameters to match against
     458                        // this is okay only if the function is variadic
     459                        if ( ! isVarArgs ) {
     460                                return false;
     461                        }
     462                        out.splice( out.end(), exploded, actualExpr, actualEnd );
    416463                }
    417464                return true;
     
    500547                                //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
    501548                                Expression *varExpr = new VariableExpr( candDecl );
    502                                 deleteAll( varExpr->get_results() );
    503                                 varExpr->get_results().clear();
    504                                 varExpr->get_results().push_front( adjType->clone() );
     549                                delete varExpr->get_result();
     550                                varExpr->set_result( adjType->clone() );
    505551                                PRINT(
    506552                                        std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
     
    545591
    546592        template< typename OutputIterator >
    547         void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) {
     593        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ) {
    548594                OpenVarSet openVars;
    549595                AssertionSet resultNeed, resultHave;
    550596                TypeEnvironment resultEnv;
    551597                makeUnifiableVars( funcType, openVars, resultNeed );
    552                 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) {
     598                AltList instantiatedActuals; // filled by instantiate function
     599                if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) {
    553600                        ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
    554                         Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) );
    555                         makeExprList( actualAlt, appExpr->get_args() );
     601                        Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals ) );
     602                        makeExprList( instantiatedActuals, appExpr->get_args() );
    556603                        PRINT(
    557604                                std::cerr << "need assertions:" << std::endl;
     
    574621                                PointerType pt( Type::Qualifiers(), v.clone() );
    575622                                UntypedExpr *vexpr = untypedExpr->clone();
    576                                 vexpr->get_results().push_front( pt.clone() );
     623                                vexpr->set_result( pt.clone() );
    577624                                alternatives.push_back( Alternative( vexpr, env, Cost()) );
    578625                                return;
     
    587634                combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
    588635
    589                 Tuples::TupleAssignSpotter tassign( this );
    590                 if ( tassign.isTupleAssignment( untypedExpr, possibilities ) ) {
    591                         // take care of possible tuple assignments, or discard expression
    592                         return;
    593                 } // else ...
     636                // take care of possible tuple assignments
     637                // if not tuple assignment, assignment is taken care of as a normal function call
     638                Tuples::handleTupleAssignment( *this, untypedExpr, possibilities );
    594639
    595640                AltList candidates;
     
    604649                                // check if the type is pointer to function
    605650                                PointerType *pointer;
    606                                 if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
     651                                if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {
    607652                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    608653                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    640685                                                // check if the type is pointer to function
    641686                                                PointerType *pointer;
    642                                                 if ( funcOp->expr->get_results().size() == 1
    643                                                         && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
     687                                                if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) {
    644688                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    645689                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    665709
    666710                        PRINT(
    667                                 ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr );
    668                                 assert( appExpr );
    669                                 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
    670                                 assert( pointer );
    671                                 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
    672                                 assert( function );
     711                                ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( withFunc->expr );
     712                                PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
     713                                FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
    673714                                std::cerr << "Case +++++++++++++" << std::endl;
    674715                                std::cerr << "formals are:" << std::endl;
     
    692733
    693734        bool isLvalue( Expression *expr ) {
    694                 for ( std::list< Type* >::const_iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
    695                         if ( !(*i)->get_isLvalue() ) return false;
    696                 } // for
    697                 return true;
     735                // xxx - recurse into tuples?
     736                return expr->has_result() && expr->get_result()->get_isLvalue();
    698737        }
    699738
     
    709748
    710749        void AlternativeFinder::visit( CastExpr *castExpr ) {
    711                 for ( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) {
    712                         *i = resolveTypeof( *i, indexer );
    713                         SymTab::validateType( *i, &indexer );
    714                         adjustExprType( *i, env, indexer );
    715                 } // for
     750                Type *& toType = castExpr->get_result();
     751                toType = resolveTypeof( toType, indexer );
     752                SymTab::validateType( toType, &indexer );
     753                adjustExprType( toType, env, indexer );
    716754
    717755                AlternativeFinder finder( indexer, env );
     
    727765                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    728766                        // to.
    729                         int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
     767                        int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
    730768                        if ( discardedValues < 0 ) continue;
    731                         std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin();
    732                         std::advance( candidate_end, castExpr->get_results().size() );
     769                        // xxx - may need to go into tuple types and extract relavent types and use unifyList
    733770                        // unification run for side-effects
    734                         unifyList( castExpr->get_results().begin(), castExpr->get_results().end(),
    735                                            (*i).expr->get_results().begin(), candidate_end,
    736                                    i->env, needAssertions, haveAssertions, openVars, indexer );
    737                         Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end,
    738                                                                                   castExpr->get_results().begin(), castExpr->get_results().end(),
    739                                                                                   indexer, i->env );
     771                        unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
     772                        Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env );
    740773                        if ( thisCost != Cost::infinity ) {
    741774                                // count one safe conversion for each value that is thrown away
     
    760793
    761794                for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
    762                         if ( agg->expr->get_results().size() == 1 ) {
    763                                 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) {
    764                                         addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    765                                 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) {
    766                                         addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    767                                 } // if
     795                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) {
     796                                addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
     797                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) {
     798                                addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
     799                        } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( agg->expr->get_result() ) ) {
     800                                addTupleMembers( tupleType, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    768801                        } // if
    769802                } // for
     
    791824                        renameTypes( alternatives.back().expr );
    792825                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
    793                                 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
     826                                NameExpr nameExpr( "" );
     827                                addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
    794828                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
    795                                 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
     829                                NameExpr nameExpr( "" );
     830                                addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
    796831                        } // if
    797832                } // for
     
    894929                        alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
    895930                        for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
    896                                 alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() );
     931                                alternatives.back().expr->set_result( (*i)->get_type()->clone() );
    897932                        } // for
    898933                } // if
     
    917952                                                        finder.find( attrExpr->get_expr() );
    918953                                                        for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    919                                                                 if ( choice->expr->get_results().size() == 1 ) {
    920                                                                         resolveAttr(*i, function, choice->expr->get_results().front(), choice->env );
     954                                                                if ( choice->expr->get_result()->size() == 1 ) {
     955                                                                        resolveAttr(*i, function, choice->expr->get_result(), choice->env );
    921956                                                                } // fi
    922957                                                        } // for
     
    960995                                        AssertionSet needAssertions, haveAssertions;
    961996                                        Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost );
    962                                         std::list< Type* > commonTypes;
    963                                         if ( unifyList( second->expr->get_results().begin(), second->expr->get_results().end(), third->expr->get_results().begin(), third->expr->get_results().end(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
     997                                        Type* commonType;
     998                                        if ( unify( second->expr->get_result(), third->expr->get_result(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    964999                                                ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
    965                                                 std::list< Type* >::const_iterator original = second->expr->get_results().begin();
    966                                                 std::list< Type* >::const_iterator commonType = commonTypes.begin();
    967                                                 for ( ; original != second->expr->get_results().end() && commonType != commonTypes.end(); ++original, ++commonType ) {
    968                                                         if ( *commonType ) {
    969                                                                 newExpr->get_results().push_back( *commonType );
    970                                                         } else {
    971                                                                 newExpr->get_results().push_back( (*original)->clone() );
    972                                                         } // if
    973                                                 } // for
     1000                                                newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() );
    9741001                                                newAlt.expr = newExpr;
    9751002                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     
    9991026                        TupleExpr *newExpr = new TupleExpr;
    10001027                        makeExprList( *i, newExpr->get_exprs() );
    1001                         for ( std::list< Expression* >::const_iterator resultExpr = newExpr->get_exprs().begin(); resultExpr != newExpr->get_exprs().end(); ++resultExpr ) {
    1002                                 for ( std::list< Type* >::const_iterator resultType = (*resultExpr)->get_results().begin(); resultType != (*resultExpr)->get_results().end(); ++resultType ) {
    1003                                         newExpr->get_results().push_back( (*resultType)->clone() );
    1004                                 } // for
    1005                         } // for
     1028                        newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) );
    10061029
    10071030                        TypeEnvironment compositeEnv;
     
    10241047                }
    10251048        }
     1049
     1050        void AlternativeFinder::visit( TupleIndexExpr *tupleExpr ) {
     1051                alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
     1052        }
     1053
     1054        void AlternativeFinder::visit( TupleAssignExpr *tupleAssignExpr ) {
     1055                alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );
     1056        }
     1057
     1058        void AlternativeFinder::visit( UniqueExpr *unqExpr ) {
     1059                // this won't work because the unqExprs wont share an expression anymore...
     1060                AlternativeFinder finder( indexer, env );
     1061                finder.findWithAdjustment( unqExpr->get_expr() );
     1062                for ( Alternative & alt : finder.alternatives ) {
     1063                        // xxx - attach a resolved ConstructorInit node?
     1064                        // xxx - is it possible to make the objDecl's type const?
     1065                        static UniqueName tempNamer( "_unq_expr_" );
     1066                        ObjectDecl * objDecl = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, alt.expr->get_result()->clone(), nullptr );
     1067                        // must be done on two lines because genCtorInit accesses objDecl's fields
     1068                        objDecl->set_init( InitTweak::genCtorInit( objDecl ) );
     1069
     1070                        UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() );
     1071                        newUnqExpr->set_object( objDecl );
     1072
     1073                        resolveObject( indexer, objDecl );
     1074
     1075                        alternatives.push_back( Alternative( newUnqExpr, env, Cost::zero ) );
     1076                }
     1077        }
     1078
    10261079} // namespace ResolvExpr
    10271080
Note: See TracChangeset for help on using the changeset viewer.