Changeset 7933351


Ignore:
Timestamp:
Dec 13, 2016, 4:59:46 PM (5 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
ea83e00a
Parents:
fc638d2
Message:

add tuple cast resolution code

Location:
src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    rfc638d2 r7933351  
    185185                        if ( alternatives.begin() == oldBegin ) {
    186186                                std::ostringstream stream;
    187                                 stream << "Can't choose between alternatives for expression ";
     187                                stream << "Can't choose between " << alternatives.size() << " alternatives for expression ";
    188188                                expr->print( stream );
    189189                                stream << "Alternatives are:";
     
    308308                                        (*actualType)->print( std::cerr, 8 );
    309309                                        std::cerr << std::endl << " to ";
    310                                         (*formal)->get_type()->print( std::cerr, 8 );
     310                                        (*formalType)->print( std::cerr, 8 );
    311311                                )
    312312                                Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
     
    511511                if ( ! cur->second ) {
    512512                        inferRecursive( begin, end, newAlt, openVars, decls, newNeed, /*needParents,*/ level, indexer, out );
     513                        return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
    513514                }
    514515                DeclarationWithType *curDecl = cur->first;
     516
    515517                PRINT(
    516518                        std::cerr << "inferRecursive: assertion is ";
     
    649651                AltList candidates;
    650652                SemanticError errors;
    651 
    652653                for ( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
    653654                        try {
     
    758759        void AlternativeFinder::visit( CastExpr *castExpr ) {
    759760                Type *& toType = castExpr->get_result();
     761                assert( toType );
    760762                toType = resolveTypeof( toType, indexer );
    761763                SymTab::validateType( toType, &indexer );
     
    763765
    764766                AlternativeFinder finder( indexer, env );
     767                finder.targetType = toType;
    765768                finder.findWithAdjustment( castExpr->get_arg() );
    766769
     
    776779                        int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
    777780                        if ( discardedValues < 0 ) continue;
    778                         // xxx - may need to go into tuple types and extract relavent types and use unifyList
     781                        // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
     782                        // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
    779783                        // unification run for side-effects
    780784                        unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
     
    783787                                // count one safe conversion for each value that is thrown away
    784788                                thisCost += Cost( 0, 0, discardedValues );
    785                                 CastExpr *newExpr = castExpr->clone();
    786                                 newExpr->set_arg( i->expr->clone() );
    787                                 candidates.push_back( Alternative( newExpr, i->env, i->cost, thisCost ) );
     789
     790                                Expression * argExpr = i->expr->clone();
     791                                if ( argExpr->get_result()->size() > 1 && ! castExpr->get_result()->isVoid() ) {
     792                                        // Argument expression is a tuple and the target type is not void. Cast each member of the tuple
     793                                        // to its corresponding target type, producing the tuple of those cast expressions. If there are
     794                                        // more components of the tuple than components in the target type, then excess components do not
     795                                        // come out in the result expression (but UniqueExprs ensure that side effects will still be done).
     796                                        if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
     797                                                // expressions which may contain side effects require a single unique instance of the expression.
     798                                                argExpr = new UniqueExpr( argExpr );
     799                                        }
     800                                        std::list< Expression * > componentExprs;
     801                                        for ( unsigned int i = 0; i < castExpr->get_result()->size(); i++ ) {
     802                                                // cast each component
     803                                                TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i );
     804                                                componentExprs.push_back( new CastExpr( idx, castExpr->get_result()->getComponent( i )->clone() ) );
     805                                        }
     806                                        delete argExpr;
     807                                        assert( componentExprs.size() > 0 );
     808                                        // produce the tuple of casts
     809                                        candidates.push_back( Alternative( new TupleExpr( componentExprs ), i->env, i->cost, thisCost ) );
     810                                } else {
     811                                        // handle normally
     812                                        candidates.push_back( Alternative( new CastExpr( argExpr->clone(), toType->clone() ), i->env, i->cost, thisCost ) );
     813                                }
    788814                        } // if
    789815                } // for
  • src/ResolvExpr/AlternativeFinder.h

    rfc638d2 r7933351  
    9191                AltList alternatives;
    9292                const TypeEnvironment &env;
     93                Type * targetType = nullptr;
    9394        }; // AlternativeFinder
    9495
  • src/SynTree/Type.h

    rfc638d2 r7933351  
    7272        virtual unsigned size() const { return 1; };
    7373        virtual bool isVoid() const { return size() == 0; }
     74        virtual Type * getComponent( unsigned i ) { assertf( size() == 1 && i == 0, "Type::getComponent was called with size %d and index %d\n", size(), i ); return this; }
    7475
    7576        virtual Type *clone() const = 0;
     
    372373        iterator end() { return types.end(); }
    373374
     375        virtual Type * getComponent( unsigned i ) {
     376                assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d", i, size() );
     377                return *(begin()+i);
     378        }
     379
    374380        virtual TupleType *clone() const { return new TupleType( *this ); }
    375381        virtual void accept( Visitor &v ) { v.visit( this ); }
  • src/tests/.expect/castError.txt

    rfc638d2 r7933351  
    11CFA Version 1.0.0 (debug)
    2 Error: Can't choose between alternatives for expression Cast of:
     2Error: Can't choose between 3 alternatives for expression Cast of:
    33  Name: f
    44
  • src/tests/.expect/tupleCast.txt

    rfc638d2 r7933351  
    1110 A 3.14
    2210 A
     310
    3410 65
    45ran f
  • src/tests/tupleCast.c

    rfc638d2 r7933351  
    2020  printf("%d %c %g\n", ([int, char, float])x);
    2121  printf("%d %c\n", ([int, char])x);
     22  printf("%d\n", ([int])x);
     23  // printf("%d\n", (int)x);
    2224  printf("%g %g\n", ([double, float])x);
    2325  printf("%d %c\n", ([int, char])f());
Note: See TracChangeset for help on using the changeset viewer.