Changeset c86b08d for src


Ignore:
Timestamp:
May 1, 2023, 4:06:07 PM (18 months ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, master
Children:
a33a5e2
Parents:
73bf7ddc
Message:

added support for the waituntil statement in the compiler

Location:
src
Files:
2 added
16 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r73bf7ddc rc86b08d  
    567567        }
    568568
     569    const ast::WhenClause * visit( const ast::WhenClause * node ) override final {
     570                // There is no old-AST WhenClause, so this should never be called.
     571                assert( !node );
     572                return nullptr;
     573        }
     574
    569575        const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
    570576                if ( inCache( node ) ) return nullptr;
     
    573579                for ( auto clause : node->clauses ) {
    574580                        stmt->clauses.push_back({{
    575                                         get<Expression>().accept1( clause->target_func ),
     581                                        get<Expression>().accept1( clause->target ),
    576582                                        get<Expression>().acceptL( clause->target_args ),
    577583                                },
    578584                                get<Statement>().accept1( clause->stmt ),
    579                                 get<Expression>().accept1( clause->cond ),
     585                                get<Expression>().accept1( clause->when_cond ),
    580586                        });
    581587                }
     
    594600        const ast::WaitForClause * visit( const ast::WaitForClause * node ) override final {
    595601                // There is no old-AST WaitForClause, so this should never be called.
     602                assert( !node );
     603                return nullptr;
     604        }
     605
     606    const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final {
     607        // There is no old-AST WaitUntilStmt, so this should never be called.
    596608                assert( !node );
    597609                return nullptr;
     
    21582170                        auto clause = new ast::WaitForClause( old->location );
    21592171
    2160                         clause->target_func = GET_ACCEPT_1(clauses[i].target.function, Expr);
     2172                        clause->target = GET_ACCEPT_1(clauses[i].target.function, Expr);
    21612173                        clause->target_args = GET_ACCEPT_V(clauses[i].target.arguments, Expr);
    21622174                        clause->stmt = GET_ACCEPT_1(clauses[i].statement, Stmt);
    2163                         clause->cond = GET_ACCEPT_1(clauses[i].condition, Expr);
     2175                        clause->when_cond = GET_ACCEPT_1(clauses[i].condition, Expr);
    21642176
    21652177                        stmt->clauses.push_back( clause );
  • src/AST/Fwd.hpp

    r73bf7ddc rc86b08d  
    5858class FinallyClause;
    5959class SuspendStmt;
     60class WhenClause;
    6061class WaitForStmt;
    6162class WaitForClause;
     63class WaitUntilStmt;
    6264class WithStmt;
    6365class DeclStmt;
  • src/AST/Node.cpp

    r73bf7ddc rc86b08d  
    174174template class ast::ptr_base< ast::FinallyClause, ast::Node::ref_type::weak >;
    175175template class ast::ptr_base< ast::FinallyClause, ast::Node::ref_type::strong >;
     176template class ast::ptr_base< ast::WhenClause, ast::Node::ref_type::weak >;
     177template class ast::ptr_base< ast::WhenClause, ast::Node::ref_type::strong >;
    176178template class ast::ptr_base< ast::WaitForStmt, ast::Node::ref_type::weak >;
    177179template class ast::ptr_base< ast::WaitForStmt, ast::Node::ref_type::strong >;
    178180template class ast::ptr_base< ast::WaitForClause, ast::Node::ref_type::weak >;
    179181template class ast::ptr_base< ast::WaitForClause, ast::Node::ref_type::strong >;
     182template class ast::ptr_base< ast::WaitUntilStmt, ast::Node::ref_type::weak >;
     183template class ast::ptr_base< ast::WaitUntilStmt, ast::Node::ref_type::strong >;
    180184template class ast::ptr_base< ast::WithStmt, ast::Node::ref_type::weak >;
    181185template class ast::ptr_base< ast::WithStmt, ast::Node::ref_type::strong >;
  • src/AST/Pass.hpp

    r73bf7ddc rc86b08d  
    162162        const ast::FinallyClause *    visit( const ast::FinallyClause        * ) override final;
    163163        const ast::Stmt *             visit( const ast::SuspendStmt          * ) override final;
     164    const ast::WhenClause *       visit( const ast::WhenClause           * ) override final;
    164165        const ast::Stmt *             visit( const ast::WaitForStmt          * ) override final;
    165166        const ast::WaitForClause *    visit( const ast::WaitForClause        * ) override final;
     167    const ast::Stmt *             visit( const ast::WaitUntilStmt        * ) override final;
    166168        const ast::Decl *             visit( const ast::WithStmt             * ) override final;
    167169        const ast::NullStmt *         visit( const ast::NullStmt             * ) override final;
  • src/AST/Pass.impl.hpp

    r73bf7ddc rc86b08d  
    10661066
    10671067//--------------------------------------------------------------------------
     1068// WhenClause
     1069template< typename core_t >
     1070const ast::WhenClause * ast::Pass< core_t >::visit( const ast::WhenClause * node ) {
     1071        VISIT_START( node );
     1072
     1073        if ( __visit_children() ) {
     1074                maybe_accept( node, &WhenClause::target );
     1075                maybe_accept( node, &WhenClause::stmt );
     1076                maybe_accept( node, &WhenClause::when_cond );
     1077        }
     1078
     1079        VISIT_END( WhenClause, node );
     1080}
     1081
     1082//--------------------------------------------------------------------------
    10681083// WaitForStmt
    10691084template< typename core_t >
     
    10901105
    10911106        if ( __visit_children() ) {
    1092                 maybe_accept( node, &WaitForClause::target_func );
     1107                maybe_accept( node, &WaitForClause::target );
    10931108                maybe_accept( node, &WaitForClause::target_args );
    10941109                maybe_accept( node, &WaitForClause::stmt );
    1095                 maybe_accept( node, &WaitForClause::cond );
     1110                maybe_accept( node, &WaitForClause::when_cond );
    10961111        }
    10971112
    10981113        VISIT_END( WaitForClause, node );
     1114}
     1115
     1116//--------------------------------------------------------------------------
     1117// WaitUntilStmt
     1118template< typename core_t >
     1119const ast::Stmt * ast::Pass< core_t >::visit( const ast::WaitUntilStmt * node ) {
     1120        VISIT_START( node );
     1121
     1122        if ( __visit_children() ) {
     1123                maybe_accept( node, &WaitUntilStmt::clauses );
     1124                maybe_accept( node, &WaitUntilStmt::timeout_time );
     1125                maybe_accept( node, &WaitUntilStmt::timeout_stmt );
     1126                maybe_accept( node, &WaitUntilStmt::timeout_cond );
     1127                maybe_accept( node, &WaitUntilStmt::else_stmt );
     1128                maybe_accept( node, &WaitUntilStmt::else_cond );
     1129        }
     1130
     1131        VISIT_END( Stmt, node );
    10991132}
    11001133
  • src/AST/Print.cpp

    r73bf7ddc rc86b08d  
    208208        }
    209209
     210    void print( const ast::WaitStmt * node ) {
     211                if ( node->timeout_time ) {
     212                        os << indent-1 << "timeout of:" << endl;
     213                        node->timeout_time->accept( *this );
     214
     215                        if ( node->timeout_stmt ) {
     216                                os << indent-1 << "... with statment:" << endl;
     217                                node->timeout_stmt->accept( *this );
     218                        }
     219
     220                        if ( node->timeout_cond ) {
     221                                os << indent-1 << "... with condition:" << endl;
     222                                node->timeout_cond->accept( *this );
     223                        }
     224                }
     225
     226                if ( node->else_stmt ) {
     227                        os << indent-1 << "else:" << endl;
     228                        node->else_stmt->accept( *this );
     229
     230                        if ( node->else_cond ) {
     231                                os << indent-1 << "... with condition:" << endl;
     232                                node->else_cond->accept( *this );
     233                        }
     234                }
     235        }
     236
    210237        void preprint( const ast::NamedTypeDecl * node ) {
    211238                if ( ! node->name.empty() ) {
     
    756783        }
    757784
     785        virtual const ast::WhenClause * visit( const ast::WhenClause * node ) override final {
     786                os << indent-1 << "target: ";
     787                safe_print( node->target );
     788
     789                if ( node->stmt ) {
     790                        os << indent-1 << "... with statment:" << endl;
     791                        node->stmt->accept( *this );
     792                }
     793
     794                if ( node->when_cond ) {
     795                        os << indent-1 << "... with when condition:" << endl;
     796                        node->when_cond->accept( *this );
     797                }
     798
     799                return node;
     800        }
     801
    758802        virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
    759803                os << "Waitfor Statement" << endl;
     
    793837        virtual const ast::WaitForClause * visit( const ast::WaitForClause * node ) override final {
    794838                os << indent-1 << "target function: ";
    795                 safe_print( node->target_func );
     839                safe_print( node->target );
    796840
    797841                if ( !node->target_args.empty() ) {
     
    807851                }
    808852
    809                 if ( node->cond ) {
     853                if ( node->when_cond ) {
    810854                        os << indent-1 << "... with condition:" << endl;
    811                         node->cond->accept( *this );
    812                 }
    813 
     855                        node->when_cond->accept( *this );
     856                }
     857
     858                return node;
     859        }
     860
     861    virtual const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final {
     862                os << "Waituntil Statement" << endl;
     863                indent += 2;
     864                for( const auto & clause : node->clauses ) {
     865                        clause->accept( *this );
     866                }
     867        print(node);    // calls print( const ast::WaitStmt * node )
    814868                return node;
    815869        }
  • src/AST/Stmt.hpp

    r73bf7ddc rc86b08d  
    375375};
    376376
    377 // Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ...
    378 class WaitForStmt final : public Stmt {
    379   public:
    380         std::vector<ptr<WaitForClause>> clauses;
    381         ptr<Expr> timeout_time;
     377// Base class of WaitFor/WaitUntil statements
     378// form: KEYWORD(...) ... timeout(...) ... else ...
     379class WaitStmt : public Stmt {
     380  public:
     381    ptr<Expr> timeout_time;
    382382        ptr<Stmt> timeout_stmt;
    383383        ptr<Expr> timeout_cond;
     
    385385        ptr<Expr> else_cond;
    386386
     387    WaitStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
     388                : Stmt(loc, std::move(labels)) {}
     389
     390  private:
     391    WaitStmt * clone() const override = 0;
     392        MUTATE_FRIEND
     393};
     394
     395// Base class for WaitFor/WaitUntil clauses
     396// form: when( when_cond ) KEYWORD( target ) stmt
     397class WhenClause : public StmtClause {
     398  public:
     399        ptr<Expr> target;
     400        ptr<Stmt> stmt;
     401        ptr<Expr> when_cond;
     402
     403        WhenClause( const CodeLocation & loc )
     404                : StmtClause( loc ) {}
     405
     406        const WhenClause * accept( Visitor & v ) const override { return v.visit( this ); }
     407  private:
     408        WhenClause * clone() const override { return new WhenClause{ *this }; }
     409        MUTATE_FRIEND
     410};
     411
     412// Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ...
     413class WaitForStmt final : public WaitStmt {
     414  public:
     415        std::vector<ptr<WaitForClause>> clauses;
     416
    387417        WaitForStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
    388                 : Stmt(loc, std::move(labels)) {}
     418                : WaitStmt(loc, std::move(labels)) {}
    389419
    390420        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
     
    394424};
    395425
    396 class WaitForClause final : public StmtClause {
    397   public:
    398         ptr<Expr> target_func;
     426class WaitForClause final : public WhenClause {
     427  public:
    399428        std::vector<ptr<Expr>> target_args;
    400         ptr<Stmt> stmt;
    401         ptr<Expr> cond;
    402429
    403430        WaitForClause( const CodeLocation & loc )
    404                 : StmtClause( loc ) {}
     431                : WhenClause( loc ) {}
    405432
    406433        const WaitForClause * accept( Visitor & v ) const override { return v.visit( this ); }
    407434  private:
    408435        WaitForClause * clone() const override { return new WaitForClause{ *this }; }
     436        MUTATE_FRIEND
     437};
     438
     439// waituntil statement: when (...) waituntil (...) ... timeout(...) ... else ...
     440class WaitUntilStmt final : public WaitStmt {
     441  public:
     442    // Non-ast node used during compilation to store data needed to generate predicates
     443    //    and set initial status values for clauses
     444    // Used to create a tree corresponding to the structure of the clauses in a WaitUntil
     445    struct ClauseNode {
     446        enum Op { AND, OR, LEFT_OR, LEAF, ELSE, TIMEOUT } op; // operation/type tag
     447        // LEFT_OR used with TIMEOUT/ELSE to indicate that we ignore right hand side after parsing
     448
     449        ClauseNode * left;
     450        ClauseNode * right;
     451        WhenClause * leaf;  // only set if this node is a leaf (points into vector of clauses)
     452
     453        bool ambiguousWhen; // used to paint nodes of predicate tree based on when() clauses
     454        bool whenState;     // used to track if when_cond is toggled on or off for generating init values
     455        bool childOfAnd;      // true on leaf nodes that are children of AND, false otherwise
     456
     457        ClauseNode( Op op, ClauseNode * left, ClauseNode * right )
     458            : op(op), left(left), right(right), leaf(nullptr),
     459            ambiguousWhen(false), whenState(true), childOfAnd(false) {}
     460        ClauseNode( Op op, WhenClause * leaf )
     461            : op(op), left(nullptr), right(nullptr), leaf(leaf),
     462            ambiguousWhen(false), whenState(true), childOfAnd(false) {}
     463        ClauseNode( WhenClause * leaf ) : ClauseNode(LEAF, leaf) {}
     464       
     465        ~ClauseNode() {
     466            if ( left ) delete left;
     467            if ( right ) delete right;
     468        }
     469    };
     470
     471        std::vector<ptr<WhenClause>> clauses;
     472    ClauseNode * predicateTree;
     473
     474        WaitUntilStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
     475                : WaitStmt(loc, std::move(labels)) {}
     476
     477    ~WaitUntilStmt() { delete predicateTree; }
     478
     479        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
     480  private:
     481        WaitUntilStmt * clone() const override { return new WaitUntilStmt{ *this }; }
    409482        MUTATE_FRIEND
    410483};
  • src/AST/Visitor.hpp

    r73bf7ddc rc86b08d  
    5050    virtual const ast::FinallyClause *    visit( const ast::FinallyClause        * ) = 0;
    5151    virtual const ast::Stmt *             visit( const ast::SuspendStmt          * ) = 0;
     52    virtual const ast::WhenClause *       visit( const ast::WhenClause           * ) = 0;
    5253    virtual const ast::Stmt *             visit( const ast::WaitForStmt          * ) = 0;
    5354    virtual const ast::WaitForClause *    visit( const ast::WaitForClause        * ) = 0;
     55    virtual const ast::Stmt *             visit( const ast::WaitUntilStmt        * ) = 0;
    5456    virtual const ast::Decl *             visit( const ast::WithStmt             * ) = 0;
    5557    virtual const ast::NullStmt *         visit( const ast::NullStmt             * ) = 0;
  • src/Common/CodeLocationTools.cpp

    r73bf7ddc rc86b08d  
    128128    macro(FinallyClause, FinallyClause) \
    129129    macro(SuspendStmt, Stmt) \
     130    macro(WhenClause, WhenClause) \
    130131    macro(WaitForStmt, Stmt) \
    131132    macro(WaitForClause, WaitForClause) \
     133    macro(WaitUntilStmt, Stmt) \
    132134    macro(WithStmt, Decl) \
    133135    macro(NullStmt, NullStmt) \
  • src/Concurrency/WaitforNew.cpp

    r73bf7ddc rc86b08d  
    305305
    306306        const ast::VariableExpr * variableExpr =
    307                 clause->target_func.as<ast::VariableExpr>();
     307                clause->target.as<ast::VariableExpr>();
    308308        ast::Expr * castExpr = new ast::CastExpr(
    309309                location,
    310310                new ast::CastExpr(
    311311                        location,
    312                         clause->target_func,
     312                        clause->target,
    313313                        ast::deepCopy( variableExpr->result.get() ),
    314314                        ast::GeneratedCast ),
     
    325325
    326326        ResolveContext context{ symtab, transUnit().global };
    327         out->push_back( maybeCond( location, clause->cond.get(), {
     327        out->push_back( maybeCond( location, clause->when_cond.get(), {
    328328                makeAccStmt( location, acceptables, index, "is_dtor",
    329                         detectIsDtor( location, clause->target_func ), context ),
     329                        detectIsDtor( location, clause->target ), context ),
    330330                makeAccStmt( location, acceptables, index, "func",
    331331                        funcExpr, context ),
  • src/Concurrency/module.mk

    r73bf7ddc rc86b08d  
    2323        Concurrency/WaitforNew.cpp \
    2424        Concurrency/Waitfor.cc \
    25         Concurrency/Waitfor.h
     25        Concurrency/Waitfor.h \
     26        Concurrency/Waituntil.cpp \
     27        Concurrency/Waituntil.hpp
  • src/Parser/ParseNode.h

    r73bf7ddc rc86b08d  
    441441ast::WaitForStmt * build_waitfor_else( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt );
    442442ast::WaitForStmt * build_waitfor_timeout( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );
     443ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation &, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt );
     444ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation &, ExpressionNode * when, StatementNode * stmt );
     445ast::WaitUntilStmt::ClauseNode * build_waituntil_timeout( const CodeLocation &, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );
     446ast::WaitUntilStmt * build_waituntil_stmt( const CodeLocation &, ast::WaitUntilStmt::ClauseNode * root );
    443447ast::Stmt * build_with( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
    444448ast::Stmt * build_mutex( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
  • src/Parser/StatementNode.cc

    r73bf7ddc rc86b08d  
    377377ast::WaitForStmt * build_waitfor( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
    378378        auto clause = new ast::WaitForClause( location );
    379         clause->target_func = maybeBuild( targetExpr );
     379        clause->target = maybeBuild( targetExpr );
    380380        clause->stmt = maybeMoveBuild( stmt );
    381         clause->cond = notZeroExpr( maybeMoveBuild( when ) );
     381        clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
    382382
    383383        ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );
     
    408408        return existing;
    409409} // build_waitfor_timeout
     410
     411ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
     412    ast::WhenClause * clause = new ast::WhenClause( loc );
     413    clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     414    clause->stmt = maybeMoveBuild( stmt );
     415    clause->target = maybeMoveBuild( targetExpr );
     416    return new ast::WaitUntilStmt::ClauseNode( clause );
     417}
     418ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation & loc, ExpressionNode * when, StatementNode * stmt ) {
     419    ast::WhenClause * clause = new ast::WhenClause( loc );
     420    clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     421    clause->stmt = maybeMoveBuild( stmt );
     422    return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::ELSE, clause );
     423}
     424ast::WaitUntilStmt::ClauseNode * build_waituntil_timeout( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
     425    ast::WhenClause * clause = new ast::WhenClause( loc );
     426    clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     427    clause->stmt = maybeMoveBuild( stmt );
     428    clause->target = maybeMoveBuild( timeout );
     429    return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::TIMEOUT, clause );
     430}
     431
     432ast::WaitUntilStmt * build_waituntil_stmt( const CodeLocation & loc, ast::WaitUntilStmt::ClauseNode * root ) {
     433    ast::WaitUntilStmt * retStmt = new ast::WaitUntilStmt( loc );
     434    retStmt->predicateTree = root;
     435   
     436    // iterative tree traversal
     437    std::vector<ast::WaitUntilStmt::ClauseNode *> nodeStack; // stack needed for iterative traversal
     438    ast::WaitUntilStmt::ClauseNode * currNode = nullptr;
     439    ast::WaitUntilStmt::ClauseNode * lastInternalNode = nullptr;
     440    ast::WaitUntilStmt::ClauseNode * cleanup = nullptr; // used to cleanup removed else/timeout
     441    nodeStack.push_back(root);
     442
     443    do {
     444        currNode = nodeStack.back();
     445        nodeStack.pop_back(); // remove node since it will be processed
     446
     447        switch (currNode->op) {
     448            case ast::WaitUntilStmt::ClauseNode::LEAF:
     449                retStmt->clauses.push_back(currNode->leaf);
     450                break;
     451            case ast::WaitUntilStmt::ClauseNode::ELSE:
     452                retStmt->else_stmt = currNode->leaf->stmt
     453                    ? ast::deepCopy( currNode->leaf->stmt )
     454                    : nullptr;
     455               
     456                retStmt->else_cond = currNode->leaf->when_cond
     457                    ? ast::deepCopy( currNode->leaf->when_cond )
     458                    : nullptr;
     459
     460                delete currNode->leaf;
     461                break;
     462            case ast::WaitUntilStmt::ClauseNode::TIMEOUT:
     463                retStmt->timeout_time = currNode->leaf->target
     464                    ? ast::deepCopy( currNode->leaf->target )
     465                    : nullptr;
     466                retStmt->timeout_stmt = currNode->leaf->stmt
     467                    ? ast::deepCopy( currNode->leaf->stmt )
     468                    : nullptr;
     469                retStmt->timeout_cond = currNode->leaf->when_cond
     470                    ? ast::deepCopy( currNode->leaf->when_cond )
     471                    : nullptr;
     472
     473                delete currNode->leaf;
     474                break;
     475            default:
     476                nodeStack.push_back( currNode->right ); // process right after left
     477                nodeStack.push_back( currNode->left );
     478
     479                // Cut else/timeout out of the tree
     480                if ( currNode->op == ast::WaitUntilStmt::ClauseNode::LEFT_OR ) {
     481                    if ( lastInternalNode )
     482                        lastInternalNode->right = currNode->left;
     483                    else    // if not set then root is LEFT_OR
     484                        retStmt->predicateTree = currNode->left;
     485   
     486                    currNode->left = nullptr;
     487                    cleanup = currNode;
     488                }
     489               
     490                lastInternalNode = currNode;
     491                break;
     492        }
     493    } while ( !nodeStack.empty() );
     494
     495    if ( cleanup ) delete cleanup;
     496
     497    return retStmt;
     498}
    410499
    411500ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) {
  • src/Parser/parser.yy

    r73bf7ddc rc86b08d  
    304304        StatementNode * sn;
    305305        ast::WaitForStmt * wfs;
     306    ast::WaitUntilStmt::ClauseNode * wuscn;
    306307        ast::Expr * constant;
    307308        CondCtl * ifctl;
     
    425426%type<en> when_clause                                   when_clause_opt                         waitfor         waituntil               timeout
    426427%type<sn> waitfor_statement                             waituntil_statement
    427 %type<wfs> wor_waitfor_clause                   waituntil_clause                        wand_waituntil_clause   wor_waituntil_clause
     428%type<wfs> wor_waitfor_clause
     429%type<wuscn> waituntil_clause                   wand_waituntil_clause       wor_waituntil_clause
    428430
    429431// declarations
     
    16831685waituntil_clause:
    16841686        when_clause_opt waituntil statement
    1685                 { printf( "waituntil_clause 1\n" ); $$ = nullptr; }
     1687                { $$ = build_waituntil_clause( yylloc, $1, $2, maybe_build_compound( yylloc, $3 ) ); }
    16861688        | '(' wor_waituntil_clause ')'
    1687                 { printf( "waituntil_clause 2\n" ); $$ = nullptr; }
     1689                { $$ = $2; }
    16881690        ;
    16891691
    16901692wand_waituntil_clause:
    16911693        waituntil_clause                                                                        %prec THEN
    1692                 { printf( "wand_waituntil_clause 1\n" ); $$ = nullptr; }
     1694                { $$ = $1; }
    16931695        | waituntil_clause wand wand_waituntil_clause
    1694                 { printf( "wand_waituntil_clause 2\n" ); $$ = nullptr; }
     1696                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::AND, $1, $3 ); }
    16951697        ;
    16961698
    16971699wor_waituntil_clause:
    16981700        wand_waituntil_clause
    1699                 { printf( "wor_waituntil_clause 1\n" ); $$ = nullptr; }
     1701                { $$ = $1; }
    17001702        | wor_waituntil_clause wor wand_waituntil_clause
    1701                 { printf( "wor_waituntil_clause 2\n" ); $$ = nullptr; }
     1703                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, $1, $3 ); }
    17021704        | wor_waituntil_clause wor when_clause_opt ELSE statement
    1703                 { printf( "wor_waituntil_clause 3\n" ); $$ = nullptr; }
     1705                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_else( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    17041706        | wor_waituntil_clause wor when_clause_opt timeout statement    %prec THEN
    1705                 { printf( "wor_waituntil_clause 4\n" ); $$ = nullptr; }
     1707                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ) ); }
    17061708        // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
    17071709        | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error
    17081710                { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    17091711        | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
    1710                 { printf( "wor_waituntil_clause 6\n" ); $$ = nullptr; }
     1712                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1,
     1713                new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR,
     1714                    build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ),
     1715                    build_waituntil_else( yylloc, $7, maybe_build_compound( yylloc, $9 ) ) ) ); }
    17111716        ;
    17121717
     
    17141719        wor_waituntil_clause                                                            %prec THEN
    17151720                // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement.
    1716                 { $$ = new StatementNode( build_compound( yylloc, nullptr ) ); }
     1721                {
     1722            $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) );
     1723            // $$ = new StatementNode( build_compound( yylloc, nullptr ) );
     1724        }
    17171725        ;
    17181726
  • src/ResolvExpr/Resolver.cc

    r73bf7ddc rc86b08d  
    17301730
    17311731                        // Find all candidates for a function in canonical form
    1732                         funcFinder.find( clause.target_func, ResolvMode::withAdjustment() );
     1732                        funcFinder.find( clause.target, ResolvMode::withAdjustment() );
    17331733
    17341734                        if ( funcFinder.candidates.empty() ) {
    17351735                                stringstream ss;
    17361736                                ss << "Use of undeclared indentifier '";
    1737                                 ss << clause.target_func.strict_as< ast::NameExpr >()->name;
     1737                                ss << clause.target.strict_as< ast::NameExpr >()->name;
    17381738                                ss << "' in call to waitfor";
    17391739                                SemanticError( stmt->location, ss.str() );
     
    19221922                        auto clause2 = new ast::WaitForClause( clause.location );
    19231923
    1924                         clause2->target_func = funcCandidates.front()->expr;
     1924                        clause2->target = funcCandidates.front()->expr;
    19251925
    19261926                        clause2->target_args.reserve( clause.target_args.size() );
     
    19451945
    19461946                        // Resolve the conditions as if it were an IfStmt, statements normally
    1947                         clause2->cond = findSingleExpression( clause.cond, context );
     1947                        clause2->when_cond = findSingleExpression( clause.when_cond, context );
    19481948                        clause2->stmt = clause.stmt->accept( *visitor );
    19491949
  • src/main.cc

    r73bf7ddc rc86b08d  
    4747#include "Concurrency/Keywords.h"           // for implementMutex, implement...
    4848#include "Concurrency/Waitfor.h"            // for generateWaitfor
     49#include "Concurrency/Waituntil.hpp"        // for generateWaitUntil
    4950#include "ControlStruct/ExceptDecl.h"       // for translateExcept
    5051#include "ControlStruct/ExceptTranslate.h"  // for translateThrows, translat...
     
    337338                PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords( transUnit ) );
    338339                PASS( "Forall Pointer Decay", Validate::decayForallPointers( transUnit ) );
     340        PASS( "Implement Waituntil", Concurrency::generateWaitUntil( transUnit ) );
    339341                PASS( "Hoist Control Declarations", ControlStruct::hoistControlDecls( transUnit ) );
    340342
     
    343345                PASS( "Implement Actors", Concurrency::implementActors( transUnit ) );
    344346        PASS( "Implement Virtual Destructors", Virtual::implementVirtDtors(transUnit) );
    345        
    346347                PASS( "Implement Mutex", Concurrency::implementMutex( transUnit ) );
    347348                PASS( "Implement Thread Start", Concurrency::implementThreadStarter( transUnit ) );
Note: See TracChangeset for help on using the changeset viewer.