Ignore:
Timestamp:
Sep 22, 2016, 8:14:56 AM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
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:
ac9ca96
Parents:
1132b62
git-author:
Rob Schluntz <rschlunt@…> (09/21/16 23:43:37)
git-committer:
Rob Schluntz <rschlunt@…> (09/22/16 08:14:56)
Message:

replace multiple-returning functions with tuple-returning functions, implement tuple ctor/dtor, allow N-arg tuple assignment

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/TupleExpansion.cc

    r1132b62 r65660bd  
    4949
    5050                        virtual Type * mutate( TupleType * tupleType );
    51                         virtual Type * mutate( FunctionType * ftype );
    5251
    5352                        virtual CompoundStmt * mutate( CompoundStmt * stmt ) {
     
    119118                delete assnExpr;
    120119                return new StmtExpr( compoundStmt );
    121         }
    122 
    123         Type * TupleTypeReplacer::mutate( FunctionType * ftype ) {
    124                 // replace multiple-returning functions with functions which return a tuple
    125                 if ( ftype->get_returnVals().size() > 1 ) {
    126                         TupleType * tupleType = safe_dynamic_cast<TupleType *>( ResolvExpr::extractResultType( ftype ) );
    127                         ObjectDecl * retVal = new ObjectDecl( "__tuple_ret", DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, tupleType, nullptr );
    128                         // xxx - replace all uses of return vals with appropriate tuple index expr
    129                         deleteAll( ftype->get_returnVals() );
    130                         ftype->get_returnVals().clear();
    131                         ftype->get_returnVals().push_back( retVal );
    132                 }
    133                 return Parent::mutate( ftype );
    134120        }
    135121
     
    167153        }
    168154
     155        Expression * replaceTupleExpr( Type * result, const std::list< Expression * > & exprs ) {
     156                if ( result->isVoid() ) {
     157                        // void result - don't need to produce a value for cascading - just output a chain of comma exprs
     158                        assert( ! exprs.empty() );
     159                        std::list< Expression * >::const_iterator iter = exprs.begin();
     160                        Expression * expr = *iter++;
     161                        for ( ; iter != exprs.end(); ++iter ) {
     162                                expr = new CommaExpr( expr, *iter );
     163                        }
     164                        return expr;
     165                } else {
     166                        // typed tuple expression - produce a compound literal which performs each of the expressions
     167                        // as a distinct part of its initializer - the produced compound literal may be used as part of
     168                        // another expression
     169                        std::list< Initializer * > inits;
     170                        for ( Expression * expr : exprs ) {
     171                                inits.push_back( new SingleInit( expr ) );
     172                        }
     173                        return new CompoundLiteralExpr( result, new ListInit( inits ) );
     174                }
     175        }
     176
    169177        Expression * TupleExprExpander::mutate( TupleExpr * tupleExpr ) {
    170                 assert( tupleExpr->get_result() );
    171                 std::list< Initializer * > inits;
    172                 for ( Expression * expr : tupleExpr->get_exprs() ) {
    173                         inits.push_back( new SingleInit( expr ) );
    174                 }
    175                 return new CompoundLiteralExpr( tupleExpr->get_result(), new ListInit( inits ) );
    176         }
    177 
    178         TupleType * makeTupleType( const std::list< Expression * > & exprs ) {
     178                Type * result = tupleExpr->get_result();
     179                std::list< Expression * > exprs = tupleExpr->get_exprs();
     180                assert( result );
     181
     182                tupleExpr->set_result( nullptr );
     183                tupleExpr->get_exprs().clear();
     184                delete tupleExpr;
     185
     186                return replaceTupleExpr( result, exprs );
     187        }
     188
     189        Type * makeTupleType( const std::list< Expression * > & exprs ) {
     190                // produce the TupleType which aggregates the types of the exprs
    179191                TupleType *tupleType = new TupleType( Type::Qualifiers(true, true, true, true, true, false) );
    180192                Type::Qualifiers &qualifiers = tupleType->get_qualifiers();
    181193                for ( Expression * expr : exprs ) {
    182194                        assert( expr->get_result() );
     195                        if ( expr->get_result()->isVoid() ) {
     196                                // if the type of any expr is void, the type of the entire tuple is void
     197                                delete tupleType;
     198                                return new VoidType( Type::Qualifiers() );
     199                        }
    183200                        Type * type = expr->get_result()->clone();
    184201                        tupleType->get_types().push_back( type );
     202                        // the qualifiers on the tuple type are the qualifiers that exist on all component types
    185203                        qualifiers &= type->get_qualifiers();
    186204                } // for
    187205                return tupleType;
     206        }
     207
     208        namespace {
     209                /// determines if impurity (read: side-effects) may exist in a piece of code. Currently gives a very crude approximation, wherein any function call expression means the code may be impure
     210                class ImpurityDetector : public Visitor {
     211                public:
     212                        typedef Visitor Parent;
     213                        virtual void visit( ApplicationExpr * appExpr ) { maybeImpure = true;   }
     214                        virtual void visit( UntypedExpr * untypedExpr ) { maybeImpure = true; }
     215                        bool maybeImpure = false;
     216                };
     217        } // namespace
     218
     219        bool maybeImpure( Expression * expr ) {
     220                ImpurityDetector detector;
     221                expr->accept( detector );
     222                return detector.maybeImpure;
    188223        }
    189224} // namespace Tuples
Note: See TracChangeset for help on using the changeset viewer.