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

added support for the waituntil statement in the compiler

File:
1 edited

Legend:

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