Changeset c86b08d for src/AST/Stmt.hpp


Ignore:
Timestamp:
May 1, 2023, 4:06:07 PM (14 months 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/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};
Note: See TracChangeset for help on using the changeset viewer.