Ignore:
Timestamp:
Nov 29, 2016, 3:30:59 PM (9 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
8e5724e
Parents:
3a2128f (diff), 9129a84 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg2:software/cfa/cfa-cc

Conflicts:

src/Parser/parser.cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r3a2128f r1f44196  
    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"
     41#include "Tuples/Explode.h"
    4242#include "Common/utility.h"
    4343#include "InitTweak/InitTweak.h"
     44#include "InitTweak/GenInit.h"
    4445#include "ResolveTypeof.h"
    4546
     
    6465        }
    6566
     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
    6675        namespace {
    6776                void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
     
    7685                                out.push_back( i->expr->clone() );
    7786                        }
    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;
    8687                }
    8788
     
    101102                                PruneStruct current( candidate );
    102103                                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();
     104                                {
     105                                        Type * newType = candidate->expr->get_result()->clone();
    105106                                        candidate->env.apply( newType );
    106                                         mangleName += SymTab::Mangler::mangle( newType );
     107                                        mangleName = SymTab::Mangler::mangle( newType );
    107108                                        delete newType;
    108109                                }
     
    133134                                if ( ! target->second.isAmbiguous ) {
    134135                                        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                                         }
     136                                        alt.env.applyFree( alt.expr->get_result() );
    138137                                        *out++ = alt;
    139138                                }
    140139                        }
    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                         }
    169140                }
    170141
    171142                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                         }
     143                        expr->get_result()->accept( global_renamer );
    175144                }
    176145        }
     
    204173                for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
    205174                        if ( adjust ) {
    206                                 adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
     175                                adjustExprType( i->expr->get_result(), i->env, indexer );
    207176                        }
    208177                }
     
    240209        }
    241210
     211        // std::unordered_map< Expression *, UniqueExpr * > ;
     212
    242213        template< typename StructOrUnionType >
    243         void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) {
     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();
    244218                std::list< Declaration* > members;
    245219                aggInst->lookup( name, members );
     
    254228        }
    255229
     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
    256254        void AlternativeFinder::visit( ApplicationExpr *applicationExpr ) {
    257255                alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
     
    259257
    260258        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 );
     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() );
    267262
    268263                Cost convCost( 0, 0, 0 );
     
    270265                std::list< DeclarationWithType* >::iterator formal = formals.begin();
    271266                std::list< Expression* >& actuals = appExpr->get_args();
     267
     268                std::list< Type * > formalTypes;
     269                std::list< Type * >::iterator formalType = formalTypes.end();
     270
    272271                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                                 printAll( (*actualExpr)->get_results(), std::cerr, 8 );
     277                                (*actualExpr)->get_result()->print( std::cerr, 8 );
    278278                        )
    279279                        std::list< DeclarationWithType* >::iterator startFormal = formal;
    280280                        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;
     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                                                }
    288299                                        }
     300                                        formalTypes.clear();
     301                                        flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
     302                                        formalType = formalTypes.begin();
     303                                        ++formal;
    289304                                }
     305
    290306                                PRINT(
    291307                                        std::cerr << std::endl << "converting ";
    292                                         (*actual)->print( std::cerr, 8 );
     308                                        (*actualType)->print( std::cerr, 8 );
    293309                                        std::cerr << std::endl << " to ";
    294310                                        (*formal)->get_type()->print( std::cerr, 8 );
    295311                                )
    296                                 Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
     312                                Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
    297313                                PRINT(
    298314                                        std::cerr << std::endl << "cost is" << newCost << std::endl;
     
    305321                                actualCost += newCost;
    306322
    307                                 convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
    308 
    309                                 formal++;
     323                                convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
     324
     325                                formalType++;
    310326                        }
    311327                        if ( actualCost != Cost( 0, 0, 0 ) ) {
     
    356372        /// Adds type variables to the open variable set and marks their assertions
    357373        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 ) {
     374                for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    359375                        unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind();
    360376                        for ( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
     
    365381        }
    366382
    367         bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave ) {
     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 ) {
    368438                simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
    369439                // make sure we don't widen any existing bindings
     
    373443                resultEnv.extractOpenVars( openVars );
    374444
    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;
     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 );
    416472                }
    417473                return true;
     
    500556                                //if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
    501557                                Expression *varExpr = new VariableExpr( candDecl );
    502                                 deleteAll( varExpr->get_results() );
    503                                 varExpr->get_results().clear();
    504                                 varExpr->get_results().push_front( adjType->clone() );
     558                                delete varExpr->get_result();
     559                                varExpr->set_result( adjType->clone() );
    505560                                PRINT(
    506561                                        std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
     
    545600
    546601        template< typename OutputIterator >
    547         void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out ) {
     602        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ) {
    548603                OpenVarSet openVars;
    549604                AssertionSet resultNeed, resultHave;
    550605                TypeEnvironment resultEnv;
    551606                makeUnifiableVars( funcType, openVars, resultNeed );
    552                 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) {
     607                AltList instantiatedActuals; // filled by instantiate function
     608                if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) {
    553609                        ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
    554                         Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) );
    555                         makeExprList( actualAlt, appExpr->get_args() );
     610                        Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals ) );
     611                        makeExprList( instantiatedActuals, appExpr->get_args() );
    556612                        PRINT(
    557613                                std::cerr << "need assertions:" << std::endl;
     
    574630                                PointerType pt( Type::Qualifiers(), v.clone() );
    575631                                UntypedExpr *vexpr = untypedExpr->clone();
    576                                 vexpr->get_results().push_front( pt.clone() );
     632                                vexpr->set_result( pt.clone() );
    577633                                alternatives.push_back( Alternative( vexpr, env, Cost()) );
    578634                                return;
     
    587643                combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
    588644
    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 ...
     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 );
    594648
    595649                AltList candidates;
     
    604658                                // check if the type is pointer to function
    605659                                PointerType *pointer;
    606                                 if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
     660                                if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {
    607661                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    608662                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    640694                                                // check if the type is pointer to function
    641695                                                PointerType *pointer;
    642                                                 if ( funcOp->expr->get_results().size() == 1
    643                                                         && ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
     696                                                if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) {
    644697                                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    645698                                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
     
    665718
    666719                        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 );
     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() );
    673723                                std::cerr << "Case +++++++++++++" << std::endl;
    674724                                std::cerr << "formals are:" << std::endl;
     
    692742
    693743        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;
     744                // xxx - recurse into tuples?
     745                return expr->has_result() && expr->get_result()->get_isLvalue();
    698746        }
    699747
     
    709757
    710758        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
     759                Type *& toType = castExpr->get_result();
     760                toType = resolveTypeof( toType, indexer );
     761                SymTab::validateType( toType, &indexer );
     762                adjustExprType( toType, env, indexer );
    716763
    717764                AlternativeFinder finder( indexer, env );
     
    727774                        // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    728775                        // to.
    729                         int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
     776                        int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
    730777                        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() );
     778                        // xxx - may need to go into tuple types and extract relavent types and use unifyList
    733779                        // 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 );
     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 );
    740782                        if ( thisCost != Cost::infinity ) {
    741783                                // count one safe conversion for each value that is thrown away
     
    760802
    761803                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
     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() );
    768810                        } // if
    769811                } // for
     
    791833                        renameTypes( alternatives.back().expr );
    792834                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
    793                                 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
     835                                NameExpr nameExpr( "" );
     836                                addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
    794837                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
    795                                 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
     838                                NameExpr nameExpr( "" );
     839                                addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
    796840                        } // if
    797841                } // for
     
    894938                        alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
    895939                        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() );
     940                                alternatives.back().expr->set_result( (*i)->get_type()->clone() );
    897941                        } // for
    898942                } // if
     
    917961                                                        finder.find( attrExpr->get_expr() );
    918962                                                        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 );
     963                                                                if ( choice->expr->get_result()->size() == 1 ) {
     964                                                                        resolveAttr(*i, function, choice->expr->get_result(), choice->env );
    921965                                                                } // fi
    922966                                                        } // for
     
    9601004                                        AssertionSet needAssertions, haveAssertions;
    9611005                                        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 ) ) {
     1006                                        Type* commonType = nullptr;
     1007                                        if ( unify( second->expr->get_result(), third->expr->get_result(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    9641008                                                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
     1009                                                newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() );
    9741010                                                newAlt.expr = newExpr;
    9751011                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     
    9991035                        TupleExpr *newExpr = new TupleExpr;
    10001036                        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
     1037                        newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) );
    10061038
    10071039                        TypeEnvironment compositeEnv;
     
    10241056                }
    10251057        }
     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
    10261077} // namespace ResolvExpr
    10271078
Note: See TracChangeset for help on using the changeset viewer.