Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r141b786 rb6fe7e6  
    3838#include "SynTree/TypeSubstitution.h"
    3939#include "SymTab/Validate.h"
    40 #include "Tuples/Tuples.h"
    41 #include "Tuples/Explode.h"
     40#include "Tuples/TupleAssignment.h"
     41#include "Tuples/NameMatcher.h"
    4242#include "Common/utility.h"
    4343#include "InitTweak/InitTweak.h"
    44 #include "InitTweak/GenInit.h"
    4544#include "ResolveTypeof.h"
    4645
     
    6564        }
    6665
    67         Cost sumCost( const AltList &in ) {
    68                 Cost total;
    69                 for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
    70                         total += i->cost;
    71                 }
    72                 return total;
    73         }
    74 
    7566        namespace {
    7667                void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
     
    8576                                out.push_back( i->expr->clone() );
    8677                        }
     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;
    8786                }
    8887
     
    102101                                PruneStruct current( candidate );
    103102                                std::string mangleName;
    104                                 {
    105                                         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();
    106105                                        candidate->env.apply( newType );
    107                                         mangleName = SymTab::Mangler::mangle( newType );
     106                                        mangleName += SymTab::Mangler::mangle( newType );
    108107                                        delete newType;
    109108                                }
     
    134133                                if ( ! target->second.isAmbiguous ) {
    135134                                        Alternative &alt = *target->second.candidate;
    136                                         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                                        }
    137138                                        *out++ = alt;
    138139                                }
    139140                        }
     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                        }
    140169                }
    141170
    142171                void renameTypes( Expression *expr ) {
    143                         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                        }
    144175                }
    145176        }
     
    173204                for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
    174205                        if ( adjust ) {
    175                                 adjustExprType( i->expr->get_result(), i->env, indexer );
     206                                adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
    176207                        }
    177208                }
     
    209240        }
    210241
    211         // std::unordered_map< Expression *, UniqueExpr * > ;
    212 
    213242        template< typename StructOrUnionType >
    214         void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
    215                 // by this point, member must be a name expr
    216                 NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member );
    217                 const std::string & name = nameExpr->get_name();
     243        void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) {
    218244                std::list< Declaration* > members;
    219245                aggInst->lookup( name, members );
     
    228254        }
    229255
    230         void AlternativeFinder::addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
    231                 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
    232                         // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
    233                         // xxx - this should be improved by memoizing the value of constant exprs
    234                         // during parsing and reusing that information here.
    235                         std::stringstream ss( constantExpr->get_constant()->get_value() );
    236                         int val;
    237                         std::string tmp;
    238                         if ( ss >> val && ! (ss >> tmp) ) {
    239                                 if ( val >= 0 && (unsigned int)val < tupleType->size() ) {
    240                                         alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
    241                                 } // if
    242                         } // if
    243                 } else if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) {
    244                         // xxx - temporary hack until 0/1 are int constants
    245                         if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
    246                                 std::stringstream ss( nameExpr->get_name() );
    247                                 int val;
    248                                 ss >> val;
    249                                 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
    250                         }
    251                 } // if
    252         }
    253 
    254256        void AlternativeFinder::visit( ApplicationExpr *applicationExpr ) {
    255257                alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
     
    257259
    258260        Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
    259                 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
    260                 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    261                 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 );
    262267
    263268                Cost convCost( 0, 0, 0 );
     
    265270                std::list< DeclarationWithType* >::iterator formal = formals.begin();
    266271                std::list< Expression* >& actuals = appExpr->get_args();
    267 
    268                 std::list< Type * > formalTypes;
    269                 std::list< Type * >::iterator formalType = formalTypes.end();
    270 
    271272                for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    272 
    273273                        PRINT(
    274274                                std::cerr << "actual expression:" << std::endl;
    275275                                (*actualExpr)->print( std::cerr, 8 );
    276276                                std::cerr << "--- results are" << std::endl;
    277                                 (*actualExpr)->get_result()->print( std::cerr, 8 );
     277                                printAll( (*actualExpr)->get_results(), std::cerr, 8 );
    278278                        )
    279279                        std::list< DeclarationWithType* >::iterator startFormal = formal;
    280280                        Cost actualCost;
    281                         std::list< Type * > flatActualTypes;
    282                         flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) );
    283                         for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) {
    284 
    285 
    286                                 // tuple handling code
    287                                 if ( formalType == formalTypes.end() ) {
    288                                         // the type of the formal parameter may be a tuple type. To make this easier to work with,
    289                                         // flatten the tuple type and traverse the resulting list of types, incrementing the formal
    290                                         // iterator once its types have been extracted. Once a particular formal parameter's type has
    291                                         // been exhausted load the next formal parameter's type.
    292                                         if ( formal == formals.end() ) {
    293                                                 if ( function->get_isVarArgs() ) {
    294                                                         convCost += Cost( 1, 0, 0 );
    295                                                         break;
    296                                                 } else {
    297                                                         return Cost::infinity;
    298                                                 }
     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;
    299288                                        }
    300                                         formalTypes.clear();
    301                                         flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
    302                                         formalType = formalTypes.begin();
    303                                         ++formal;
    304289                                }
    305 
    306290                                PRINT(
    307291                                        std::cerr << std::endl << "converting ";
    308                                         (*actualType)->print( std::cerr, 8 );
     292                                        (*actual)->print( std::cerr, 8 );
    309293                                        std::cerr << std::endl << " to ";
    310294                                        (*formal)->get_type()->print( std::cerr, 8 );
    311295                                )
    312                                 Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
     296                                Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
    313297                                PRINT(
    314298                                        std::cerr << std::endl << "cost is" << newCost << std::endl;
     
    321305                                actualCost += newCost;
    322306
    323                                 convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
    324 
    325                                 formalType++;
     307                                convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
     308
     309                                formal++;
    326310                        }
    327311                        if ( actualCost != Cost( 0, 0, 0 ) ) {
     
    372356        /// Adds type variables to the open variable set and marks their assertions
    373357        void makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions ) {
    374                 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 ) {
    375359                        unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind();
    376360                        for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
     
    381365        }
    382366
    383         /// instantiate a single argument by matching actuals from [actualIt, actualEnd) against formalType,
    384         /// producing expression(s) in out and their total cost in cost.
    385         template< typename AltIterator, typename OutputIterator >
    386         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 ) {
    387                 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) {
    388                         // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType
    389                         TupleExpr * tupleExpr = new TupleExpr();
    390                         for ( Type * type : *tupleType ) {
    391                                 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( tupleExpr->get_exprs() ) ) ) {
    392                                         delete tupleExpr;
    393                                         return false;
    394                                 }
    395                         }
    396                         tupleExpr->set_result( Tuples::makeTupleType( tupleExpr->get_exprs() ) );
    397                         *out++ = tupleExpr;
    398                 } else if ( actualIt != actualEnd ) {
    399                         // both actualType and formalType are atomic (non-tuple) types - if they unify
    400                         // then accept actual as an argument, otherwise return false (fail to instantiate argument)
    401                         Expression * actual = actualIt->expr;
    402                         Type * actualType = actual->get_result();
    403                         PRINT(
    404                                 std::cerr << "formal type is ";
    405                                 formalType->print( std::cerr );
    406                                 std::cerr << std::endl << "actual type is ";
    407                                 actualType->print( std::cerr );
    408                                 std::cerr << std::endl;
    409                         )
    410                         if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    411                                 return false;
    412                         }
    413                         // move the expression from the alternative to the output iterator
    414                         *out++ = actual;
    415                         actualIt->expr = nullptr;
    416                         cost += actualIt->cost;
    417                         ++actualIt;
    418                 } else {
    419                         // End of actuals - Handle default values
    420                         if ( SingleInit *si = dynamic_cast<SingleInit *>( defaultValue )) {
    421                                 // so far, only constant expressions are accepted as default values
    422                                 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) {
    423                                         if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) {
    424                                                 if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
    425                                                         // xxx - Don't know if this is right
    426                                                         *out++ = cnstexpr->clone();
    427                                                         return true;
    428                                                 } // if
    429                                         } // if
    430                                 } // if
    431                         } // if
    432                         return false;
    433                 } // if
    434                 return true;
    435         }
    436 
    437         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 ) {
    438368                simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
    439369                // make sure we don't widen any existing bindings
     
    443373                resultEnv.extractOpenVars( openVars );
    444374
    445                 // flatten actuals so that each actual has an atomic (non-tuple) type
    446                 AltList exploded;
    447                 Tuples::explode( actuals, indexer, back_inserter( exploded ) );
    448 
    449                 AltList::iterator actualExpr = exploded.begin();
    450                 AltList::iterator actualEnd = exploded.end();
    451                 for ( DeclarationWithType * formal : formals ) {
    452                         // match flattened actuals with formal parameters - actuals will be grouped to match
    453                         // with formals as appropriate
    454                         Cost cost;
    455                         std::list< Expression * > newExprs;
    456                         ObjectDecl * obj = safe_dynamic_cast< ObjectDecl * >( formal );
    457                         if ( ! instantiateArgument( obj->get_type(), obj->get_init(), actualExpr, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( newExprs ) ) ) {
    458                                 deleteAll( newExprs );
    459                                 return false;
    460                         }
    461                         // success - produce argument as a new alternative
    462                         assert( newExprs.size() == 1 );
    463                         out.push_back( Alternative( newExprs.front(), resultEnv, cost ) );
    464                 }
    465                 if ( actualExpr != actualEnd ) {
    466                         // there are still actuals remaining, but we've run out of formal parameters to match against
    467                         // this is okay only if the function is variadic
    468                         if ( ! isVarArgs ) {
    469                                 return false;
    470                         }
    471                         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;
    472416                }
    473417                return true;
     
    556500                                //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
    557501                                Expression *varExpr = new VariableExpr( candDecl );
    558                                 delete varExpr->get_result();
    559                                 varExpr->set_result( adjType->clone() );
     502                                deleteAll( varExpr->get_results() );
     503                                varExpr->get_results().clear();
     504                                varExpr->get_results().push_front( adjType->clone() );
    560505                                PRINT(
    561506                                        std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
     
    600545
    601546        template< typename OutputIterator >
    602         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 ) {
    603548                OpenVarSet openVars;
    604549                AssertionSet resultNeed, resultHave;
    605550                TypeEnvironment resultEnv;
    606551                makeUnifiableVars( funcType, openVars, resultNeed );
    607                 AltList instantiatedActuals; // filled by instantiate function
    608                 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 ) ) {
    609553                        ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
    610                         Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals ) );
    611                         makeExprList( instantiatedActuals, appExpr->get_args() );
     554                        Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) );
     555                        makeExprList( actualAlt, appExpr->get_args() );
    612556                        PRINT(
    613557                                std::cerr << "need assertions:" << std::endl;
     
    630574                                PointerType pt( Type::Qualifiers(), v.clone() );
    631575                                UntypedExpr *vexpr = untypedExpr->clone();
    632                                 vexpr->set_result( pt.clone() );
     576                                vexpr->get_results().push_front( pt.clone() );
    633577                                alternatives.push_back( Alternative( vexpr, env, Cost()) );
    634578                                return;
     
    643587                combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
    644588
    645                 // take care of possible tuple assignments
    646                 // if not tuple assignment, assignment is taken care of as a normal function call
    647                 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 ...
    648594
    649595                AltList candidates;
     
    658604                                // check if the type is pointer to function
    659605                                PointerType *pointer;
    660                                 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() ) ) ) {
    661607                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    662608                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    694640                                                // check if the type is pointer to function
    695641                                                PointerType *pointer;
    696                                                 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() ) ) ) {
    697644                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    698645                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    718665
    719666                        PRINT(
    720                                 ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( withFunc->expr );
    721                                 PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    722                                 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 );
    723673                                std::cerr << "Case +++++++++++++" << std::endl;
    724674                                std::cerr << "formals are:" << std::endl;
     
    742692
    743693        bool isLvalue( Expression *expr ) {
    744                 // xxx - recurse into tuples?
    745                 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;
    746698        }
    747699
     
    757709
    758710        void AlternativeFinder::visit( CastExpr *castExpr ) {
    759                 Type *& toType = castExpr->get_result();
    760                 toType = resolveTypeof( toType, indexer );
    761                 SymTab::validateType( toType, &indexer );
    762                 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
    763716
    764717                AlternativeFinder finder( indexer, env );
     
    774727                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    775728                        // to.
    776                         int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
     729                        int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
    777730                        if ( discardedValues < 0 ) continue;
    778                         // 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() );
    779733                        // unification run for side-effects
    780                         unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
    781                         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 );
    782740                        if ( thisCost != Cost::infinity ) {
    783741                                // count one safe conversion for each value that is thrown away
     
    802760
    803761                for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
    804                         if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) {
    805                                 addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    806                         } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) {
    807                                 addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
    808                         } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( agg->expr->get_result() ) ) {
    809                                 addTupleMembers( tupleType, 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
    810768                        } // if
    811769                } // for
     
    833791                        renameTypes( alternatives.back().expr );
    834792                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
    835                                 NameExpr nameExpr( "" );
    836                                 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
     793                                addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
    837794                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
    838                                 NameExpr nameExpr( "" );
    839                                 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
     795                                addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
    840796                        } // if
    841797                } // for
     
    938894                        alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
    939895                        for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
    940                                 alternatives.back().expr->set_result( (*i)->get_type()->clone() );
     896                                alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() );
    941897                        } // for
    942898                } // if
     
    961917                                                        finder.find( attrExpr->get_expr() );
    962918                                                        for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    963                                                                 if ( choice->expr->get_result()->size() == 1 ) {
    964                                                                         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 );
    965921                                                                } // fi
    966922                                                        } // for
     
    1004960                                        AssertionSet needAssertions, haveAssertions;
    1005961                                        Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost );
    1006                                         Type* commonType;
    1007                                         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 ) ) {
    1008964                                                ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
    1009                                                 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
    1010974                                                newAlt.expr = newExpr;
    1011975                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     
    1035999                        TupleExpr *newExpr = new TupleExpr;
    10361000                        makeExprList( *i, newExpr->get_exprs() );
    1037                         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
    10381006
    10391007                        TypeEnvironment compositeEnv;
     
    10561024                }
    10571025        }
    1058 
    1059         void AlternativeFinder::visit( TupleIndexExpr *tupleExpr ) {
    1060                 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
    1061         }
    1062 
    1063         void AlternativeFinder::visit( TupleAssignExpr *tupleAssignExpr ) {
    1064                 alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );
    1065         }
    1066 
    1067         void AlternativeFinder::visit( UniqueExpr *unqExpr ) {
    1068                 AlternativeFinder finder( indexer, env );
    1069                 finder.findWithAdjustment( unqExpr->get_expr() );
    1070                 for ( Alternative & alt : finder.alternatives ) {
    1071                         // ensure that the id is passed on to the UniqueExpr alternative so that the expressions are "linked"
    1072                         UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() );
    1073                         alternatives.push_back( Alternative( newUnqExpr, alt.env, alt.cost ) );
    1074                 }
    1075         }
    1076 
    10771026} // namespace ResolvExpr
    10781027
Note: See TracChangeset for help on using the changeset viewer.