Changeset c083c3d for src


Ignore:
Timestamp:
May 1, 2023, 6:15:26 PM (2 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, ast-experimental, master
Children:
67408114
Parents:
4daf79f (diff), 6e1e2d0 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Peter A. Buhr <pabuhr@…> (05/01/23 16:59:14)
git-committer:
Peter A. Buhr <pabuhr@…> (05/01/23 18:15:26)
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src
Files:
2 added
16 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r4daf79f rc083c3d  
    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

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

    r4daf79f rc083c3d  
    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

    r4daf79f rc083c3d  
    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

    r4daf79f rc083c3d  
    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

    r4daf79f rc083c3d  
    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

    r4daf79f rc083c3d  
    378378};
    379379
    380 // Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ...
    381 class WaitForStmt final : public Stmt {
    382   public:
    383         std::vector<ptr<WaitForClause>> clauses;
    384         ptr<Expr> timeout_time;
     380// Base class of WaitFor/WaitUntil statements
     381// form: KEYWORD(...) ... timeout(...) ... else ...
     382class WaitStmt : public Stmt {
     383  public:
     384    ptr<Expr> timeout_time;
    385385        ptr<Stmt> timeout_stmt;
    386386        ptr<Expr> timeout_cond;
     
    388388        ptr<Expr> else_cond;
    389389
     390    WaitStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
     391                : Stmt(loc, std::move(labels)) {}
     392
     393  private:
     394    WaitStmt * clone() const override = 0;
     395        MUTATE_FRIEND
     396};
     397
     398// Base class for WaitFor/WaitUntil clauses
     399// form: when( when_cond ) KEYWORD( target ) stmt
     400class WhenClause : public StmtClause {
     401  public:
     402        ptr<Expr> target;
     403        ptr<Stmt> stmt;
     404        ptr<Expr> when_cond;
     405
     406        WhenClause( const CodeLocation & loc )
     407                : StmtClause( loc ) {}
     408
     409        const WhenClause * accept( Visitor & v ) const override { return v.visit( this ); }
     410  private:
     411        WhenClause * clone() const override { return new WhenClause{ *this }; }
     412        MUTATE_FRIEND
     413};
     414
     415// Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ...
     416class WaitForStmt final : public WaitStmt {
     417  public:
     418        std::vector<ptr<WaitForClause>> clauses;
     419
    390420        WaitForStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
    391                 : Stmt(loc, std::move(labels)) {}
     421                : WaitStmt(loc, std::move(labels)) {}
    392422
    393423        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
     
    398428
    399429// Clause in a waitfor statement: waitfor (..., ...) ...
    400 class WaitForClause final : public StmtClause {
    401   public:
    402         ptr<Expr> target_func;
     430class WaitForClause final : public WhenClause {
     431  public:
    403432        std::vector<ptr<Expr>> target_args;
    404         ptr<Stmt> stmt;
    405         ptr<Expr> cond;
    406433
    407434        WaitForClause( const CodeLocation & loc )
    408                 : StmtClause( loc ) {}
     435                : WhenClause( loc ) {}
    409436
    410437        const WaitForClause * accept( Visitor & v ) const override { return v.visit( this ); }
    411438  private:
    412439        WaitForClause * clone() const override { return new WaitForClause{ *this }; }
     440        MUTATE_FRIEND
     441};
     442
     443// waituntil statement: when (...) waituntil (...) ... timeout(...) ... else ...
     444class WaitUntilStmt final : public WaitStmt {
     445  public:
     446    // Non-ast node used during compilation to store data needed to generate predicates
     447    //    and set initial status values for clauses
     448    // Used to create a tree corresponding to the structure of the clauses in a WaitUntil
     449    struct ClauseNode {
     450        enum Op { AND, OR, LEFT_OR, LEAF, ELSE, TIMEOUT } op; // operation/type tag
     451        // LEFT_OR used with TIMEOUT/ELSE to indicate that we ignore right hand side after parsing
     452
     453        ClauseNode * left;
     454        ClauseNode * right;
     455        WhenClause * leaf;  // only set if this node is a leaf (points into vector of clauses)
     456
     457        bool ambiguousWhen; // used to paint nodes of predicate tree based on when() clauses
     458        bool whenState;     // used to track if when_cond is toggled on or off for generating init values
     459        bool childOfAnd;      // true on leaf nodes that are children of AND, false otherwise
     460
     461        ClauseNode( Op op, ClauseNode * left, ClauseNode * right )
     462            : op(op), left(left), right(right), leaf(nullptr),
     463            ambiguousWhen(false), whenState(true), childOfAnd(false) {}
     464        ClauseNode( Op op, WhenClause * leaf )
     465            : op(op), left(nullptr), right(nullptr), leaf(leaf),
     466            ambiguousWhen(false), whenState(true), childOfAnd(false) {}
     467        ClauseNode( WhenClause * leaf ) : ClauseNode(LEAF, leaf) {}
     468       
     469        ~ClauseNode() {
     470            if ( left ) delete left;
     471            if ( right ) delete right;
     472        }
     473    };
     474
     475        std::vector<ptr<WhenClause>> clauses;
     476    ClauseNode * predicateTree;
     477
     478        WaitUntilStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} )
     479                : WaitStmt(loc, std::move(labels)) {}
     480
     481    ~WaitUntilStmt() { delete predicateTree; }
     482
     483        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
     484  private:
     485        WaitUntilStmt * clone() const override { return new WaitUntilStmt{ *this }; }
    413486        MUTATE_FRIEND
    414487};
  • src/AST/Visitor.hpp

    r4daf79f rc083c3d  
    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

    r4daf79f rc083c3d  
    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

    r4daf79f rc083c3d  
    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

    r4daf79f rc083c3d  
    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/StatementNode.cc

    r4daf79f rc083c3d  
    328328ast::WaitForStmt * build_waitfor( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
    329329        auto clause = new ast::WaitForClause( location );
    330         clause->target_func = maybeBuild( targetExpr );
     330        clause->target = maybeBuild( targetExpr );
    331331        clause->stmt = maybeMoveBuild( stmt );
    332         clause->cond = notZeroExpr( maybeMoveBuild( when ) );
     332        clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
    333333
    334334        ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );
     
    359359        return existing;
    360360} // build_waitfor_timeout
     361
     362ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
     363    ast::WhenClause * clause = new ast::WhenClause( loc );
     364    clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     365    clause->stmt = maybeMoveBuild( stmt );
     366    clause->target = maybeMoveBuild( targetExpr );
     367    return new ast::WaitUntilStmt::ClauseNode( clause );
     368}
     369ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation & loc, ExpressionNode * when, StatementNode * stmt ) {
     370    ast::WhenClause * clause = new ast::WhenClause( loc );
     371    clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     372    clause->stmt = maybeMoveBuild( stmt );
     373    return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::ELSE, clause );
     374}
     375ast::WaitUntilStmt::ClauseNode * build_waituntil_timeout( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
     376    ast::WhenClause * clause = new ast::WhenClause( loc );
     377    clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     378    clause->stmt = maybeMoveBuild( stmt );
     379    clause->target = maybeMoveBuild( timeout );
     380    return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::TIMEOUT, clause );
     381}
     382
     383ast::WaitUntilStmt * build_waituntil_stmt( const CodeLocation & loc, ast::WaitUntilStmt::ClauseNode * root ) {
     384    ast::WaitUntilStmt * retStmt = new ast::WaitUntilStmt( loc );
     385    retStmt->predicateTree = root;
     386   
     387    // iterative tree traversal
     388    std::vector<ast::WaitUntilStmt::ClauseNode *> nodeStack; // stack needed for iterative traversal
     389    ast::WaitUntilStmt::ClauseNode * currNode = nullptr;
     390    ast::WaitUntilStmt::ClauseNode * lastInternalNode = nullptr;
     391    ast::WaitUntilStmt::ClauseNode * cleanup = nullptr; // used to cleanup removed else/timeout
     392    nodeStack.push_back(root);
     393
     394    do {
     395        currNode = nodeStack.back();
     396        nodeStack.pop_back(); // remove node since it will be processed
     397
     398        switch (currNode->op) {
     399            case ast::WaitUntilStmt::ClauseNode::LEAF:
     400                retStmt->clauses.push_back(currNode->leaf);
     401                break;
     402            case ast::WaitUntilStmt::ClauseNode::ELSE:
     403                retStmt->else_stmt = currNode->leaf->stmt
     404                    ? ast::deepCopy( currNode->leaf->stmt )
     405                    : nullptr;
     406               
     407                retStmt->else_cond = currNode->leaf->when_cond
     408                    ? ast::deepCopy( currNode->leaf->when_cond )
     409                    : nullptr;
     410
     411                delete currNode->leaf;
     412                break;
     413            case ast::WaitUntilStmt::ClauseNode::TIMEOUT:
     414                retStmt->timeout_time = currNode->leaf->target
     415                    ? ast::deepCopy( currNode->leaf->target )
     416                    : nullptr;
     417                retStmt->timeout_stmt = currNode->leaf->stmt
     418                    ? ast::deepCopy( currNode->leaf->stmt )
     419                    : nullptr;
     420                retStmt->timeout_cond = currNode->leaf->when_cond
     421                    ? ast::deepCopy( currNode->leaf->when_cond )
     422                    : nullptr;
     423
     424                delete currNode->leaf;
     425                break;
     426            default:
     427                nodeStack.push_back( currNode->right ); // process right after left
     428                nodeStack.push_back( currNode->left );
     429
     430                // Cut else/timeout out of the tree
     431                if ( currNode->op == ast::WaitUntilStmt::ClauseNode::LEFT_OR ) {
     432                    if ( lastInternalNode )
     433                        lastInternalNode->right = currNode->left;
     434                    else    // if not set then root is LEFT_OR
     435                        retStmt->predicateTree = currNode->left;
     436   
     437                    currNode->left = nullptr;
     438                    cleanup = currNode;
     439                }
     440               
     441                lastInternalNode = currNode;
     442                break;
     443        }
     444    } while ( !nodeStack.empty() );
     445
     446    if ( cleanup ) delete cleanup;
     447
     448    return retStmt;
     449}
    361450
    362451ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) {
  • src/Parser/StatementNode.h

    r4daf79f rc083c3d  
    100100ast::WaitForStmt * build_waitfor_else( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt );
    101101ast::WaitForStmt * build_waitfor_timeout( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );
     102ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation &, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt );
     103ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation &, ExpressionNode * when, StatementNode * stmt );
     104ast::WaitUntilStmt::ClauseNode * build_waituntil_timeout( const CodeLocation &, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );
     105ast::WaitUntilStmt * build_waituntil_stmt( const CodeLocation &, ast::WaitUntilStmt::ClauseNode * root );
    102106ast::Stmt * build_with( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
    103107ast::Stmt * build_mutex( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
  • src/Parser/parser.yy

    r4daf79f rc083c3d  
    307307        ClauseNode * clause;
    308308        ast::WaitForStmt * wfs;
     309    ast::WaitUntilStmt::ClauseNode * wucn;
    309310        CondCtl * ifctl;
    310311        ForCtrl * forctl;
     
    427428%type<expr> when_clause                                 when_clause_opt                         waitfor         waituntil               timeout
    428429%type<stmt> waitfor_statement                           waituntil_statement
    429 %type<wfs> wor_waitfor_clause                   waituntil_clause                        wand_waituntil_clause   wor_waituntil_clause
     430%type<wfs> wor_waitfor_clause
     431%type<wucn> waituntil_clause                    wand_waituntil_clause       wor_waituntil_clause
    430432
    431433// declarations
     
    16851687waituntil_clause:
    16861688        when_clause_opt waituntil statement
    1687                 { printf( "waituntil_clause 1\n" ); $$ = nullptr; }
     1689                { $$ = build_waituntil_clause( yylloc, $1, $2, maybe_build_compound( yylloc, $3 ) ); }
    16881690        | '(' wor_waituntil_clause ')'
    1689                 { printf( "waituntil_clause 2\n" ); $$ = nullptr; }
     1691                { $$ = $2; }
    16901692        ;
    16911693
    16921694wand_waituntil_clause:
    16931695        waituntil_clause                                                                        %prec THEN
    1694                 { printf( "wand_waituntil_clause 1\n" ); $$ = nullptr; }
     1696                { $$ = $1; }
    16951697        | waituntil_clause wand wand_waituntil_clause
    1696                 { printf( "wand_waituntil_clause 2\n" ); $$ = nullptr; }
     1698                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::AND, $1, $3 ); }
    16971699        ;
    16981700
    16991701wor_waituntil_clause:
    17001702        wand_waituntil_clause
    1701                 { printf( "wor_waituntil_clause 1\n" ); $$ = nullptr; }
     1703                { $$ = $1; }
    17021704        | wor_waituntil_clause wor wand_waituntil_clause
    1703                 { printf( "wor_waituntil_clause 2\n" ); $$ = nullptr; }
     1705                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, $1, $3 ); }
    17041706        | wor_waituntil_clause wor when_clause_opt ELSE statement
    1705                 { printf( "wor_waituntil_clause 3\n" ); $$ = nullptr; }
     1707                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_else( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    17061708        | wor_waituntil_clause wor when_clause_opt timeout statement    %prec THEN
    1707                 { printf( "wor_waituntil_clause 4\n" ); $$ = nullptr; }
     1709                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ) ); }
    17081710        // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
    17091711        | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error
    17101712                { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    17111713        | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
    1712                 { printf( "wor_waituntil_clause 6\n" ); $$ = nullptr; }
     1714                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1,
     1715                new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR,
     1716                    build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ),
     1717                    build_waituntil_else( yylloc, $7, maybe_build_compound( yylloc, $9 ) ) ) ); }
    17131718        ;
    17141719
     
    17161721        wor_waituntil_clause                                                            %prec THEN
    17171722                // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement.
    1718                 { $$ = new StatementNode( build_compound( yylloc, nullptr ) ); }
     1723                {
     1724            $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) );
     1725            // $$ = new StatementNode( build_compound( yylloc, nullptr ) );
     1726        }
    17191727        ;
    17201728
  • src/ResolvExpr/Resolver.cc

    r4daf79f rc083c3d  
    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

    r4daf79f rc083c3d  
    4848#include "Concurrency/Keywords.h"           // for implementMutex, implement...
    4949#include "Concurrency/Waitfor.h"            // for generateWaitfor
     50#include "Concurrency/Waituntil.hpp"        // for generateWaitUntil
    5051#include "ControlStruct/ExceptDecl.h"       // for translateExcept
    5152#include "ControlStruct/ExceptTranslate.h"  // for translateThrows, translat...
     
    340341                PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords, transUnit );
    341342                PASS( "Forall Pointer Decay", Validate::decayForallPointers, transUnit );
     343        PASS( "Implement Waituntil", Concurrency::generateWaitUntil, transUnit  );
    342344                PASS( "Hoist Control Declarations", ControlStruct::hoistControlDecls, transUnit );
    343345
Note: See TracChangeset for help on using the changeset viewer.