Changeset a025ea8


Ignore:
Timestamp:
Oct 24, 2020, 9:40:24 AM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
76d73fc
Parents:
9b0c3ec5
Message:

add maybe_build_compound to always build a compound statement for control structures with a single statement

Location:
src/Parser
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ParseNode.h

    r9b0c3ec5 ra025ea8  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul  6 09:33:32 2020
    13 // Update Count     : 892
     12// Last Modified On : Sat Oct 24 03:53:54 2020
     13// Update Count     : 895
    1414//
    1515
     
    205205struct TypeData;
    206206
    207 class DeclarationNode : public ParseNode {
    208   public:
     207struct DeclarationNode : public ParseNode {
    209208        // These enumerations must harmonize with their names in DeclarationNode.cc.
    210209        enum BasicType { Void, Bool, Char, Int, Int128,
     
    304303        bool get_inLine() const { return inLine; }
    305304        DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
    306   public:
     305
    307306        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
    308307
     
    360359//##############################################################################
    361360
    362 class StatementNode final : public ParseNode {
    363   public:
     361struct StatementNode final : public ParseNode {
    364362        StatementNode() { stmt = nullptr; }
    365363        StatementNode( Statement * stmt ) : stmt( stmt ) {}
     
    382380                os << stmt.get() << std::endl;
    383381        }
    384   private:
     382
    385383        std::unique_ptr<Statement> stmt;
    386384}; // StatementNode
     
    426424Statement * build_finally( StatementNode * stmt );
    427425Statement * build_compound( StatementNode * first );
     426StatementNode * maybe_build_compound( StatementNode * first );
    428427Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
    429428Statement * build_directive( std::string * directive );
  • src/Parser/StatementNode.cc

    r9b0c3ec5 ra025ea8  
    1010// Created On       : Sat May 16 14:59:41 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Aug  4 09:39:25 2018
    13 // Update Count     : 363
     12// Last Modified On : Sat Oct 24 04:20:55 2020
     13// Update Count     : 383
    1414//
    1515
     
    345345} // build_compound
    346346
     347// A single statement in a control structure is always converted to a compound statement so subsequent generated code
     348// can be placed within this compound statement. Otherwise, code generation has to constantly check for a single
     349// statement and wrap it into a compound statement to insert additional code. Hence, all control structures have a
     350// conical form for code generation.
     351StatementNode * maybe_build_compound( StatementNode * first ) {
     352        // Optimization: if the control-structure statement is a compound statement, do not wrap it.
     353        // e.g., if (...) {...} do not wrap the existing compound statement.
     354        if ( ! dynamic_cast<CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr
     355                CompoundStmt * cs = new CompoundStmt();
     356                buildMoveList( first, cs->get_kids() );
     357                return new StatementNode( cs );
     358        } // if
     359        return first;
     360} // maybe_build_compound
     361
    347362Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
    348363        std::list< Expression * > out, in;
  • src/Parser/parser.yy

    r9b0c3ec5 ra025ea8  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Oct  9 18:09:09 2020
    13 // Update Count     : 4614
     12// Last Modified On : Sat Oct 24 08:21:14 2020
     13// Update Count     : 4624
    1414//
    1515
     
    10801080        IF '(' if_control_expression ')' statement                      %prec THEN
    10811081                // explicitly deal with the shift/reduce conflict on if/else
    1082                 { $$ = new StatementNode( build_if( $3, $5, nullptr ) ); }
     1082                { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); }
    10831083        | IF '(' if_control_expression ')' statement ELSE statement
    1084                 { $$ = new StatementNode( build_if( $3, $5, $7 ) ); }
     1084                { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound( $7 ) ) ); }
    10851085        ;
    10861086
     
    11301130
    11311131case_clause:                                                                                    // CFA
    1132         case_label_list statement                                       { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); }
     1132        case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( $2 ) ); }
    11331133        ;
    11341134
     
    11481148iteration_statement:
    11491149        WHILE '(' push if_control_expression ')' statement pop
    1150                 { $$ = new StatementNode( build_while( $4, $6 ) ); }
     1150                { $$ = new StatementNode( build_while( $4, maybe_build_compound( $6 ) ) ); }
    11511151        | WHILE '(' ')' statement                                                       // CFA => while ( 1 )
    1152                 { $$ = new StatementNode( build_while( new IfCtrl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), $4 ) ); }
     1152                { $$ = new StatementNode( build_while( new IfCtrl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); }
    11531153        | DO statement WHILE '(' comma_expression ')' ';'
    1154                 { $$ = new StatementNode( build_do_while( $5, $2 ) ); }
     1154                { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); }
    11551155        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    1156                 { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), $2 ) ); }
     1156                { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); }
    11571157        | FOR '(' push for_control_expression_list ')' statement pop
    1158                 { $$ = new StatementNode( build_for( $4, $6 ) ); }
     1158                { $$ = new StatementNode( build_for( $4, maybe_build_compound( $6 ) ) ); }
    11591159        | FOR '(' ')' statement                                                         // CFA => for ( ;; )
    1160                 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), $4 ) ); }
     1160                { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); }
    11611161        ;
    11621162
     
    13411341waitfor_clause:
    13421342        when_clause_opt waitfor statement                                       %prec THEN
    1343                 { $$ = build_waitfor( $2, $3, $1 ); }
     1343                { $$ = build_waitfor( $2, maybe_build_compound( $3 ), $1 ); }
    13441344        | when_clause_opt waitfor statement WOR waitfor_clause
    1345                 { $$ = build_waitfor( $2, $3, $1, $5 ); }
     1345                { $$ = build_waitfor( $2, maybe_build_compound( $3 ), $1, $5 ); }
    13461346        | when_clause_opt timeout statement                                     %prec THEN
    1347                 { $$ = build_waitfor_timeout( $2, $3, $1 ); }
     1347                { $$ = build_waitfor_timeout( $2, maybe_build_compound( $3 ), $1 ); }
    13481348        | when_clause_opt ELSE statement
    1349                 { $$ = build_waitfor_timeout( nullptr, $3, $1 ); }
     1349                { $$ = build_waitfor_timeout( nullptr, maybe_build_compound( $3 ), $1 ); }
    13501350                // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
    13511351        | when_clause_opt timeout statement WOR ELSE statement
    13521352                { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    13531353        | when_clause_opt timeout statement WOR when_clause ELSE statement
    1354                 { $$ = build_waitfor_timeout( $2, $3, $1, $7, $5 ); }
     1354                { $$ = build_waitfor_timeout( $2, maybe_build_compound( $3 ), $1, maybe_build_compound( $7 ), $5 ); }
    13551355        ;
    13561356
Note: See TracChangeset for help on using the changeset viewer.