Changes in / [5da9d6a:3ca540f]


Ignore:
Location:
src
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r5da9d6a r3ca540f  
    10121012        }
    10131013
     1014        void CodeGenerator::postvisit( WithStmt * with ) {
     1015                if ( ! genC ) {
     1016                        output << "with ( ";
     1017                        genCommaList( with->exprs.begin(), with->exprs.end() );
     1018                        output << " ) ";
     1019                }
     1020                with->stmt->accept( *visitor );
     1021        }
    10141022
    10151023        void CodeGenerator::postvisit( WhileStmt * whileStmt ) {
  • src/CodeGen/CodeGenerator.h

    r5da9d6a r3ca540f  
    102102                void postvisit( CatchStmt * );
    103103                void postvisit( WaitForStmt * );
     104                void postvisit( WithStmt * );
    104105                void postvisit( WhileStmt * );
    105106                void postvisit( ForStmt * );
  • src/Common/PassVisitor.h

    r5da9d6a r3ca540f  
    8181        virtual void visit( FinallyStmt * finallyStmt ) override final;
    8282        virtual void visit( WaitForStmt * waitforStmt ) override final;
     83        virtual void visit( WithStmt * withStmt ) override final;
    8384        virtual void visit( NullStmt * nullStmt ) override final;
    8485        virtual void visit( DeclStmt * declStmt ) override final;
     
    172173        virtual Statement * mutate( FinallyStmt * finallyStmt ) override final;
    173174        virtual Statement * mutate( WaitForStmt * waitforStmt ) override final;
     175        virtual Statement * mutate( WithStmt * withStmt ) override final;
    174176        virtual NullStmt * mutate( NullStmt * nullStmt ) override final;
    175177        virtual Statement * mutate( DeclStmt * declStmt ) override final;
     
    296298        void indexerAddUnionFwd ( UnionDecl           * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
    297299        void indexerAddTrait    ( TraitDecl           * node ) { indexer_impl_addTrait    ( pass, 0, node ); }
     300        void indexerAddWith     ( WithStmt            * node ) { indexer_impl_addWith    ( pass, 0, node ); }
     301
    298302
    299303        template< typename TreeType, typename VisitorType >
  • src/Common/PassVisitor.impl.h

    r5da9d6a r3ca540f  
    985985}
    986986
     987
     988
     989//--------------------------------------------------------------------------
     990// NullStmt
     991template< typename pass_type >
     992void PassVisitor< pass_type >::visit( WithStmt * node ) {
     993        VISIT_START( node );
     994        maybeAccept_impl( node->exprs, *this );
     995        {
     996                // catch statements introduce a level of scope (for the caught exception)
     997                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     998                indexerAddWith( node );
     999                maybeAccept_impl( node->stmt, *this );
     1000        }
     1001        VISIT_END( node );
     1002}
     1003
     1004template< typename pass_type >
     1005Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) {
     1006        MUTATE_START( node );
     1007        maybeMutate_impl( node->exprs, *this );
     1008        {
     1009                // catch statements introduce a level of scope (for the caught exception)
     1010                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1011                indexerAddWith( node );
     1012                maybeMutate_impl( node->stmt, *this );
     1013        }
     1014        MUTATE_END( Statement, node );
     1015}
     1016
    9871017//--------------------------------------------------------------------------
    9881018// NullStmt
  • src/Common/PassVisitor.proto.h

    r5da9d6a r3ca540f  
    208208INDEXER_FUNC( addUnion  , UnionDecl *           );
    209209INDEXER_FUNC( addTrait  , TraitDecl *           );
     210INDEXER_FUNC( addWith   , WithStmt *            );
    210211
    211212
  • src/GenPoly/InstantiateGeneric.cc

    r5da9d6a r3ca540f  
    453453                        return false;
    454454                }
    455 
    456                 AggregateDecl * getAggr( Type * t ) {
    457                         if ( StructInstType * inst = dynamic_cast< StructInstType * >( t ) ) {
    458                                 return inst->baseStruct;
    459                         } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( t ) ) {
    460                                 return inst->baseUnion;
    461                         }
    462                         assertf( false, "Non-aggregate type: %s", toString( t ).c_str() );
    463                 }
    464455        }
    465456
     
    469460                if ( isGenericType( memberExpr->aggregate->result ) ) {
    470461                        // find the location of the member
    471                         AggregateDecl * aggr = getAggr( memberExpr->aggregate->result );
     462                        AggregateDecl * aggr = memberExpr->aggregate->result->getAggr();
    472463                        std::list< Declaration * > & members = aggr->members;
    473464                        memberIndex = std::distance( members.begin(), std::find( members.begin(), members.end(), memberExpr->member ) );
     
    479470                if ( memberIndex != -1 ) {
    480471                        // using the location from the generic type, find the member in the instantiation and rebuild the member expression
    481                         AggregateDecl * aggr = getAggr( memberExpr->aggregate->result );
     472                        AggregateDecl * aggr = memberExpr->aggregate->result->getAggr();
    482473                        assertf( memberIndex < (int)aggr->members.size(), "Instantiation somehow has fewer members than the generic type." );
    483474                        Declaration * member = *std::next( aggr->members.begin(), memberIndex );
  • src/Parser/ParseNode.h

    r5da9d6a r3ca540f  
    408408WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
    409409WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
     410WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
    410411
    411412//##############################################################################
  • src/Parser/StatementNode.cc

    r5da9d6a r3ca540f  
    282282        node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) );
    283283
    284         node->orelse.statement = maybeMoveBuild<Statement >( else_stmt );
     284        node->orelse.statement  = maybeMoveBuild<Statement >( else_stmt );
    285285        node->orelse.condition  = notZeroExpr( maybeMoveBuild<Expression>( else_when ) );
    286286
    287287        return node;
     288}
     289
     290WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
     291        std::list< Expression * > e;
     292        buildMoveList( exprs, e );
     293        Statement * s = maybeMoveBuild<Statement>( stmt );
     294        return new WithStmt( e, s );
    288295}
    289296
  • src/Parser/parser.yy

    r5da9d6a r3ca540f  
    10581058with_statement:
    10591059        WITH '(' tuple_expression_list ')' statement
    1060                 { throw SemanticError("With clause is currently unimplemented."); $$ = nullptr; } // FIX ME
     1060                {
     1061                        $$ = new StatementNode( build_with( $3, $5 ) );
     1062                }
    10611063        ;
    10621064
  • src/ResolvExpr/AlternativeFinder.cc

    r5da9d6a r3ca540f  
    8383        }
    8484
     85        void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt ) {
     86                Indenter indent = { Indenter::tabsize, indentAmt };
     87                for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
     88                        i->print( os, indent );
     89                        os << std::endl;
     90                }
     91        }
     92
    8593        namespace {
    86                 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 ) {
    87                         Indenter indent = { Indenter::tabsize, indentAmt };
    88                         for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
    89                                 i->print( os, indent );
    90                                 os << std::endl;
    91                         }
    92                 }
    93 
    9494                void makeExprList( const AltList &in, std::list< Expression* > &out ) {
    9595                        for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
  • src/ResolvExpr/AlternativeFinder.h

    r5da9d6a r3ca540f  
    174174
    175175        Cost sumCost( const AltList &in );
     176        void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 );
    176177
    177178        template< typename InputIterator >
     
    181182                }
    182183        }
     184
    183185} // namespace ResolvExpr
    184186
  • src/ResolvExpr/Resolver.cc

    r5da9d6a r3ca540f  
    7474                void previsit( CatchStmt *catchStmt );
    7575                void previsit( WaitForStmt * stmt );
     76                void previsit( WithStmt * withStmt );
    7677
    7778                void previsit( SingleInit *singleInit );
     
    571572        }
    572573
     574        bool isStructOrUnion( Type * t ) {
     575                t = t->stripReferences();
     576                return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t );
     577        }
     578
     579        void Resolver::previsit( WithStmt * withStmt ) {
     580                for ( Expression *& expr : withStmt->exprs )  {
     581                        TypeEnvironment env;
     582                        AlternativeFinder finder( indexer, env );
     583                        finder.findWithAdjustment( expr );
     584
     585                        // only struct- and union-typed expressions are viable candidates
     586                        AltList candidates;
     587                        for ( Alternative & alt : finder.get_alternatives() ) {
     588                                if ( isStructOrUnion( alt.expr->result ) ) {
     589                                        candidates.push_back( std::move( alt ) );
     590                                }
     591                        }
     592
     593                        // choose the lowest cost expression among the candidates
     594                        AltList winners;
     595                        findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) );
     596                        if ( winners.size() == 0 ) {
     597                                throw SemanticError( "No reasonable alternatives for with statement expression: ", expr );
     598                        } else if ( winners.size() != 1 ) {
     599                                std::ostringstream stream;
     600                                stream << "Cannot choose between " << winners.size() << " alternatives for with statement expression\n";
     601                                expr->print( stream );
     602                                stream << "Alternatives are:\n";
     603                                printAlts( winners, stream, 1 );
     604                                throw SemanticError( stream.str() );
     605                        }
     606
     607                        // there is one unambiguous interpretation - move the expression into the with statement
     608                        Alternative & alt = winners.front();
     609                        finishExpr( alt.expr, alt.env, expr->env );
     610                        delete expr;
     611                        expr = alt.expr;
     612                        alt.expr = nullptr;
     613                }
     614        }
     615
    573616        template< typename T >
    574617        bool isCharType( T t ) {
  • src/SymTab/Indexer.cc

    r5da9d6a r3ca540f  
    567567        }
    568568
     569        void Indexer::addWith( WithStmt * stmt ) {
     570                for ( Expression * expr : stmt->exprs ) {
     571                        if ( expr->result ) {
     572                                AggregateDecl * aggr = expr->result->getAggr();
     573                                assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() );
     574
     575                                // xxx - this is wrong, needs to somehow hook up chain of objects
     576                                for ( Declaration * decl : aggr->members ) {
     577                                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
     578                                                addId( dwt );
     579                                        }
     580                                }
     581                        }
     582                }
     583        }
     584
    569585        void Indexer::addIds( const std::list< DeclarationWithType * > & decls ) {
    570586                for ( auto d : decls ) {
  • src/SymTab/Indexer.h

    r5da9d6a r3ca540f  
    7676                void addTrait( TraitDecl *decl );
    7777
     78                /// adds all of the IDs from WithStmt exprs
     79                void addWith( WithStmt * );
     80
    7881                /// convenience function for adding a list of Ids to the indexer
    7982                void addIds( const std::list< DeclarationWithType * > & decls );
  • src/SynTree/Mutator.cc

    r5da9d6a r3ca540f  
    203203}
    204204
     205Statement * Mutator::mutate( WithStmt * withStmt ) {
     206        mutateAll( withStmt->exprs, *this );
     207        withStmt->stmt = maybeMutate( withStmt->stmt, *this );
     208        return withStmt;
     209}
     210
    205211NullStmt * Mutator::mutate( NullStmt *nullStmt ) {
    206212        return nullStmt;
  • src/SynTree/Mutator.h

    r5da9d6a r3ca540f  
    5050        virtual Statement * mutate( FinallyStmt * catchStmt );
    5151        virtual Statement * mutate( WaitForStmt * waitforStmt );
     52        virtual Statement * mutate( WithStmt * withStmt );
    5253        virtual NullStmt * mutate( NullStmt * nullStmt );
    5354        virtual Statement * mutate( DeclStmt * declStmt );
  • src/SynTree/ReferenceToType.cc

    r5da9d6a r3ca540f  
    7070bool StructInstType::isComplete() const { return baseStruct ? baseStruct->has_body() : false; }
    7171
     72AggregateDecl * StructInstType::getAggr() { return baseStruct; }
     73
    7274void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
    7375        assert( baseStruct );
     
    101103
    102104bool UnionInstType::isComplete() const { return baseUnion ? baseUnion->has_body() : false; }
     105
     106AggregateDecl * UnionInstType::getAggr() { return baseUnion; }
    103107
    104108void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
  • src/SynTree/Statement.cc

    r5da9d6a r3ca540f  
    456456}
    457457
     458
     459WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Statement(), exprs( exprs ), stmt( stmt ) {}
     460WithStmt::WithStmt( const WithStmt & other ) : Statement( other ), stmt( maybeClone( other.stmt ) ) {
     461        cloneAll( other.exprs, exprs );
     462}
     463WithStmt::~WithStmt() {
     464        deleteAll( exprs );
     465        delete stmt;
     466}
     467
     468void WithStmt::print( std::ostream & os, Indenter indent ) const {
     469        os << "With statement" << endl;
     470        os << indent << "... with statement:" << endl << indent+1;
     471        stmt->print( os, indent+1 );
     472}
     473
     474
    458475NullStmt::NullStmt( const std::list<Label> & labels ) : Statement( labels ) {
    459476}
  • src/SynTree/Statement.h

    r5da9d6a r3ca540f  
    431431};
    432432
     433class WithStmt : public Statement {
     434public:
     435        std::list< Expression * > exprs;
     436        Statement * stmt;
     437
     438        WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
     439        WithStmt( const WithStmt & other );
     440        virtual ~WithStmt();
     441
     442        virtual WithStmt * clone() const override { return new WithStmt( *this ); }
     443        virtual void accept( Visitor & v ) override { v.visit( this ); }
     444        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     445        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     446};
     447
    433448
    434449// represents a declaration that occurs as part of a compound statement
  • src/SynTree/SynTree.h

    r5da9d6a r3ca540f  
    5555class FinallyStmt;
    5656class WaitForStmt;
     57class WithStmt;
    5758class NullStmt;
    5859class DeclStmt;
  • src/SynTree/Type.h

    r5da9d6a r3ca540f  
    178178        virtual bool isComplete() const { return true; }
    179179
     180        virtual AggregateDecl * getAggr() {     assertf( false, "Non-aggregate type: %s", toString( this ).c_str() ); }
     181
    180182        virtual Type *clone() const = 0;
    181183        virtual void accept( Visitor & v ) = 0;
     
    405407        virtual bool isComplete() const override;
    406408
     409        virtual AggregateDecl * getAggr() override;
     410
    407411        /// Looks up the members of this struct named "name" and places them into "foundDecls".
    408412        /// Clones declarations into "foundDecls", caller responsible for freeing
     
    436440
    437441        virtual bool isComplete() const override;
     442
     443        virtual AggregateDecl * getAggr() override;
    438444
    439445        /// looks up the members of this union named "name" and places them into "foundDecls"
  • src/SynTree/Visitor.cc

    r5da9d6a r3ca540f  
    174174}
    175175
    176 void Visitor::visit( __attribute__((unused)) NullStmt *nullStmt ) {
     176void Visitor::visit( WithStmt * withStmt ) {
     177        acceptAll( withStmt->exprs, *this );
     178        maybeAccept( withStmt->stmt, *this );
     179}
     180
     181void Visitor::visit( NullStmt * ) {
    177182}
    178183
  • src/SynTree/Visitor.h

    r5da9d6a r3ca540f  
    5252        virtual void visit( FinallyStmt * finallyStmt );
    5353        virtual void visit( WaitForStmt * waitforStmt );
     54        virtual void visit( WithStmt * withStmt );
    5455        virtual void visit( NullStmt * nullStmt );
    5556        virtual void visit( DeclStmt * declStmt );
Note: See TracChangeset for help on using the changeset viewer.