Changeset c083c3d for src/Parser


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/Parser
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.