Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    rb6fe7e6 rac9ca96  
    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"
     
    6463        }
    6564
     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
    6673        namespace {
    6774                void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
     
    7683                                out.push_back( i->expr->clone() );
    7784                        }
    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;
    8685                }
    8786
     
    101100                                PruneStruct current( candidate );
    102101                                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();
     102                                {
     103                                        Type * newType = candidate->expr->get_result()->clone();
    105104                                        candidate->env.apply( newType );
    106                                         mangleName += SymTab::Mangler::mangle( newType );
     105                                        mangleName = SymTab::Mangler::mangle( newType );
    107106                                        delete newType;
    108107                                }
     
    133132                                if ( ! target->second.isAmbiguous ) {
    134133                                        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                                         }
     134                                        alt.env.applyFree( alt.expr->get_result() );
    138135                                        *out++ = alt;
    139136                                }
    140137                        }
    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                         }
    169138                }
    170139
    171140                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                         }
     141                        expr->get_result()->accept( global_renamer );
    175142                }
    176143        }
     
    204171                for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
    205172                        if ( adjust ) {
    206                                 adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
     173                                adjustExprType( i->expr->get_result(), i->env, indexer );
    207174                        }
    208175                }
     
    241208
    242209        template< typename StructOrUnionType >
    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                         }
     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" );
    253230                }
    254231        }
     
    259236
    260237        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 );
     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() );
    267241
    268242                Cost convCost( 0, 0, 0 );
     
    270244                std::list< DeclarationWithType* >::iterator formal = formals.begin();
    271245                std::list< Expression* >& actuals = appExpr->get_args();
     246
     247                std::list< Type * > formalTypes;
     248                std::list< Type * >::iterator formalType = formalTypes.end();
     249
    272250                for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
     251
    273252                        PRINT(
    274253                                std::cerr << "actual expression:" << std::endl;
    275254                                (*actualExpr)->print( std::cerr, 8 );
    276255                                std::cerr << "--- results are" << std::endl;
    277                                 printAll( (*actualExpr)->get_results(), std::cerr, 8 );
     256                                (*actualExpr)->get_result()->print( std::cerr, 8 );
    278257                        )
    279258                        std::list< DeclarationWithType* >::iterator startFormal = formal;
    280259                        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;
     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                                                }
    288278                                        }
     279                                        formalTypes.clear();
     280                                        flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
     281                                        formalType = formalTypes.begin();
     282                                        ++formal;
    289283                                }
     284
    290285                                PRINT(
    291286                                        std::cerr << std::endl << "converting ";
    292                                         (*actual)->print( std::cerr, 8 );
     287                                        (*actualType)->print( std::cerr, 8 );
    293288                                        std::cerr << std::endl << " to ";
    294289                                        (*formal)->get_type()->print( std::cerr, 8 );
    295290                                )
    296                                 Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
     291                                Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
    297292                                PRINT(
    298293                                        std::cerr << std::endl << "cost is" << newCost << std::endl;
     
    305300                                actualCost += newCost;
    306301
    307                                 convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
    308 
    309                                 formal++;
     302                                convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
     303
     304                                formalType++;
    310305                        }
    311306                        if ( actualCost != Cost( 0, 0, 0 ) ) {
     
    356351        /// Adds type variables to the open variable set and marks their assertions
    357352        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 ) {
     353                for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    359354                        unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind();
    360355                        for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
     
    365360        }
    366361
    367         bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) {
     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 ) {
    368417                simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
    369418                // make sure we don't widen any existing bindings
     
    373422                resultEnv.extractOpenVars( openVars );
    374423
    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;
     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 );
    416451                }
    417452                return true;
     
    500535                                //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
    501536                                Expression *varExpr = new VariableExpr( candDecl );
    502                                 deleteAll( varExpr->get_results() );
    503                                 varExpr->get_results().clear();
    504                                 varExpr->get_results().push_front( adjType->clone() );
     537                                delete varExpr->get_result();
     538                                varExpr->set_result( adjType->clone() );
    505539                                PRINT(
    506540                                        std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
     
    545579
    546580        template< typename OutputIterator >
    547         void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) {
     581        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ) {
    548582                OpenVarSet openVars;
    549583                AssertionSet resultNeed, resultHave;
    550584                TypeEnvironment resultEnv;
    551585                makeUnifiableVars( funcType, openVars, resultNeed );
    552                 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) {
     586                AltList instantiatedActuals; // filled by instantiate function
     587                if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) {
    553588                        ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
    554                         Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) );
    555                         makeExprList( actualAlt, appExpr->get_args() );
     589                        Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals ) );
     590                        makeExprList( instantiatedActuals, appExpr->get_args() );
    556591                        PRINT(
    557592                                std::cerr << "need assertions:" << std::endl;
     
    574609                                PointerType pt( Type::Qualifiers(), v.clone() );
    575610                                UntypedExpr *vexpr = untypedExpr->clone();
    576                                 vexpr->get_results().push_front( pt.clone() );
     611                                vexpr->set_result( pt.clone() );
    577612                                alternatives.push_back( Alternative( vexpr, env, Cost()) );
    578613                                return;
     
    587622                combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
    588623
    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 ...
     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 );
    594627
    595628                AltList candidates;
     
    604637                                // check if the type is pointer to function
    605638                                PointerType *pointer;
    606                                 if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
     639                                if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {
    607640                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    608641                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    640673                                                // check if the type is pointer to function
    641674                                                PointerType *pointer;
    642                                                 if ( funcOp->expr->get_results().size() == 1
    643                                                         && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
     675                                                if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) {
    644676                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    645677                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    665697
    666698                        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 );
     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() );
    673702                                std::cerr << "Case +++++++++++++" << std::endl;
    674703                                std::cerr << "formals are:" << std::endl;
     
    692721
    693722        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;
     723                // xxx - recurse into tuples?
     724                return expr->has_result() && expr->get_result()->get_isLvalue();
    698725        }
    699726
     
    709736
    710737        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
     738                Type *& toType = castExpr->get_result();
     739                toType = resolveTypeof( toType, indexer );
     740                SymTab::validateType( toType, &indexer );
     741                adjustExprType( toType, env, indexer );
    716742
    717743                AlternativeFinder finder( indexer, env );
     
    727753                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    728754                        // to.
    729                         int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
     755                        int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
    730756                        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() );
     757                        // xxx - may need to go into tuple types and extract relavent types and use unifyList
    733758                        // 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 );
     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 );
    740761                        if ( thisCost != Cost::infinity ) {
    741762                                // count one safe conversion for each value that is thrown away
     
    760781
    761782                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
     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() );
    768787                        } // if
    769788                } // for
     
    791810                        renameTypes( alternatives.back().expr );
    792811                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
    793                                 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
     812                                NameExpr nameExpr( "" );
     813                                addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
    794814                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
    795                                 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
     815                                NameExpr nameExpr( "" );
     816                                addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
    796817                        } // if
    797818                } // for
     
    894915                        alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
    895916                        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() );
     917                                alternatives.back().expr->set_result( (*i)->get_type()->clone() );
    897918                        } // for
    898919                } // if
     
    917938                                                        finder.find( attrExpr->get_expr() );
    918939                                                        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 );
     940                                                                if ( choice->expr->get_result()->size() == 1 ) {
     941                                                                        resolveAttr(*i, function, choice->expr->get_result(), choice->env );
    921942                                                                } // fi
    922943                                                        } // for
     
    960981                                        AssertionSet needAssertions, haveAssertions;
    961982                                        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 ) ) {
     983                                        Type* commonType;
     984                                        if ( unify( second->expr->get_result(), third->expr->get_result(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    964985                                                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
     986                                                newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() );
    974987                                                newAlt.expr = newExpr;
    975988                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     
    9991012                        TupleExpr *newExpr = new TupleExpr;
    10001013                        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
     1014                        newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) );
    10061015
    10071016                        TypeEnvironment compositeEnv;
     
    10241033                }
    10251034        }
     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        }
    10261043} // namespace ResolvExpr
    10271044
Note: See TracChangeset for help on using the changeset viewer.