Ignore:
Timestamp:
Apr 4, 2023, 2:25:52 PM (15 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, ast-experimental, master
Children:
beeff61e, e02e13f
Parents:
4541b09
Message:

Translated parser to the new ast. This incuded a small fix in the resolver so larger expressions can be used in with statements and some updated tests. errors/declaration just is a formatting update. attributes now actually preserves more attributes (unknown if all versions work).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/StatementNode.cc

    r4541b09 rbb7422a  
    1010// Author           : Rodolfo G. Esteves
    1111// Created On       : Sat May 16 14:59:41 2015
    12 // Last Modified By : Peter A. Buhr
    13 // Last Modified On : Wed Mar 29 08:51:23 2023
    14 // Update Count     : 454
     12// Last Modified By : Andrew Beach
     13// Last Modified On : Tue Apr  4 11:40:00 2023
     14// Update Count     : 427
    1515//
    1616
    1717#include <cassert>                 // for assert, strict_dynamic_cast, assertf
    18 #include <list>                    // for list
    1918#include <memory>                  // for unique_ptr
    2019#include <string>                  // for string
    2120
     21#include "AST/Label.hpp"           // for Label
     22#include "AST/Stmt.hpp"            // for Stmt, AsmStmt, BranchStmt, CaseCla...
    2223#include "Common/SemanticError.h"  // for SemanticError
    2324#include "Common/utility.h"        // for maybeMoveBuild, maybeBuild
    2425#include "ParseNode.h"             // for StatementNode, ExpressionNode, bui...
    25 #include "SynTree/Expression.h"    // for Expression, ConstantExpr
    26 #include "SynTree/Label.h"         // for Label, noLabels
    27 #include "SynTree/Declaration.h"
    28 #include "SynTree/Statement.h"     // for Statement, BranchStmt, CaseStmt
    2926#include "parserutility.h"         // for notZeroExpr
    3027
     
    3229
    3330using namespace std;
    34 
    3531
    3632StatementNode::StatementNode( DeclarationNode * decl ) {
     
    3834        DeclarationNode * agg = decl->extractAggregate();
    3935        if ( agg ) {
    40                 StatementNode * nextStmt = new StatementNode( new DeclStmt( maybeBuild( decl ) ) );
     36                StatementNode * nextStmt = new StatementNode(
     37                        new ast::DeclStmt( decl->location, maybeBuild( decl ) ) );
    4138                set_next( nextStmt );
    4239                if ( decl->get_next() ) {
     
    5148                agg = decl;
    5249        } // if
    53         stmt.reset( new DeclStmt( maybeMoveBuild( agg ) ) );
     50        // Local copy to avoid accessing the pointer after it is moved from.
     51        CodeLocation declLocation = agg->location;
     52        stmt.reset( new ast::DeclStmt( declLocation, maybeMoveBuild( agg ) ) );
    5453} // StatementNode::StatementNode
    5554
     
    5958        for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) {
    6059                StatementNode * node = strict_dynamic_cast< StatementNode * >(curr);
    61                 assert( dynamic_cast< CaseStmt * >(node->stmt.get()) );
     60                assert( nullptr == node->stmt.get() );
     61                assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) );
    6262                prev = curr;
    6363        } // for
    6464        // convert from StatementNode list to Statement list
    6565        StatementNode * node = dynamic_cast< StatementNode * >(prev);
    66         list< Statement * > stmts;
     66        std::vector<ast::ptr<ast::Stmt>> stmts;
    6767        buildMoveList( stmt, stmts );
    6868        // splice any new Statements to end of current Statements
    69         CaseStmt * caseStmt = dynamic_cast< CaseStmt * >(node->stmt.get());
    70         caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts );
     69        auto caseStmt = strict_dynamic_cast<ast::CaseClause *>( node->clause.get() );
     70        for ( auto const & newStmt : stmts ) {
     71                caseStmt->stmts.emplace_back( newStmt );
     72        }
     73        stmts.clear();
    7174        return this;
    7275} // StatementNode::append_last_case
    7376
    74 Statement * build_expr( ExpressionNode * ctl ) {
    75         Expression * e = maybeMoveBuild( ctl );
    76 
    77         if ( e ) return new ExprStmt( e );
    78         else return new NullStmt();
     77ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) {
     78        if ( ast::Expr * e = maybeMoveBuild( ctl ) ) {
     79                return new ast::ExprStmt( location, e );
     80        } else {
     81                return new ast::NullStmt( location );
     82        }
    7983} // build_expr
    8084
    81 Expression * build_if_control( CondCtl * ctl, list< Statement * > & init ) {
    82         if ( ctl->init != 0 ) {
    83                 buildMoveList( ctl->init, init );
    84         } // if
    85 
    86         Expression * cond = nullptr;
     85static ast::Expr * build_if_control( CondCtl * ctl,
     86                std::vector<ast::ptr<ast::Stmt>> & inits ) {
     87        assert( inits.empty() );
     88        if ( nullptr != ctl->init ) {
     89                buildMoveList( ctl->init, inits );
     90        } // if
     91
     92        ast::Expr * cond = nullptr;
    8793        if ( ctl->condition ) {
    8894                // compare the provided condition against 0
    8995                cond = notZeroExpr( maybeMoveBuild( ctl->condition ) );
    9096        } else {
    91                 for ( Statement * stmt : init ) {
     97                for ( ast::ptr<ast::Stmt> & stmt : inits ) {
    9298                        // build the && of all of the declared variables compared against 0
    93                         DeclStmt * declStmt = strict_dynamic_cast< DeclStmt * >( stmt );
    94                         DeclarationWithType * dwt = strict_dynamic_cast< DeclarationWithType * >( declStmt->decl );
    95                         Expression * nze = notZeroExpr( new VariableExpr( dwt ) );
    96                         cond = cond ? new LogicalExpr( cond, nze, true ) : nze;
     99                        //auto declStmt = strict_dynamic_cast<ast::DeclStmt *>( stmt );
     100                        auto declStmt = stmt.strict_as<ast::DeclStmt>();
     101                        //ast::DeclWithType * dwt = strict_dynamic_cast<ast::DeclWithType *>( declStmt->decl );
     102                        auto dwt = declStmt->decl.strict_as<ast::DeclWithType>();
     103                        ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) );
     104                        cond = cond ? new ast::LogicalExpr( dwt->location, cond, nze, ast::AndExpr ) : nze;
    97105                }
    98106        }
     
    101109} // build_if_control
    102110
    103 Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ ) {
    104         list< Statement * > astinit;                                            // maybe empty
    105         Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
    106 
    107         Statement * astthen, * astelse = nullptr;
    108         list< Statement * > aststmt;
    109         buildMoveList< Statement, StatementNode >( then, aststmt );
     111ast::Stmt * build_if( const CodeLocation & location, CondCtl * ctl, StatementNode * then, StatementNode * else_ ) {
     112        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
     113        ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
     114
     115        std::vector<ast::ptr<ast::Stmt>> aststmt;
     116        buildMoveList( then, aststmt );
    110117        assert( aststmt.size() == 1 );
    111         astthen = aststmt.front();
    112 
     118        ast::Stmt const * astthen = aststmt.front().release();
     119
     120        ast::Stmt const * astelse = nullptr;
    113121        if ( else_ ) {
    114                 list< Statement * > aststmt;
    115                 buildMoveList< Statement, StatementNode >( else_, aststmt );
     122                std::vector<ast::ptr<ast::Stmt>> aststmt;
     123                buildMoveList( else_, aststmt );
    116124                assert( aststmt.size() == 1 );
    117                 astelse = aststmt.front();
    118         } // if
    119 
    120         return new IfStmt( astcond, astthen, astelse, astinit );
     125                astelse = aststmt.front().release();
     126        } // if
     127
     128        return new ast::IfStmt( location, astcond, astthen, astelse,
     129                std::move( astinit )
     130        );
    121131} // build_if
    122132
    123 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) {
    124         list< Statement * > aststmt;
    125         buildMoveList< Statement, StatementNode >( stmt, aststmt );
    126         if ( ! isSwitch ) {                                                                     // choose statement
    127                 for ( Statement * stmt : aststmt ) {
    128                         CaseStmt * caseStmt = strict_dynamic_cast< CaseStmt * >( stmt );
    129                         if ( ! caseStmt->stmts.empty() ) {                      // code after "case" => end of case list
    130                                 CompoundStmt * block = strict_dynamic_cast< CompoundStmt * >( caseStmt->stmts.front() );
    131                                 block->kids.push_back( new BranchStmt( "", BranchStmt::Break ) );
     133// Temporary work around. Split StmtClause off from StatementNode.
     134template<typename clause_t>
     135static void buildMoveClauseList( StatementNode * firstNode,
     136                std::vector<ast::ptr<clause_t>> & output ) {
     137        SemanticErrorException errors;
     138        std::back_insert_iterator<std::vector<ast::ptr<clause_t>>>
     139                out( output );
     140        StatementNode * cur = firstNode;
     141
     142        while ( cur ) {
     143                try {
     144                        auto clause = cur->clause.release();
     145                        if ( auto result = dynamic_cast<clause_t *>( clause ) ) {
     146                                *out++ = result;
     147                        } else {
     148                                assertf(false, __PRETTY_FUNCTION__ );
     149                                SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
     150                        } // if
     151                } catch( SemanticErrorException & e ) {
     152                        errors.append( e );
     153                } // try
     154                ParseNode * temp = cur->get_next();
     155                // Should not return nullptr, then it is non-homogeneous:
     156                cur = dynamic_cast<StatementNode *>( temp );
     157                if ( !cur && temp ) {
     158                        SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
     159                } // if
     160        } // while
     161        if ( ! errors.isEmpty() ) {
     162                throw errors;
     163        } // if
     164        // Usually in the wrapper.
     165        delete firstNode;
     166}
     167
     168ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) {
     169        std::vector<ast::ptr<ast::CaseClause>> aststmt;
     170        buildMoveClauseList( stmt, aststmt );
     171        // If it is not a switch it is a choose statement.
     172        if ( ! isSwitch ) {
     173                for ( ast::ptr<ast::CaseClause> & stmt : aststmt ) {
     174                        // Code after "case" is the end of case list.
     175                        if ( !stmt->stmts.empty() ) {
     176                                auto mutStmt = ast::mutate( stmt.get() );
     177                                // I believe the stmts are actually always one block.
     178                                auto stmts = mutStmt->stmts.front().get_and_mutate();
     179                                auto block = strict_dynamic_cast<ast::CompoundStmt *>( stmts );
     180                                block->kids.push_back( new ast::BranchStmt( block->location,
     181                                        ast::BranchStmt::Break,
     182                                        ast::Label( block->location ) ) );
     183                                stmt = mutStmt;
    132184                        } // if
    133185                } // for
    134186        } // if
    135187        // aststmt.size() == 0 for switch (...) {}, i.e., no declaration or statements
    136         return new SwitchStmt( maybeMoveBuild( ctl ), aststmt );
     188        return new ast::SwitchStmt( location,
     189                maybeMoveBuild( ctl ), std::move( aststmt ) );
    137190} // build_switch
    138191
    139 Statement * build_case( ExpressionNode * ctl ) {
    140         return new CaseStmt( maybeMoveBuild( ctl ), {} ); // stmt starts empty and then added to
     192ast::CaseClause * build_case( ExpressionNode * ctl ) {
     193        // stmt starts empty and then added to
     194        auto expr = maybeMoveBuild( ctl );
     195        return new ast::CaseClause( expr->location, expr, {} );
    141196} // build_case
    142197
    143 Statement * build_default() {
    144         return new CaseStmt( nullptr, {}, true );                       // stmt starts empty and then added to
     198ast::CaseClause * build_default( const CodeLocation & location ) {
     199        // stmt starts empty and then added to
     200        return new ast::CaseClause( location, nullptr, {} );
    145201} // build_default
    146202
    147 Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) {
    148         list< Statement * > astinit;                                            // maybe empty
    149         Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
    150 
    151         list< Statement * > aststmt;                                            // loop body, compound created if empty
    152         buildMoveList< Statement, StatementNode >( stmt, aststmt );
     203ast::Stmt * build_while( const CodeLocation & location, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) {
     204        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
     205        ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
     206
     207        std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
     208        buildMoveList( stmt, aststmt );
    153209        assert( aststmt.size() == 1 );
    154210
    155         list< Statement * > astelse;                                            // else clause, maybe empty
    156         buildMoveList< Statement, StatementNode >( else_, astelse );
    157 
    158         return new WhileDoStmt( astcond, aststmt.front(), astelse.front(), astinit, false );
     211        std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
     212        buildMoveList( else_, astelse );
     213        assert( astelse.size() <= 1 );
     214
     215        return new ast::WhileDoStmt( location,
     216                astcond,
     217                aststmt.front(),
     218                astelse.empty() ? nullptr : astelse.front().release(),
     219                std::move( astinit ),
     220                false
     221        );
    159222} // build_while
    160223
    161 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) {
    162         list< Statement * > aststmt;                                            // loop body, compound created if empty
    163         buildMoveList< Statement, StatementNode >( stmt, aststmt );
     224ast::Stmt * build_do_while( const CodeLocation & location, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) {
     225        std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
     226        buildMoveList( stmt, aststmt );
    164227        assert( aststmt.size() == 1 );                                          // compound created if empty
    165228
    166         list< Statement * > astelse;                                            // else clause, maybe empty
    167         buildMoveList< Statement, StatementNode >( else_, astelse );
     229        std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
     230        buildMoveList( else_, astelse );
     231        assert( astelse.size() <= 1 );
    168232
    169233        // do-while cannot have declarations in the contitional, so init is always empty
    170         return new WhileDoStmt( notZeroExpr( maybeMoveBuild( ctl ) ), aststmt.front(), astelse.front(), {}, true );
     234        return new ast::WhileDoStmt( location,
     235                notZeroExpr( maybeMoveBuild( ctl ) ),
     236                aststmt.front(),
     237                astelse.empty() ? nullptr : astelse.front().release(),
     238                {},
     239                true
     240        );
    171241} // build_do_while
    172242
    173 Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {
    174         list< Statement * > astinit;                                            // maybe empty
     243ast::Stmt * build_for( const CodeLocation & location, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {
     244        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
    175245        buildMoveList( forctl->init, astinit );
    176246
    177         Expression * astcond = nullptr;                                         // maybe empty
     247        ast::Expr * astcond = nullptr;                                          // maybe empty
    178248        astcond = notZeroExpr( maybeMoveBuild( forctl->condition ) );
    179249
    180         Expression * astincr = nullptr;                                         // maybe empty
     250        ast::Expr * astincr = nullptr;                                          // maybe empty
    181251        astincr = maybeMoveBuild( forctl->change );
    182252        delete forctl;
    183253
    184         list< Statement * > aststmt;                                            // loop body, compound created if empty
    185         buildMoveList< Statement, StatementNode >( stmt, aststmt );
     254        std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
     255        buildMoveList( stmt, aststmt );
    186256        assert( aststmt.size() == 1 );
    187257
    188         list< Statement * > astelse;                                            // else clause, maybe empty
    189         buildMoveList< Statement, StatementNode >( else_, astelse );
    190 
    191         return new ForStmt( astinit, astcond, astincr, aststmt.front(), astelse.front() );
     258        std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
     259        buildMoveList( else_, astelse );
     260        assert( astelse.size() <= 1 );
     261
     262        return new ast::ForStmt( location,
     263                std::move( astinit ),
     264                astcond,
     265                astincr,
     266                aststmt.front(),
     267                astelse.empty() ? nullptr : astelse.front().release()
     268        );
    192269} // build_for
    193270
    194 Statement * build_branch( BranchStmt::Type kind ) {
    195         Statement * ret = new BranchStmt( "", kind );
     271ast::Stmt * build_branch( const CodeLocation & location, ast::BranchStmt::Kind kind ) {
     272        return new ast::BranchStmt( location,
     273                kind,
     274                ast::Label( location )
     275        );
     276} // build_branch
     277
     278ast::Stmt * build_branch( const CodeLocation & location, string * identifier, ast::BranchStmt::Kind kind ) {
     279        ast::Stmt * ret = new ast::BranchStmt( location,
     280                kind,
     281                ast::Label( location, *identifier )
     282        );
     283        delete identifier;                                                                      // allocated by lexer
    196284        return ret;
    197285} // build_branch
    198286
    199 Statement * build_branch( string * identifier, BranchStmt::Type kind ) {
    200         Statement * ret = new BranchStmt( * identifier, kind );
    201         delete identifier;                                                                      // allocated by lexer
    202         return ret;
    203 } // build_branch
    204 
    205 Statement * build_computedgoto( ExpressionNode * ctl ) {
    206         return new BranchStmt( maybeMoveBuild( ctl ), BranchStmt::Goto );
     287ast::Stmt * build_computedgoto( ExpressionNode * ctl ) {
     288        ast::Expr * expr = maybeMoveBuild( ctl );
     289        return new ast::BranchStmt( expr->location, expr );
    207290} // build_computedgoto
    208291
    209 Statement * build_return( ExpressionNode * ctl ) {
    210         list< Expression * > exps;
     292ast::Stmt * build_return( const CodeLocation & location, ExpressionNode * ctl ) {
     293        std::vector<ast::ptr<ast::Expr>> exps;
    211294        buildMoveList( ctl, exps );
    212         return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr );
     295        return new ast::ReturnStmt( location,
     296                exps.size() > 0 ? exps.back().release() : nullptr
     297        );
    213298} // build_return
    214299
    215 Statement * build_throw( ExpressionNode * ctl ) {
    216         list< Expression * > exps;
     300static ast::Stmt * build_throw_stmt(
     301                const CodeLocation & location,
     302                ExpressionNode * ctl,
     303                ast::ExceptionKind kind ) {
     304        std::vector<ast::ptr<ast::Expr>> exps;
    217305        buildMoveList( ctl, exps );
    218306        assertf( exps.size() < 2, "CFA internal error: leaking memory" );
    219         return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr );
     307        return new ast::ThrowStmt( location,
     308                kind,
     309                !exps.empty() ? exps.back().release() : nullptr,
     310                (ast::Expr *)nullptr
     311        );
     312}
     313
     314ast::Stmt * build_throw( const CodeLocation & loc, ExpressionNode * ctl ) {
     315        return build_throw_stmt( loc, ctl, ast::Terminate );
    220316} // build_throw
    221317
    222 Statement * build_resume( ExpressionNode * ctl ) {
    223         list< Expression * > exps;
    224         buildMoveList( ctl, exps );
    225         assertf( exps.size() < 2, "CFA internal error: leaking memory" );
    226         return new ThrowStmt( ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr );
     318ast::Stmt * build_resume( const CodeLocation & loc, ExpressionNode * ctl ) {
     319        return build_throw_stmt( loc, ctl, ast::Resume );
    227320} // build_resume
    228321
    229 Statement * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {
     322ast::Stmt * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {
    230323        (void)ctl;
    231324        (void)target;
     
    233326} // build_resume_at
    234327
    235 Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) {
    236         list< CatchStmt * > aststmt;
    237         buildMoveList< CatchStmt, StatementNode >( catch_, aststmt );
    238         CompoundStmt * tryBlock = strict_dynamic_cast< CompoundStmt * >( maybeMoveBuild( try_ ) );
    239         FinallyStmt * finallyBlock = dynamic_cast< FinallyStmt * >( maybeMoveBuild( finally_ ) );
    240         return new TryStmt( tryBlock, aststmt, finallyBlock );
     328ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) {
     329        std::vector<ast::ptr<ast::CatchClause>> aststmt;
     330        buildMoveClauseList( catch_, aststmt );
     331        ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) );
     332        ast::FinallyClause * finallyBlock = nullptr;
     333        if ( finally_ ) {
     334                finallyBlock = dynamic_cast<ast::FinallyClause *>( finally_->clause.release() );
     335        }
     336        return new ast::TryStmt( location,
     337                tryBlock,
     338                std::move( aststmt ),
     339                finallyBlock
     340        );
    241341} // build_try
    242342
    243 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {
    244         list< Statement * > aststmt;
    245         buildMoveList< Statement, StatementNode >( body, aststmt );
     343ast::CatchClause * build_catch( const CodeLocation & location, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {
     344        std::vector<ast::ptr<ast::Stmt>> aststmt;
     345        buildMoveList( body, aststmt );
    246346        assert( aststmt.size() == 1 );
    247         return new CatchStmt( kind, maybeMoveBuild( decl ), maybeMoveBuild( cond ), aststmt.front() );
     347        return new ast::CatchClause( location,
     348                kind,
     349                maybeMoveBuild( decl ),
     350                maybeMoveBuild( cond ),
     351                aststmt.front().release()
     352        );
    248353} // build_catch
    249354
    250 Statement * build_finally( StatementNode * stmt ) {
    251         list< Statement * > aststmt;
    252         buildMoveList< Statement, StatementNode >( stmt, aststmt );
     355ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) {
     356        std::vector<ast::ptr<ast::Stmt>> aststmt;
     357        buildMoveList( stmt, aststmt );
    253358        assert( aststmt.size() == 1 );
    254         return new FinallyStmt( dynamic_cast< CompoundStmt * >( aststmt.front() ) );
     359        return new ast::FinallyClause( location,
     360                aststmt.front().strict_as<ast::CompoundStmt>()
     361        );
    255362} // build_finally
    256363
    257 SuspendStmt * build_suspend( StatementNode * then, SuspendStmt::Type type ) {
    258         auto node = new SuspendStmt();
    259 
    260         node->type = type;
    261 
    262         list< Statement * > stmts;
    263         buildMoveList< Statement, StatementNode >( then, stmts );
     364ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Type type ) {
     365        std::vector<ast::ptr<ast::Stmt>> stmts;
     366        buildMoveList( then, stmts );
     367        ast::CompoundStmt const * then2 = nullptr;
    264368        if(!stmts.empty()) {
    265369                assert( stmts.size() == 1 );
    266                 node->then = dynamic_cast< CompoundStmt * >( stmts.front() );
     370                then2 = stmts.front().strict_as<ast::CompoundStmt>();
    267371        }
    268 
     372        auto node = new ast::SuspendStmt( location, then2, ast::SuspendStmt::None );
     373        node->type = type;
    269374        return node;
    270375} // build_suspend
    271376
    272 WaitForStmt * build_waitfor( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
    273         WaitForStmt::Target target;
    274         target.function = maybeBuild( targetExpr );
     377ast::WaitForStmt * build_waitfor( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
     378        auto clause = new ast::WaitForClause( location );
     379        clause->target_func = maybeBuild( targetExpr );
     380        clause->stmt = maybeMoveBuild( stmt );
     381        clause->cond = notZeroExpr( maybeMoveBuild( when ) );
    275382
    276383        ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );
    277384        targetExpr->set_next( nullptr );
    278         buildMoveList< Expression >( next, target.arguments );
     385        buildMoveList( next, clause->target_args );
    279386
    280387        delete targetExpr;
    281388
    282         existing->clauses.insert( existing->clauses.begin(), WaitForStmt::Clause{
    283                 std::move( target ),
    284                 maybeMoveBuild( stmt ),
    285                 notZeroExpr( maybeMoveBuild( when ) )
    286         });
     389        existing->clauses.insert( existing->clauses.begin(), clause );
    287390
    288391        return existing;
    289392} // build_waitfor
    290393
    291 WaitForStmt * build_waitfor_else( WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) {
    292         existing->orelse.statement  = maybeMoveBuild( stmt );
    293         existing->orelse.condition  = notZeroExpr( maybeMoveBuild( when ) );
    294 
     394ast::WaitForStmt * build_waitfor_else( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) {
     395        existing->else_stmt = maybeMoveBuild( stmt );
     396        existing->else_cond = notZeroExpr( maybeMoveBuild( when ) );
     397
     398        (void)location;
    295399        return existing;
    296400} // build_waitfor_else
    297401
    298 WaitForStmt * build_waitfor_timeout( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
    299         existing->timeout.time      = maybeMoveBuild( timeout );
    300         existing->timeout.statement = maybeMoveBuild( stmt );
    301         existing->timeout.condition = notZeroExpr( maybeMoveBuild( when ) );
    302 
     402ast::WaitForStmt * build_waitfor_timeout( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
     403        existing->timeout_time = maybeMoveBuild( timeout );
     404        existing->timeout_stmt = maybeMoveBuild( stmt );
     405        existing->timeout_cond = notZeroExpr( maybeMoveBuild( when ) );
     406
     407        (void)location;
    303408        return existing;
    304409} // build_waitfor_timeout
    305410
    306 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
    307         list< Expression * > e;
     411ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) {
     412        std::vector<ast::ptr<ast::Expr>> e;
    308413        buildMoveList( exprs, e );
    309         Statement * s = maybeMoveBuild( stmt );
    310         return new DeclStmt( new WithStmt( e, s ) );
     414        ast::Stmt * s = maybeMoveBuild( stmt );
     415        return new ast::DeclStmt( location, new ast::WithStmt( location, std::move( e ), s ) );
    311416} // build_with
    312417
    313 Statement * build_compound( StatementNode * first ) {
    314         CompoundStmt * cs = new CompoundStmt();
    315         buildMoveList( first, cs->get_kids() );
     418ast::Stmt * build_compound( const CodeLocation & location, StatementNode * first ) {
     419        auto cs = new ast::CompoundStmt( location );
     420        buildMoveList( first, cs->kids );
    316421        return cs;
    317422} // build_compound
     
    321426// statement and wrap it into a compound statement to insert additional code. Hence, all control structures have a
    322427// conical form for code generation.
    323 StatementNode * maybe_build_compound( StatementNode * first ) {
     428StatementNode * maybe_build_compound( const CodeLocation & location, StatementNode * first ) {
    324429        // Optimization: if the control-structure statement is a compound statement, do not wrap it.
    325430        // e.g., if (...) {...} do not wrap the existing compound statement.
    326         if ( ! dynamic_cast<CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr
    327                 CompoundStmt * cs = new CompoundStmt();
    328                 buildMoveList( first, cs->get_kids() );
    329                 return new StatementNode( cs );
     431        if ( !dynamic_cast<ast::CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr
     432                return new StatementNode( build_compound( location, first ) );
    330433        } // if
    331434        return first;
     
    333436
    334437// Question
    335 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
    336         list< Expression * > out, in;
    337         list< ConstantExpr * > clob;
     438ast::Stmt * build_asm( const CodeLocation & location, bool voltile, ast::Expr * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
     439        std::vector<ast::ptr<ast::Expr>> out, in;
     440        std::vector<ast::ptr<ast::ConstantExpr>> clob;
    338441
    339442        buildMoveList( output, out );
    340443        buildMoveList( input, in );
    341444        buildMoveList( clobber, clob );
    342         return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels );
     445        return new ast::AsmStmt( location,
     446                voltile,
     447                instruction,
     448                std::move( out ),
     449                std::move( in ),
     450                std::move( clob ),
     451                gotolabels ? gotolabels->labels : std::vector<ast::Label>()
     452        );
    343453} // build_asm
    344454
    345 Statement * build_directive( string * directive ) {
    346         return new DirectiveStmt( *directive );
     455ast::Stmt * build_directive( const CodeLocation & location, string * directive ) {
     456        auto stmt = new ast::DirectiveStmt( location, *directive );
     457        delete directive;
     458        return stmt;
    347459} // build_directive
    348460
    349 Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt ) {
    350         list< Expression * > expList;
     461ast::Stmt * build_mutex( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) {
     462        std::vector<ast::ptr<ast::Expr>> expList;
    351463        buildMoveList( exprs, expList );
    352         Statement * body = maybeMoveBuild( stmt );
    353         return new MutexStmt( body, expList );
     464        ast::Stmt * body = maybeMoveBuild( stmt );
     465        return new ast::MutexStmt( location, body, std::move( expList ) );
    354466} // build_mutex
    355467
Note: See TracChangeset for help on using the changeset viewer.