Ignore:
Timestamp:
May 1, 2023, 4:19:09 PM (14 months ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, master
Children:
c083c3d
Parents:
a50fdfb (diff), 985b624 (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.
Message:

resolved merge conflicts

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/StatementNode.cc

    ra50fdfb r6e1e2d0  
    1111// Created On       : Sat May 16 14:59:41 2015
    1212// Last Modified By : Andrew Beach
    13 // Last Modified On : Tue Apr  4 11:40:00 2023
    14 // Update Count     : 427
     13// Last Modified On : Tue Apr 11 10:16:00 2023
     14// Update Count     : 428
    1515//
     16
     17#include "StatementNode.h"
    1618
    1719#include <cassert>                 // for assert, strict_dynamic_cast, assertf
     
    2325#include "Common/SemanticError.h"  // for SemanticError
    2426#include "Common/utility.h"        // for maybeMoveBuild, maybeBuild
    25 #include "ParseNode.h"             // for StatementNode, ExpressionNode, bui...
     27#include "DeclarationNode.h"       // for DeclarationNode
     28#include "ExpressionNode.h"        // for ExpressionNode
    2629#include "parserutility.h"         // for notZeroExpr
    2730
     
    2932
    3033using namespace std;
     34
     35// Some helpers for cases that really want a single node but check for lists.
     36static const ast::Stmt * buildMoveSingle( StatementNode * node ) {
     37        std::vector<ast::ptr<ast::Stmt>> list;
     38        buildMoveList( node, list );
     39        assertf( list.size() == 1, "CFA Internal Error: Extra/Missing Nodes" );
     40        return list.front().release();
     41}
     42
     43static const ast::Stmt * buildMoveOptional( StatementNode * node ) {
     44        std::vector<ast::ptr<ast::Stmt>> list;
     45        buildMoveList( node, list );
     46        assertf( list.size() <= 1, "CFA Internal Error: Extra Nodes" );
     47        return list.empty() ? nullptr : list.front().release();
     48}
    3149
    3250StatementNode::StatementNode( DeclarationNode * decl ) {
     
    5371} // StatementNode::StatementNode
    5472
    55 StatementNode * StatementNode::append_last_case( StatementNode * stmt ) {
    56         StatementNode * prev = this;
     73StatementNode * StatementNode::add_label(
     74                const CodeLocation & location,
     75                const std::string * name,
     76                DeclarationNode * attr ) {
     77        stmt->labels.emplace_back( location,
     78                *name,
     79                attr ? std::move( attr->attributes )
     80                        : std::vector<ast::ptr<ast::Attribute>>{} );
     81        delete attr;
     82        delete name;
     83        return this;
     84}
     85
     86ClauseNode * ClauseNode::append_last_case( StatementNode * stmt ) {
     87        ClauseNode * prev = this;
    5788        // find end of list and maintain previous pointer
    58         for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) {
    59                 StatementNode * node = strict_dynamic_cast< StatementNode * >(curr);
    60                 assert( nullptr == node->stmt.get() );
     89        for ( ClauseNode * curr = prev; curr != nullptr; curr = (ClauseNode *)curr->get_next() ) {
     90                ClauseNode * node = strict_dynamic_cast< ClauseNode * >(curr);
    6191                assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) );
    6292                prev = curr;
    6393        } // for
     94        ClauseNode * node = dynamic_cast< ClauseNode * >(prev);
    6495        // convert from StatementNode list to Statement list
    65         StatementNode * node = dynamic_cast< StatementNode * >(prev);
    6696        std::vector<ast::ptr<ast::Stmt>> stmts;
    6797        buildMoveList( stmt, stmts );
     
    73103        stmts.clear();
    74104        return this;
    75 } // StatementNode::append_last_case
     105} // ClauseNode::append_last_case
    76106
    77107ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) {
     
    97127                for ( ast::ptr<ast::Stmt> & stmt : inits ) {
    98128                        // build the && of all of the declared variables compared against 0
    99                         //auto declStmt = strict_dynamic_cast<ast::DeclStmt *>( stmt );
    100129                        auto declStmt = stmt.strict_as<ast::DeclStmt>();
    101                         //ast::DeclWithType * dwt = strict_dynamic_cast<ast::DeclWithType *>( declStmt->decl );
    102130                        auto dwt = declStmt->decl.strict_as<ast::DeclWithType>();
    103131                        ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) );
     
    113141        ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
    114142
    115         std::vector<ast::ptr<ast::Stmt>> aststmt;
    116         buildMoveList( then, aststmt );
    117         assert( aststmt.size() == 1 );
    118         ast::Stmt const * astthen = aststmt.front().release();
    119 
    120         ast::Stmt const * astelse = nullptr;
    121         if ( else_ ) {
    122                 std::vector<ast::ptr<ast::Stmt>> aststmt;
    123                 buildMoveList( else_, aststmt );
    124                 assert( aststmt.size() == 1 );
    125                 astelse = aststmt.front().release();
    126         } // if
     143        ast::Stmt const * astthen = buildMoveSingle( then );
     144        ast::Stmt const * astelse = buildMoveOptional( else_ );
    127145
    128146        return new ast::IfStmt( location, astcond, astthen, astelse,
     
    131149} // build_if
    132150
    133 // Temporary work around. Split StmtClause off from StatementNode.
    134 template<typename clause_t>
    135 static 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 
    168 ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) {
     151ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, ClauseNode * stmt ) {
    169152        std::vector<ast::ptr<ast::CaseClause>> aststmt;
    170         buildMoveClauseList( stmt, aststmt );
     153        buildMoveList( stmt, aststmt );
    171154        // If it is not a switch it is a choose statement.
    172155        if ( ! isSwitch ) {
     
    190173} // build_switch
    191174
    192 ast::CaseClause * build_case( ExpressionNode * ctl ) {
     175ast::CaseClause * build_case( const CodeLocation & location, ExpressionNode * ctl ) {
    193176        // stmt starts empty and then added to
    194177        auto expr = maybeMoveBuild( ctl );
    195         return new ast::CaseClause( expr->location, expr, {} );
     178        return new ast::CaseClause( location, expr, {} );
    196179} // build_case
    197180
     
    205188        ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
    206189
    207         std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
    208         buildMoveList( stmt, aststmt );
    209         assert( aststmt.size() == 1 );
    210 
    211         std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
    212         buildMoveList( else_, astelse );
    213         assert( astelse.size() <= 1 );
    214 
    215190        return new ast::WhileDoStmt( location,
    216191                astcond,
    217                 aststmt.front(),
    218                 astelse.empty() ? nullptr : astelse.front().release(),
     192                buildMoveSingle( stmt ),
     193                buildMoveOptional( else_ ),
    219194                std::move( astinit ),
    220                 false
     195                ast::While
    221196        );
    222197} // build_while
    223198
    224199ast::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 );
    227         assert( aststmt.size() == 1 );                                          // compound created if empty
    228 
    229         std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
    230         buildMoveList( else_, astelse );
    231         assert( astelse.size() <= 1 );
    232 
    233200        // do-while cannot have declarations in the contitional, so init is always empty
    234201        return new ast::WhileDoStmt( location,
    235202                notZeroExpr( maybeMoveBuild( ctl ) ),
    236                 aststmt.front(),
    237                 astelse.empty() ? nullptr : astelse.front().release(),
     203                buildMoveSingle( stmt ),
     204                buildMoveOptional( else_ ),
    238205                {},
    239                 true
     206                ast::DoWhile
    240207        );
    241208} // build_do_while
     
    251218        astincr = maybeMoveBuild( forctl->change );
    252219        delete forctl;
    253 
    254         std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
    255         buildMoveList( stmt, aststmt );
    256         assert( aststmt.size() == 1 );
    257 
    258         std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
    259         buildMoveList( else_, astelse );
    260         assert( astelse.size() <= 1 );
    261220
    262221        return new ast::ForStmt( location,
     
    264223                astcond,
    265224                astincr,
    266                 aststmt.front(),
    267                 astelse.empty() ? nullptr : astelse.front().release()
     225                buildMoveSingle( stmt ),
     226                buildMoveOptional( else_ )
    268227        );
    269228} // build_for
     
    326285} // build_resume_at
    327286
    328 ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) {
     287ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, ClauseNode * catch_, ClauseNode * finally_ ) {
    329288        std::vector<ast::ptr<ast::CatchClause>> aststmt;
    330         buildMoveClauseList( catch_, aststmt );
     289        buildMoveList( catch_, aststmt );
    331290        ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) );
    332291        ast::FinallyClause * finallyBlock = nullptr;
     
    342301
    343302ast::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 );
    346         assert( aststmt.size() == 1 );
    347303        return new ast::CatchClause( location,
    348304                kind,
    349305                maybeMoveBuild( decl ),
    350306                maybeMoveBuild( cond ),
    351                 aststmt.front().release()
     307                buildMoveSingle( body )
    352308        );
    353309} // build_catch
    354310
    355311ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) {
    356         std::vector<ast::ptr<ast::Stmt>> aststmt;
    357         buildMoveList( stmt, aststmt );
    358         assert( aststmt.size() == 1 );
    359312        return new ast::FinallyClause( location,
    360                 aststmt.front().strict_as<ast::CompoundStmt>()
     313                strict_dynamic_cast<const ast::CompoundStmt *>(
     314                        buildMoveSingle( stmt )
     315                )
    361316        );
    362317} // build_finally
    363318
    364 ast::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;
    368         if(!stmts.empty()) {
    369                 assert( stmts.size() == 1 );
    370                 then2 = stmts.front().strict_as<ast::CompoundStmt>();
    371         }
    372         auto node = new ast::SuspendStmt( location, then2, ast::SuspendStmt::None );
    373         node->type = type;
    374         return node;
     319ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Kind kind ) {
     320        return new ast::SuspendStmt( location,
     321                strict_dynamic_cast<const ast::CompoundStmt *, nullptr>(
     322                        buildMoveOptional( then )
     323                ),
     324                kind
     325        );
    375326} // build_suspend
    376327
     
    525476
    526477// Question
    527 ast::Stmt * build_asm( const CodeLocation & location, bool voltile, ast::Expr * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
     478ast::Stmt * build_asm( const CodeLocation & location, bool is_volatile, ExpressionNode * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
    528479        std::vector<ast::ptr<ast::Expr>> out, in;
    529480        std::vector<ast::ptr<ast::ConstantExpr>> clob;
     
    533484        buildMoveList( clobber, clob );
    534485        return new ast::AsmStmt( location,
    535                 voltile,
    536                 instruction,
     486                is_volatile,
     487                maybeMoveBuild( instruction ),
    537488                std::move( out ),
    538489                std::move( in ),
Note: See TracChangeset for help on using the changeset viewer.