Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    rac9ca967 rb6fe7e6  
    3838#include "SynTree/TypeSubstitution.h"
    3939#include "SymTab/Validate.h"
    40 #include "Tuples/Tuples.h"
     40#include "Tuples/TupleAssignment.h"
     41#include "Tuples/NameMatcher.h"
    4142#include "Common/utility.h"
    4243#include "InitTweak/InitTweak.h"
     
    6364        }
    6465
    65         Cost sumCost( const AltList &in ) {
    66                 Cost total;
    67                 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
    68                         total += i->cost;
    69                 }
    70                 return total;
    71         }
    72 
    7366        namespace {
    7467                void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
     
    8376                                out.push_back( i->expr->clone() );
    8477                        }
     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;
    8586                }
    8687
     
    100101                                PruneStruct current( candidate );
    101102                                std::string mangleName;
    102                                 {
    103                                         Type * newType = candidate->expr->get_result()->clone();
     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();
    104105                                        candidate->env.apply( newType );
    105                                         mangleName = SymTab::Mangler::mangle( newType );
     106                                        mangleName += SymTab::Mangler::mangle( newType );
    106107                                        delete newType;
    107108                                }
     
    132133                                if ( ! target->second.isAmbiguous ) {
    133134                                        Alternative &alt = *target->second.candidate;
    134                                         alt.env.applyFree( alt.expr->get_result() );
     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                                        }
    135138                                        *out++ = alt;
    136139                                }
    137140                        }
     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                        }
    138169                }
    139170
    140171                void renameTypes( Expression *expr ) {
    141                         expr->get_result()->accept( global_renamer );
     172                        for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
     173                                (*i)->accept( global_renamer );
     174                        }
    142175                }
    143176        }
     
    171204                for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
    172205                        if ( adjust ) {
    173                                 adjustExprType( i->expr->get_result(), i->env, indexer );
     206                                adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
    174207                        }
    175208                }
     
    208241
    209242        template< typename StructOrUnionType >
    210         void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
    211                 // member must be either a tuple expression or a name expr
    212                 if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) {
    213                         const std::string & name = nameExpr->get_name();
    214                         std::list< Declaration* > members;
    215                         aggInst->lookup( name, members );
    216                         for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    217                                 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    218                                         alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
    219                                         renameTypes( alternatives.back().expr );
    220                                 } else {
    221                                         assert( false );
    222                                 }
    223                         }
    224                 } else if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( member ) ) {
    225                         assert( false );
    226                 } else {
    227                         // xxx - temporary
    228                         std::cerr << member << std::endl;
    229                         assertf( false, "reached unexpected case of addAggMembers" );
     243        void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) {
     244                std::list< Declaration* > members;
     245                aggInst->lookup( name, members );
     246                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
     247                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
     248                                alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
     249                                renameTypes( alternatives.back().expr );
     250                        } else {
     251                                assert( false );
     252                        }
    230253                }
    231254        }
     
    236259
    237260        Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
    238                 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
    239                 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    240                 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
     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 );
    241267
    242268                Cost convCost( 0, 0, 0 );
     
    244270                std::list< DeclarationWithType* >::iterator formal = formals.begin();
    245271                std::list< Expression* >& actuals = appExpr->get_args();
    246 
    247                 std::list< Type * > formalTypes;
    248                 std::list< Type * >::iterator formalType = formalTypes.end();
    249 
    250272                for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    251 
    252273                        PRINT(
    253274                                std::cerr << "actual expression:" << std::endl;
    254275                                (*actualExpr)->print( std::cerr, 8 );
    255276                                std::cerr << "--- results are" << std::endl;
    256                                 (*actualExpr)->get_result()->print( std::cerr, 8 );
     277                                printAll( (*actualExpr)->get_results(), std::cerr, 8 );
    257278                        )
    258279                        std::list< DeclarationWithType* >::iterator startFormal = formal;
    259280                        Cost actualCost;
    260                         std::list< Type * > flatActualTypes;
    261                         flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) );
    262                         for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) {
    263 
    264 
    265                                 // tuple handling code
    266                                 if ( formalType == formalTypes.end() ) {
    267                                         // the type of the formal parameter may be a tuple type. To make this easier to work with,
    268                                         // flatten the tuple type and traverse the resulting list of types, incrementing the formal
    269                                         // iterator once its types have been extracted. Once a particular formal parameter's type has
    270                                         // been exhausted load the next formal parameter's type.
    271                                         if ( formal == formals.end() ) {
    272                                                 if ( function->get_isVarArgs() ) {
    273                                                         convCost += Cost( 1, 0, 0 );
    274                                                         break;
    275                                                 } else {
    276                                                         return Cost::infinity;
    277                                                 }
     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;
    278288                                        }
    279                                         formalTypes.clear();
    280                                         flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
    281                                         formalType = formalTypes.begin();
    282                                         ++formal;
    283289                                }
    284 
    285290                                PRINT(
    286291                                        std::cerr << std::endl << "converting ";
    287                                         (*actualType)->print( std::cerr, 8 );
     292                                        (*actual)->print( std::cerr, 8 );
    288293                                        std::cerr << std::endl << " to ";
    289294                                        (*formal)->get_type()->print( std::cerr, 8 );
    290295                                )
    291                                 Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
     296                                Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
    292297                                PRINT(
    293298                                        std::cerr << std::endl << "cost is" << newCost << std::endl;
     
    300305                                actualCost += newCost;
    301306
    302                                 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
    303 
    304                                 formalType++;
     307                                convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
     308
     309                                formal++;
    305310                        }
    306311                        if ( actualCost != Cost( 0, 0, 0 ) ) {
     
    351356        /// Adds type variables to the open variable set and marks their assertions
    352357        void makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions ) {
    353                 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
     358                for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    354359                        unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind();
    355360                        for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
     
    360365        }
    361366
    362         /// instantiate a single argument by matching actuals from [actualIt, actualEnd) against formalType,
    363         /// producing expression(s) in out and their total cost in cost.
    364         template< typename AltIterator, typename OutputIterator >
    365         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 ) {
    366                 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) {
    367                         // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType
    368                         TupleExpr * tupleExpr = new TupleExpr();
    369                         for ( Type * type : *tupleType ) {
    370                                 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) {
    371                                         delete tupleExpr;
    372                                         return false;
    373                                 }
    374                         }
    375                         tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) );
    376                         *out++ = tupleExpr;
    377                 } else if ( actualIt != actualEnd ) {
    378                         // both actualType and formalType are atomic (non-tuple) types - if they unify
    379                         // then accept actual as an argument, otherwise return false (fail to instantiate argument)
    380                         Expression * actual = actualIt->expr;
    381                         Type * actualType = actual->get_result();
    382                         PRINT(
    383                                 std::cerr << "formal type is ";
    384                                 formalType->print( std::cerr );
    385                                 std::cerr << std::endl << "actual type is ";
    386                                 actualType->print( std::cerr );
    387                                 std::cerr << std::endl;
    388                         )
    389                         if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    390                                 return false;
    391                         }
    392                         // move the expression from the alternative to the output iterator
    393                         *out++ = actual;
    394                         actualIt->expr = nullptr;
    395                         cost += actualIt->cost;
    396                         ++actualIt;
    397                 } else {
    398                         // End of actuals - Handle default values
    399                         if ( SingleInit *si = dynamic_cast<SingleInit *>( defaultValue )) {
    400                                 // so far, only constant expressions are accepted as default values
    401                                 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) {
    402                                         if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) {
    403                                                 if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    404                                                         // xxx - Don't know if this is right
    405                                                         *out++ = cnstexpr->clone();
    406                                                         return true;
    407                                                 } // if
    408                                         } // if
    409                                 } // if
    410                         } // if
    411                         return false;
    412                 } // if
    413                 return true;
    414         }
    415 
    416         bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ) {
     367        bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) {
    417368                simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
    418369                // make sure we don't widen any existing bindings
     
    422373                resultEnv.extractOpenVars( openVars );
    423374
    424                 // flatten actuals so that each actual has an atomic (non-tuple) type
    425                 AltList exploded;
    426                 Tuples::explode( actuals, back_inserter( exploded ) );
    427 
    428                 AltList::iterator actualExpr = exploded.begin();
    429                 AltList::iterator actualEnd = exploded.end();
    430                 for ( DeclarationWithType * formal : formals ) {
    431                         // match flattened actuals with formal parameters - actuals will be grouped to match
    432                         // with formals as appropriate
    433                         Cost cost;
    434                         std::list< Expression * > newExprs;
    435                         ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal );
    436                         if ( ! instantiateArgument( obj->get_type(), obj->get_init(), actualExpr, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( newExprs ) ) ) {
    437                                 deleteAll( newExprs );
    438                                 return false;
    439                         }
    440                         // success - produce argument as a new alternative
    441                         assert( newExprs.size() == 1 );
    442                         out.push_back( Alternative( newExprs.front(), resultEnv, cost ) );
    443                 }
    444                 if ( actualExpr != actualEnd ) {
    445                         // there are still actuals remaining, but we've run out of formal parameters to match against
    446                         // this is okay only if the function is variadic
    447                         if ( ! isVarArgs ) {
    448                                 return false;
    449                         }
    450                         out.splice( out.end(), exploded, actualExpr, actualEnd );
     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;
    451416                }
    452417                return true;
     
    535500                                //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
    536501                                Expression *varExpr = new VariableExpr( candDecl );
    537                                 delete varExpr->get_result();
    538                                 varExpr->set_result( adjType->clone() );
     502                                deleteAll( varExpr->get_results() );
     503                                varExpr->get_results().clear();
     504                                varExpr->get_results().push_front( adjType->clone() );
    539505                                PRINT(
    540506                                        std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
     
    579545
    580546        template< typename OutputIterator >
    581         void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ) {
     547        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) {
    582548                OpenVarSet openVars;
    583549                AssertionSet resultNeed, resultHave;
    584550                TypeEnvironment resultEnv;
    585551                makeUnifiableVars( funcType, openVars, resultNeed );
    586                 AltList instantiatedActuals; // filled by instantiate function
    587                 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) {
     552                if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) {
    588553                        ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
    589                         Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals ) );
    590                         makeExprList( instantiatedActuals, appExpr->get_args() );
     554                        Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) );
     555                        makeExprList( actualAlt, appExpr->get_args() );
    591556                        PRINT(
    592557                                std::cerr << "need assertions:" << std::endl;
     
    609574                                PointerType pt( Type::Qualifiers(), v.clone() );
    610575                                UntypedExpr *vexpr = untypedExpr->clone();
    611                                 vexpr->set_result( pt.clone() );
     576                                vexpr->get_results().push_front( pt.clone() );
    612577                                alternatives.push_back( Alternative( vexpr, env, Cost()) );
    613578                                return;
     
    622587                combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
    623588
    624                 // take care of possible tuple assignments
    625                 // if not tuple assignment, assignment is taken care of as a normal function call
    626                 Tuples::handleTupleAssignment( *this, untypedExpr, possibilities );
     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 ...
    627594
    628595                AltList candidates;
     
    637604                                // check if the type is pointer to function
    638605                                PointerType *pointer;
    639                                 if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {
     606                                if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
    640607                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    641608                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    673640                                                // check if the type is pointer to function
    674641                                                PointerType *pointer;
    675                                                 if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) {
     642                                                if ( funcOp->expr->get_results().size() == 1
     643                                                        && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
    676644                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    677645                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    697665
    698666                        PRINT(
    699                                 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( withFunc->expr );
    700                                 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    701                                 FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
     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 );
    702673                                std::cerr << "Case +++++++++++++" << std::endl;
    703674                                std::cerr << "formals are:" << std::endl;
     
    721692
    722693        bool isLvalue( Expression *expr ) {
    723                 // xxx - recurse into tuples?
    724                 return expr->has_result() && expr->get_result()->get_isLvalue();
     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;
    725698        }
    726699
     
    736709
    737710        void AlternativeFinder::visit( CastExpr *castExpr ) {
    738                 Type *& toType = castExpr->get_result();
    739                 toType = resolveTypeof( toType, indexer );
    740                 SymTab::validateType( toType, &indexer );
    741                 adjustExprType( toType, env, indexer );
     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
    742716
    743717                AlternativeFinder finder( indexer, env );
     
    753727                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    754728                        // to.
    755                         int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
     729                        int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
    756730                        if ( discardedValues < 0 ) continue;
    757                         // xxx - may need to go into tuple types and extract relavent types and use unifyList
     731                        std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin();
     732                        std::advance( candidate_end, castExpr->get_results().size() );
    758733                        // unification run for side-effects
    759                         unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
    760                         Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env );
     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 );
    761740                        if ( thisCost != Cost::infinity ) {
    762741                                // count one safe conversion for each value that is thrown away
     
    781760
    782761                for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
    783                         if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) {
    784                                 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    785                         } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) {
    786                                 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
     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
    787768                        } // if
    788769                } // for
     
    810791                        renameTypes( alternatives.back().expr );
    811792                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
    812                                 NameExpr nameExpr( "" );
    813                                 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
     793                                addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
    814794                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
    815                                 NameExpr nameExpr( "" );
    816                                 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
     795                                addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
    817796                        } // if
    818797                } // for
     
    915894                        alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
    916895                        for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
    917                                 alternatives.back().expr->set_result( (*i)->get_type()->clone() );
     896                                alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() );
    918897                        } // for
    919898                } // if
     
    938917                                                        finder.find( attrExpr->get_expr() );
    939918                                                        for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    940                                                                 if ( choice->expr->get_result()->size() == 1 ) {
    941                                                                         resolveAttr(*i, function, choice->expr->get_result(), choice->env );
     919                                                                if ( choice->expr->get_results().size() == 1 ) {
     920                                                                        resolveAttr(*i, function, choice->expr->get_results().front(), choice->env );
    942921                                                                } // fi
    943922                                                        } // for
     
    981960                                        AssertionSet needAssertions, haveAssertions;
    982961                                        Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost );
    983                                         Type* commonType;
    984                                         if ( unify( second->expr->get_result(), third->expr->get_result(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
     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 ) ) {
    985964                                                ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
    986                                                 newExpr->set_result( commonType ? commonType : second->expr->get_result()->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
    987974                                                newAlt.expr = newExpr;
    988975                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     
    1012999                        TupleExpr *newExpr = new TupleExpr;
    10131000                        makeExprList( *i, newExpr->get_exprs() );
    1014                         newExpr->set_result( Tuples::makeTupleType( 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
    10151006
    10161007                        TypeEnvironment compositeEnv;
     
    10331024                }
    10341025        }
    1035 
    1036         void AlternativeFinder::visit( TupleIndexExpr *tupleExpr ) {
    1037                 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
    1038         }
    1039 
    1040         void AlternativeFinder::visit( TupleAssignExpr *tupleAssignExpr ) {
    1041                 alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );
    1042         }
    10431026} // namespace ResolvExpr
    10441027
Note: See TracChangeset for help on using the changeset viewer.