Changeset 3c13c03


Ignore:
Timestamp:
Sep 17, 2016, 8:27:51 AM (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:
8c49c0e
Parents:
12bc63a
Message:

expand TupleExpr? and TupleIndexExpr?, add UniqueExpr?

Location:
src
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r12bc63a r3c13c03  
    639639        }
    640640
    641         void CodeGenerator::visit( TupleExpr * tupleExpr ) {}
     641        void CodeGenerator::visit( TupleExpr * tupleExpr ) { assert( false ); }
    642642
    643643        void CodeGenerator::visit( TypeExpr * typeExpr ) {}
     
    655655        }
    656656
     657        void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) {
     658                assert( compLitExpr->get_type() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
     659                output << "(" << genType( compLitExpr->get_type(), "" ) << ")";
     660                compLitExpr->get_initializer()->accept( *this );
     661        }
     662
    657663        void CodeGenerator::visit( StmtExpr * stmtExpr ) {
    658                 output << "(";
    659                 stmtExpr->get_statements()->accept( *this );
    660                 output << ")";
     664                std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
     665                output << "({" << std::endl;
     666                cur_indent += CodeGenerator::tabsize;
     667                unsigned int numStmts = stmts.size();
     668                unsigned int i = 0;
     669                for ( Statement * stmt : stmts ) {
     670                        output << indent << printLabels( stmt->get_labels() );
     671                        if ( i+1 == numStmts ) {
     672                                // last statement in a statement expression needs to be handled specially -
     673                                // cannot cast to void, otherwise the expression statement has no value
     674                                if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
     675                                        exprStmt->get_expr()->accept( *this );
     676                                        output << ";" << endl;
     677                                        ++i;
     678                                        break;
     679                                }
     680                        }
     681                        stmt->accept( *this );
     682                        output << endl;
     683                        if ( wantSpacing( stmt ) ) {
     684                                output << endl;
     685                        } // if
     686                        ++i;
     687                }
     688                cur_indent -= CodeGenerator::tabsize;
     689                output << indent << "})";
    661690        }
    662691
  • src/CodeGen/CodeGenerator.h

    r12bc63a r3c13c03  
    7070                virtual void visit( ConditionalExpr *conditionalExpr );
    7171                virtual void visit( CommaExpr *commaExpr );
     72                virtual void visit( CompoundLiteralExpr *compLitExpr );
    7273                virtual void visit( TupleExpr *tupleExpr );
    7374                virtual void visit( TypeExpr *typeExpr );
  • src/CodeGen/GenType.cc

    r12bc63a r3c13c03  
    213213                        typeString = "_Atomic " + typeString;
    214214                } // if
    215                 if ( type->get_isAttribute() ) {
    216                         typeString = "__attribute(( )) " + typeString;
    217                 } // if
    218215        }
    219216} // namespace CodeGen
  • src/Common/utility.h

    r12bc63a r3c13c03  
    158158}
    159159
     160// replace element of list with all elements of another list
    160161template< typename T >
    161162void replace( std::list< T > &org, typename std::list< T >::iterator pos, std::list< T > &with ) {
     
    168169
    169170        return;
     171}
     172
     173// replace range of a list with a single element
     174template< typename T >
     175void replace( std::list< T > &org, typename std::list< T >::iterator begin, typename std::list< T >::iterator end, const T & with ) {
     176        org.insert( begin, with );
     177        org.erase( begin, end );
    170178}
    171179
  • src/ResolvExpr/Alternative.cc

    r12bc63a r3c13c03  
    2020
    2121namespace ResolvExpr {
    22         Alternative::Alternative() : expr( 0 ) {}
     22        Alternative::Alternative() : cost( Cost::zero ), cvtCost( Cost::zero ), expr( 0 ) {}
    2323
    2424        Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost )
  • src/ResolvExpr/Alternative.h

    r12bc63a r3c13c03  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Alternative.h -- 
     7// Alternative.h --
    88//
    99// Author           : Richard C. Bilson
     
    1212// Last Modified On : Sat May 16 23:54:39 2015
    1313// Update Count     : 2
    14 // 
     14//
    1515
    1616#ifndef ALTERNATIVE_H
     
    3333                Alternative &operator=( const Alternative &other );
    3434                ~Alternative();
    35  
     35
    3636                void initialize( const Alternative &src, Alternative &dest );
    37  
     37
    3838                void print( std::ostream &os, int indent = 0 ) const;
    39  
     39
    4040                Cost cost;
    4141                Cost cvtCost;
     
    4343                TypeEnvironment env;
    4444        };
     45
     46        /// helper function used by explode
     47        template< typename OutputIterator >
     48        void explodeUnique( Expression * expr, const Alternative & alt, OutputIterator out ) {
     49                Type * res = expr->get_result();
     50                if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) {
     51                        if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( alt.expr ) ) {
     52                                for ( Expression * expr : tupleExpr->get_exprs() ) {
     53                                        explodeUnique( expr, alt, out );
     54                                }
     55                        } else {
     56                                UniqueExpr * unq = new UniqueExpr( expr->clone() );
     57                                for ( unsigned int i = 0; i < tupleType->size(); i++ ) {
     58                                        TupleIndexExpr * idx = new TupleIndexExpr( unq->clone(), i );
     59                                        explodeUnique( idx, alt, out );
     60                                        delete idx;
     61                                }
     62                                delete unq;
     63                        }
     64                } else {
     65                        *out++ = Alternative( expr->clone(), alt.env, alt.cost, alt.cvtCost );
     66                }
     67        }
     68
     69        /// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type
     70        template< typename OutputIterator >
     71        void explode( Alternative &alt, OutputIterator out ) {
     72                explodeUnique( alt.expr, alt, out );
     73        }
     74
     75        // explode list of alternatives
     76        template< typename OutputIterator >
     77        void explode( AltList & alts, OutputIterator out ) {
     78                for ( Alternative & alt : alts ) {
     79                        explode( alt, out );
     80                }
     81        }
    4582} // namespace ResolvExpr
    4683
  • src/ResolvExpr/AlternativeFinder.cc

    r12bc63a r3c13c03  
    380380
    381381                std::list< DeclarationWithType* >::iterator formal = formals.begin();
     382
     383                AltList newActuals;
     384                explode( actuals, back_inserter( newActuals ) );
    382385
    383386                std::list< Type * > formalTypes;
     
    994997                        TupleExpr *newExpr = new TupleExpr;
    995998                        makeExprList( *i, newExpr->get_exprs() );
    996                         TupleType *tupleType = new TupleType( Type::Qualifiers(true, true, true, true, true, true) );
    997                         Type::Qualifiers &qualifiers = tupleType->get_qualifiers();
    998                         for ( Expression * resultExpr : newExpr->get_exprs() ) {
    999                                 Type * type = resultExpr->get_result()->clone();
    1000                                 tupleType->get_types().push_back( type );
    1001                                 qualifiers &= type->get_qualifiers();
    1002                         } // for
    1003                         newExpr->set_result( tupleType );
     999                        newExpr->set_result( Tuples::makeTupleType( newExpr->get_exprs() ) );
    10041000
    10051001                        TypeEnvironment compositeEnv;
  • src/SymTab/Validate.cc

    r12bc63a r3c13c03  
    2323// - All enumeration constants have type EnumInstType.
    2424//
    25 // - The type "void" never occurs in lists of function parameter or return types; neither do tuple types.  A function
    26 //   taking no arguments has no argument types, and tuples are flattened.
     25// - The type "void" never occurs in lists of function parameter or return types.  A function
     26//   taking no arguments has no argument types.
    2727//
    2828// - No context instances exist; they are all replaced by the set of declarations signified by the context, instantiated
  • src/SynTree/Expression.cc

    r12bc63a r3c13c03  
    522522
    523523CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : type( type ), initializer( initializer ) {
     524        assert( type && initializer );
    524525        set_result( type->clone() );
    525526}
    526527
    527 CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), type( maybeClone( other.type ) ), initializer( maybeClone( other.initializer ) ) {}
     528CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), type( other.type->clone() ), initializer( other.initializer->clone() ) {}
    528529
    529530CompoundLiteralExpr::~CompoundLiteralExpr() {
     
    534535void CompoundLiteralExpr::print( std::ostream &os, int indent ) const {
    535536        os << "Compound Literal Expression: " << std::endl;
    536         if ( type ) type->print( os, indent + 2 );
    537         if ( initializer ) initializer->print( os, indent + 2 );
     537        os << std::string( indent+2, ' ' );
     538        type->print( os, indent + 2 );
     539        os << std::string( indent+2, ' ' );
     540        initializer->print( os, indent + 2 );
    538541}
    539542
     
    549552
    550553RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {}
    551 RangeExpr::RangeExpr( const RangeExpr &other ) : low( other.low->clone() ), high( other.high->clone() ) {}
     554RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}
    552555void RangeExpr::print( std::ostream &os, int indent ) const {
    553         os << std::string( indent, ' ' ) << "Range Expression: ";
     556        os << "Range Expression: ";
    554557        low->print( os, indent );
    555558        os << " ... ";
     
    566569        }
    567570}
    568 StmtExpr::StmtExpr( const StmtExpr &other ) : statements( other.statements->clone() ) {}
     571StmtExpr::StmtExpr( const StmtExpr &other ) : Expression( other ), statements( other.statements->clone() ) {}
    569572StmtExpr::~StmtExpr() {
    570573        delete statements;
    571574}
    572575void StmtExpr::print( std::ostream &os, int indent ) const {
    573         os << std::string( indent, ' ' ) << "Statement Expression: " << std::endl;
     576        os << "Statement Expression: " << std::endl << std::string( indent, ' ' );
    574577        statements->print( os, indent+2 );
     578}
     579
     580
     581UniqueExpr::UniqueExpr( Expression *expr ) : expr( new Expression* ) {
     582        set_expr( expr );
     583        assert( expr );
     584        assert( expr->has_result() );
     585        set_result( expr->get_result()->clone() );
     586}
     587UniqueExpr::UniqueExpr( const UniqueExpr &other ) : Expression( other ), expr( other.expr ) {
     588}
     589UniqueExpr::~UniqueExpr() {
     590        if ( expr.unique() ) {
     591                delete *expr;
     592        }
     593}
     594void UniqueExpr::print( std::ostream &os, int indent ) const {
     595        os << "Unique Expression: " << std::endl << std::string( indent+2, ' ' );
     596        get_expr()->print( os, indent+2 );
    575597}
    576598
  • src/SynTree/Expression.h

    r12bc63a r3c13c03  
    639639class TupleExpr : public Expression {
    640640  public:
    641         TupleExpr( Expression *_aname = nullptr );
     641        TupleExpr( const std::list< Expression * > & exprs = std::list< Expression * >(), Expression *_aname = nullptr );
    642642        TupleExpr( const TupleExpr &other );
    643643        virtual ~TupleExpr();
     
    733733};
    734734
     735class UniqueExpr : public Expression {
     736public:
     737        UniqueExpr( Expression * expr );
     738        UniqueExpr( const UniqueExpr & other );
     739        ~UniqueExpr();
     740
     741        Expression * get_expr() const { return *expr; }
     742        UniqueExpr * set_expr( Expression * newValue ) { *expr = newValue; return this; }
     743
     744        virtual UniqueExpr *clone() const { return new UniqueExpr( *this ); }
     745        virtual void accept( Visitor &v ) { v.visit( this ); }
     746        virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     747        virtual void print( std::ostream &os, int indent = 0 ) const;
     748private:
     749        std::shared_ptr< Expression * > expr;
     750};
     751
    735752std::ostream & operator<<( std::ostream & out, const Expression * expr );
    736753
  • src/SynTree/Mutator.cc

    r12bc63a r3c13c03  
    384384}
    385385
     386Expression *Mutator::mutate( UniqueExpr *uniqueExpr ) {
     387        uniqueExpr->set_result( maybeMutate( uniqueExpr->get_result(), *this ) );
     388        uniqueExpr->set_expr( maybeMutate( uniqueExpr->get_expr(), *this ) );
     389        return uniqueExpr;
     390}
     391
    386392Type *Mutator::mutate( VoidType *voidType ) {
    387393        mutateAll( voidType->get_forall(), *this );
  • src/SynTree/Mutator.h

    r12bc63a r3c13c03  
    8383        virtual Expression* mutate( TupleAssignExpr *assignExpr );
    8484        virtual Expression* mutate( StmtExpr * stmtExpr );
     85        virtual Expression* mutate( UniqueExpr * uniqueExpr );
    8586
    8687        virtual Type* mutate( VoidType *basicType );
  • src/SynTree/SynTree.h

    r12bc63a r3c13c03  
    8888class TupleAssignExpr;
    8989class StmtExpr;
     90class UniqueExpr;
    9091
    9192class Type;
  • src/SynTree/TupleExpr.cc

    r12bc63a r3c13c03  
    1818#include "Type.h"
    1919#include "Declaration.h"
     20#include "Tuples/Tuples.h"
    2021
    21 TupleExpr::TupleExpr( Expression *_aname ) : Expression( _aname ) {
     22TupleExpr::TupleExpr( const std::list< Expression * > & exprs, Expression *_aname ) : Expression( _aname ), exprs( exprs ) {
     23        if ( ! exprs.empty() ) {
     24                if ( std::all_of( exprs.begin(), exprs.end(), [](Expression * expr) { return expr->get_result(); } ) ) {
     25                        set_result( Tuples::makeTupleType( exprs ) );
     26                }
     27        }
    2228}
    2329
     
    3642}
    3743
    38 TupleIndexExpr::TupleIndexExpr( Expression * tuple, unsigned int index ) {
     44TupleIndexExpr::TupleIndexExpr( Expression * tuple, unsigned int index ) : tuple( tuple ), index( index )  {
    3945        TupleType * type = safe_dynamic_cast< TupleType * >( tuple->get_result() );
    40         assert( type->size() >= index );
    41         set_result( *std::next( type->get_types().begin(), index ) );
     46        assert( type->size() > index );
     47        set_result( (*std::next( type->get_types().begin(), index ))->clone() );
    4248}
    4349
     
    5157void TupleIndexExpr::print( std::ostream &os, int indent ) const {
    5258        os << "Tuple Index Expression, with tuple:" << std::endl;
     59        os << std::string( indent+2, ' ' );
    5360        tuple->print( os, indent+2 );
    5461        os << std::string( indent+2, ' ' ) << "with index: " << index << std::endl;
     
    7077void MemberTupleExpr::print( std::ostream &os, int indent ) const {
    7178        os << "Member Tuple Expression, with aggregate:" << std::endl;
     79        os << std::string( indent+2, ' ' );
    7280        aggregate->print( os, indent+2 );
    7381        os << std::string( indent+2, ' ' ) << "with member: " << std::endl;
     82        os << std::string( indent+2, ' ' );
    7483        member->print( os, indent+2 );
    7584        Expression::print( os, indent );
     
    97106
    98107void TupleAssignExpr::print( std::ostream &os, int indent ) const {
    99         os << std::string( indent, ' ' ) << "Tuple Assignment Expression, with temporaries:" << std::endl;
     108        os << "Tuple Assignment Expression, with temporaries:" << std::endl;
    100109        printAll( tempDecls, os, indent+4 );
    101110        os << std::string( indent+2, ' ' ) << "with assignments: " << std::endl;
  • src/SynTree/Visitor.cc

    r12bc63a r3c13c03  
    326326}
    327327
     328void Visitor::visit( UniqueExpr *uniqueExpr ) {
     329        maybeAccept( uniqueExpr->get_result(), *this );
     330        maybeAccept( uniqueExpr->get_expr(), *this );
     331}
     332
    328333void Visitor::visit( VoidType *voidType ) {
    329334        acceptAll( voidType->get_forall(), *this );
  • src/SynTree/Visitor.h

    r12bc63a r3c13c03  
    8383        virtual void visit( TupleAssignExpr *assignExpr );
    8484        virtual void visit( StmtExpr * stmtExpr );
     85        virtual void visit( UniqueExpr * uniqueExpr );
    8586
    8687        virtual void visit( VoidType *basicType );
  • src/Tuples/TupleAssignment.cc

    r12bc63a r3c13c03  
    3939          private:
    4040                void match();
    41                 // records for assignment generation
    42                 struct Options {
    43                         void print( std::ostream & );
    44                         int size() const { return options.size(); }
    45                         bool empty() const { return options.empty(); }
    46                         typedef std::list< ResolvExpr::AltList >::iterator iterator;
    47                         iterator begin() { return options.begin(); }
    48                         iterator end() { return options.end(); }
    49 
    50                         std::list< ResolvExpr::AltList > options;
    51                 };
    5241
    5342                struct Matcher {
    5443                  public:
    55                         Matcher( TupleAssignSpotter &spotter, Expression *_lhs, Expression *_rhs );
     44                        Matcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs );
    5645                        virtual ~Matcher() {}
    5746                        virtual void match( std::list< Expression * > &out ) = 0;
    58                         std::list< Expression * > lhs, rhs;
     47                        ResolvExpr::AltList lhs, rhs;
    5948                        TupleAssignSpotter &spotter;
    6049                        std::list< ObjectDecl * > tmpDecls;
     
    6352                struct MassAssignMatcher : public Matcher {
    6453                  public:
    65                         MassAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) {
    66                                 this->rhs.push_back( rhs );
    67                         }
     54                        MassAssignMatcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs );
    6855                        virtual void match( std::list< Expression * > &out );
    6956                };
     
    7158                struct MultipleAssignMatcher : public Matcher {
    7259                  public:
    73                         MultipleAssignMatcher( TupleAssignSpotter &spot, Expression *lhs, Expression *rhs );
     60                        MultipleAssignMatcher( TupleAssignSpotter &spot, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs );
    7461                        virtual void match( std::list< Expression * > &out );
    7562                };
     
    7865                // Expression *rhs, *lhs;
    7966                Matcher *matcher = nullptr;
    80                 Options options;
    8167        };
    82 
    83         bool isTupleVar( DeclarationWithType *decl ) {
    84                 return dynamic_cast< TupleType * >( decl->get_type() );
    85         }
    8668
    8769        /// true if expr is an expression of tuple type, i.e. a tuple expression, tuple variable, or MRV (multiple-return-value) function
     
    8971                if ( ! expr ) return false;
    9072                assert( expr->has_result() );
    91                 // xxx - used to include cast to varExpr and call to isTupleVar, but this doesn't seem like it should be necessary
    9273                return dynamic_cast<TupleExpr *>(expr) || expr->get_result()->size() > 1;
    9374        }
     
    10182        }
    10283
    103         bool isTupleExpr( Expression *expr ) {
    104                 assert( expr->has_result() );
    105                 return expr->get_result()->size() > 1;
    106         }
    107 
    10884        void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
    10985                TupleAssignSpotter spotter( currentFinder );
     
    11692        void TupleAssignSpotter::spot( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
    11793                if (  NameExpr *assgnop = dynamic_cast< NameExpr * >(expr->get_function()) ) {
    118                         if ( assgnop->get_name() == std::string("?=?") ) {
     94                        if ( assgnop->get_name() == "?=?" ) {
    11995                                for ( std::list<ResolvExpr::AltList>::iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) {
    120                                         assert( ali->size() == 2 );
    121                                         ResolvExpr::Alternative op1 = ali->front(), op2 = ali->back();
    122 
    123                                         MultipleAssignMatcher multiMatcher( *this, op1.expr, op2.expr );
    124                                         MassAssignMatcher massMatcher( *this, op1.expr, op2.expr );
    125                                         if ( pointsToTuple(op1.expr) ) { // also handles tuple vars
    126                                                 if ( isTuple( op2.expr ) ) {
     96                                        if ( ali->size() != 2 ) continue; // what does it mean if an assignment takes >2 arguments? grab args 2-N and group into a TupleExpr, then proceed?
     97                                        ResolvExpr::Alternative & alt1 = ali->front(), & alt2 = ali->back();
     98
     99                                        if ( pointsToTuple(alt1.expr) ) {
     100                                                MultipleAssignMatcher multiMatcher( *this, alt1, alt2 );
     101                                                MassAssignMatcher massMatcher( *this,  alt1, alt2 );
     102                                                if ( isTuple( alt2.expr ) ) {
    127103                                                        matcher = &multiMatcher;
    128104                                                } else {
     
    131107                                                }
    132108                                                match();
    133                                         } else if ( isTuple( op2.expr ) ) {
     109                                        } else if ( isTuple( alt2.expr ) ) {
    134110                                                throw SemanticError("Cannot assign a tuple value into a non-tuple lvalue.", expr);
    135111                                        }
     
    170146        }
    171147
    172         TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : spotter(spotter) {
    173                 // xxx - shouldn't need to be &<tuple-expr>, just &<lvalue-tuple-type>
    174                 if (AddressExpr *addr = dynamic_cast<AddressExpr *>(lhs) )
    175                         if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(addr->get_arg()) )
    176                                 std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(this->lhs) );
    177         }
    178 
    179         TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) {
    180 
    181                 if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(rhs) )
    182                         std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(this->rhs) );
     148        TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs ) : spotter(spotter) {
     149                if (AddressExpr *addr = dynamic_cast<AddressExpr *>(lhs.expr) ) {
     150                        // xxx - not every assignment NEEDS to have the first argument as address-taken, e.g. a manual call to assignment. What to do in this case? skip it as a possibility for TupleAssignment, since the type will always be T*, where T can never be a tuple? Is this true?
     151
     152                        // explode the lhs so that each field of the tuple-valued-expr is assigned.
     153                        ResolvExpr::Alternative lhsAlt( addr->get_arg()->clone(), lhs.env, lhs.cost, lhs.cvtCost );
     154                        explode( lhsAlt, back_inserter(this->lhs) );
     155                }
     156        }
     157
     158        TupleAssignSpotter::MassAssignMatcher::MassAssignMatcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs ) : Matcher( spotter, lhs, rhs ) {
     159                this->rhs.push_back( rhs );
     160        }
     161
     162        TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, ResolvExpr::Alternative & lhs, ResolvExpr::Alternative & rhs ) : Matcher( spotter, lhs, rhs ) {
     163
     164                // explode the rhs so that each field of the tuple-valued-expr is assigned.
     165                explode( rhs, back_inserter(this->rhs) );
    183166        }
    184167
     
    201184                assert ( ! lhs.empty() && rhs.size() == 1);
    202185
    203                 ObjectDecl * rtmp = newObject( rhsNamer, rhs.front() );
    204                 for ( Expression * l : lhs ) {
    205                         ObjectDecl * ltmp = newObject( lhsNamer, new AddressExpr( l ) );
     186                ObjectDecl * rtmp = newObject( rhsNamer, rhs.front().expr );
     187                for ( ResolvExpr::Alternative & lhsAlt : lhs ) {
     188                        ObjectDecl * ltmp = newObject( lhsNamer, new AddressExpr( lhsAlt.expr ) );
    206189                        out.push_back( createAssgn( ltmp, rtmp ) );
    207190                        tmpDecls.push_back( ltmp );
     
    217200                        std::list< ObjectDecl * > ltmp;
    218201                        std::list< ObjectDecl * > rtmp;
    219                         std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( Expression * expr ){
    220                                 return newObject( lhsNamer, new AddressExpr( expr ) );
     202                        std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( ResolvExpr::Alternative & alt ){
     203                                return newObject( lhsNamer, new AddressExpr( alt.expr ) );
    221204                        });
    222                         std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( Expression * expr ){
    223                                 return newObject( rhsNamer, expr );
     205                        std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( ResolvExpr::Alternative & alt ){
     206                                return newObject( rhsNamer, alt.expr );
    224207                        });
    225208                        zipWith( ltmp.begin(), ltmp.end(), rtmp.begin(), rtmp.end(), back_inserter(out), createAssgn );
     
    227210                        tmpDecls.splice( tmpDecls.end(), rtmp );
    228211                }
    229         }
    230 
    231         void TupleAssignSpotter::Options::print( std::ostream &ostr ) {
    232                 for ( ResolvExpr::AltList & l : options ) {
    233                         for ( ResolvExpr::Alternative & alt : l ) {
    234                                 alt.print( ostr );
    235                                 ostr << " ";
    236                         }
    237                         ostr << std::endl;
    238                 } // for
    239212        }
    240213} // namespace Tuples
  • src/Tuples/TupleExpansion.cc

    r12bc63a r3c13c03  
    2323#include "SynTree/Declaration.h"
    2424#include "SynTree/Type.h"
     25#include "SynTree/Expression.h"
     26#include "SynTree/Initializer.h"
    2527#include "SymTab/Mangler.h"
    2628#include "Common/ScopedMap.h"
    2729
    2830namespace Tuples {
    29         class TupleAssignExpander : public Mutator {
    30         public:
    31                 virtual Expression * mutate( TupleAssignExpr * tupleExpr );
    32         };
     31        namespace {
     32                class UniqueExprExpander : public GenPoly::DeclMutator {
     33                public:
     34                        typedef GenPoly::DeclMutator Parent;
     35                        virtual Expression * mutate( UniqueExpr * unqExpr );
     36                        std::map< Expression *, ObjectDecl * > decls;
     37                };
    3338
    34         class TupleTypeReplacer : public GenPoly::DeclMutator {
    35           public:
    36                 typedef GenPoly::DeclMutator Parent;
     39                class TupleAssignExpander : public Mutator {
     40                public:
     41                        typedef Mutator Parent;
     42                        virtual Expression * mutate( TupleAssignExpr * tupleExpr );
     43                };
    3744
    38                 virtual Type * mutate( TupleType * tupleType );
     45                class TupleTypeReplacer : public GenPoly::DeclMutator {
     46                  public:
     47                        typedef GenPoly::DeclMutator Parent;
    3948
    40                 virtual CompoundStmt * mutate( CompoundStmt * stmt ) {
    41                         typeMap.beginScope();
    42                         stmt = Parent::mutate( stmt );
    43                         typeMap.endScope();
    44                         return stmt;
    45                 }
    46           private:
    47                 ScopedMap< std::string, StructDecl * > typeMap;
    48         };
     49                        virtual Type * mutate( TupleType * tupleType );
     50
     51                        virtual CompoundStmt * mutate( CompoundStmt * stmt ) {
     52                                typeMap.beginScope();
     53                                stmt = Parent::mutate( stmt );
     54                                typeMap.endScope();
     55                                return stmt;
     56                        }
     57                  private:
     58                        ScopedMap< std::string, StructDecl * > typeMap;
     59                };
     60
     61                class TupleIndexExpander : public Mutator {
     62                public:
     63                        typedef Mutator Parent;
     64                        virtual Expression * mutate( TupleIndexExpr * tupleExpr );
     65                };
     66
     67                class TupleExprExpander : public Mutator {
     68                public:
     69                        typedef Mutator Parent;
     70                        virtual Expression * mutate( TupleExpr * tupleExpr );
     71                };
     72        }
    4973
    5074        void expandTuples( std::list< Declaration * > & translationUnit ) {
    51                 TupleAssignExpander expander;
    52                 mutateAll( translationUnit, expander );
     75                UniqueExprExpander unqExpander;
     76                unqExpander.mutateDeclarationList( translationUnit );
     77
     78                TupleAssignExpander assnExpander;
     79                mutateAll( translationUnit, assnExpander );
    5380
    5481                TupleTypeReplacer replacer;
    5582                replacer.mutateDeclarationList( translationUnit );
     83
     84                TupleIndexExpander idxExpander;
     85                mutateAll( translationUnit, idxExpander );
     86
     87                TupleExprExpander exprExpander;
     88                mutateAll( translationUnit, exprExpander );
    5689        }
    5790
    58         Expression * TupleAssignExpander::mutate( TupleAssignExpr * tupleExpr ) {
     91        Expression * UniqueExprExpander::mutate( UniqueExpr * unqExpr ) {
     92                static UniqueName tempNamer( "_unq_expr_" );
     93                unqExpr = safe_dynamic_cast< UniqueExpr * > ( Parent::mutate( unqExpr ) );
     94                if ( ! decls.count( unqExpr->get_expr() ) ) {
     95                        // xxx - it's possible (likely?) that expressions can appear in the wrong order because of this. Need to ensure they're placed in the correct location.
     96                        ObjectDecl * decl = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, unqExpr->get_result()->clone(), new SingleInit( unqExpr->get_expr()->clone() ) );
     97                        decls[unqExpr->get_expr()] = decl;
     98                        addDeclaration( decl );
     99                }
     100                return new VariableExpr( decls[unqExpr->get_expr()] );
     101        }
     102
     103        Expression * TupleAssignExpander::mutate( TupleAssignExpr * assnExpr ) {
     104                // xxx - Parent::mutate?
    59105                CompoundStmt * compoundStmt = new CompoundStmt( noLabels );
    60106                std::list< Statement * > & stmts = compoundStmt->get_kids();
    61                 for ( ObjectDecl * obj : tupleExpr->get_tempDecls() ) {
     107                for ( ObjectDecl * obj : assnExpr->get_tempDecls() ) {
    62108                        stmts.push_back( new DeclStmt( noLabels, obj ) );
    63109                }
    64                 for ( Expression * assign : tupleExpr->get_assigns() ) {
    65                         stmts.push_back( new ExprStmt( noLabels, assign ) );
    66                 }
    67                 tupleExpr->get_tempDecls().clear();
    68                 tupleExpr->get_assigns().clear();
    69                 delete tupleExpr;
     110                TupleExpr * tupleExpr = new TupleExpr( assnExpr->get_assigns() );
     111                assert( tupleExpr->get_result() );
     112                stmts.push_back( new ExprStmt( noLabels, tupleExpr ) );
     113                assnExpr->get_tempDecls().clear();
     114                assnExpr->get_assigns().clear();
     115                delete assnExpr;
    70116                return new StmtExpr( compoundStmt );
    71117        }
     
    90136        }
    91137
     138        Expression * TupleIndexExpander::mutate( TupleIndexExpr * tupleExpr ) {
     139                Expression * tuple = maybeMutate( tupleExpr->get_tuple(), *this );
     140                assert( tuple );
     141                tupleExpr->set_tuple( nullptr );
     142                unsigned int idx = tupleExpr->get_index();
     143                delete tupleExpr;
     144
     145                StructInstType * type = safe_dynamic_cast< StructInstType * >( tuple->get_result() );
     146                StructDecl * structDecl = type->get_baseStruct();
     147                assert( structDecl->get_members().size() > idx );
     148                Declaration * member = *std::next(structDecl->get_members().begin(), idx);
     149                return new MemberExpr( safe_dynamic_cast< DeclarationWithType * >( member ), tuple );
     150        }
     151
     152        Expression * TupleExprExpander::mutate( TupleExpr * tupleExpr ) {
     153                assert( tupleExpr->get_result() );
     154                std::list< Initializer * > inits;
     155                for ( Expression * expr : tupleExpr->get_exprs() ) {
     156                        inits.push_back( new SingleInit( expr ) );
     157                }
     158                return new CompoundLiteralExpr( tupleExpr->get_result(), new ListInit( inits ) );
     159        }
     160
     161        TupleType * makeTupleType( const std::list< Expression * > & exprs ) {
     162                TupleType *tupleType = new TupleType( Type::Qualifiers(true, true, true, true, true, false) );
     163                Type::Qualifiers &qualifiers = tupleType->get_qualifiers();
     164                for ( Expression * expr : exprs ) {
     165                        assert( expr->get_result() );
     166                        Type * type = expr->get_result()->clone();
     167                        tupleType->get_types().push_back( type );
     168                        qualifiers &= type->get_qualifiers();
     169                } // for
     170                return tupleType;
     171        }
    92172} // namespace Tuples
    93173
  • src/Tuples/Tuples.h

    r12bc63a r3c13c03  
    3131        // TupleExpansion.cc
    3232        void expandTuples( std::list< Declaration * > & translationUnit );
     33
     34  TupleType * makeTupleType( const std::list< Expression * > & exprs );
    3335} // namespace Tuples
    3436
Note: See TracChangeset for help on using the changeset viewer.