Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    reb3261f ra61fea9a  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CodeGenerator.cc --
     7// CodeGenerator2.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Thu Jun 04 15:00:00 2015
    13 // Update Count     : 125
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jun  3 11:53:32 2015
     13// Update Count     : 13
    1414//
    1515
     
    3535
    3636namespace CodeGen {
    37         int CodeGenerator::tabsize = 4;
    38 
    39         // the kinds of statements that would ideally be separated by more whitespace
    40         bool wantSpacing( Statement * stmt) {
    41                 return dynamic_cast< IfStmt * >( stmt ) || dynamic_cast< CompoundStmt * >( stmt ) ||
    42                         dynamic_cast< WhileStmt * >( stmt ) || dynamic_cast< ForStmt * > ( stmt ) || dynamic_cast< SwitchStmt *>( stmt );
    43         }
    44 
    45         CodeGenerator::CodeGenerator( std::ostream &os ) : cur_indent( 0 ), insideFunction( false ), output( os ) { }
    46 
    47         CodeGenerator::CodeGenerator( std::ostream &os, std::string init, int indent, bool infunp )
    48                         : cur_indent( indent ), insideFunction( infunp ), output( os ) {
    49                 //output << std::string( init );
    50         }
    51 
    52         CodeGenerator::CodeGenerator( std::ostream &os, char *init, int indent, bool infunp )
    53                         : cur_indent( indent ), insideFunction( infunp ), output( os ) {
    54                 //output << std::string( init );
     37        int CodeGenerator2::tabsize = 4;
     38
     39        CodeGenerator2::CodeGenerator2( std::ostream &os ) : cur_indent( 0 ), insideFunction( false ), before( os ), after() { }
     40
     41        CodeGenerator2::CodeGenerator2( std::ostream &os, std::string init, int indent, bool infunp )
     42                        : cur_indent( indent ), insideFunction( infunp ), before( os ) {
     43                //before << std::string( init );
     44        }
     45
     46        CodeGenerator2::CodeGenerator2( std::ostream &os, char *init, int indent, bool infunp )
     47                        : cur_indent( indent ), insideFunction( infunp ), before( os ) {
     48                //before << std::string( init );
    5549        }
    5650
     
    6458 
    6559        //*** Declarations
    66         void CodeGenerator::visit( FunctionDecl *functionDecl ) {
     60        void CodeGenerator2::visit( FunctionDecl *functionDecl ) {
    6761                handleStorageClass( functionDecl );
    6862                if ( functionDecl->get_isInline() ) {
    69                         output << "inline ";
    70                 } // if
    71                 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );
     63                        before << "inline ";
     64                } // if
     65                before << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );
    7266
    7367                // how to get this to the Functype?
    7468                std::list< Declaration * > olds = functionDecl->get_oldDecls();
    7569                if ( ! olds.empty() ) {
    76                         output << " /* function has old declaration */";
     70                        before << " /* function has old declaration */";
    7771                } // if
    7872
     
    8377        }
    8478
    85         void CodeGenerator::visit( ObjectDecl *objectDecl ) {
     79        void CodeGenerator2::visit( ObjectDecl *objectDecl ) {
    8680                handleStorageClass( objectDecl );
    87                 output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
     81                before << genType( objectDecl->get_type(), mangleName( objectDecl ) );
    8882       
    8983                if ( objectDecl->get_init() ) {
    90                         output << " = ";
     84                        before << " = ";
    9185                        objectDecl->get_init()->accept( *this );
    9286                } // if
    9387                if ( objectDecl->get_bitfieldWidth() ) {
    94                         output << ":";
     88                        before << ":";
    9589                        objectDecl->get_bitfieldWidth()->accept( *this );
    9690                } // if
    9791        }
    9892
    99         void CodeGenerator::handleAggregate( AggregateDecl *aggDecl ) {
     93        void CodeGenerator2::handleAggregate( AggregateDecl *aggDecl ) {
    10094                if ( aggDecl->get_name() != "" )
    101                         output << aggDecl->get_name();
     95                        before << aggDecl->get_name();
    10296       
    10397                std::list< Declaration * > &memb = aggDecl->get_members();
    10498
    10599                if ( ! memb.empty() ) {
    106                         output << endl << string( cur_indent, ' ' ) << "{" << endl;
    107 
    108                         cur_indent += CodeGenerator::tabsize;
     100                        before << endl << string( cur_indent, ' ' ) << "{" << endl;
     101
     102                        cur_indent += CodeGenerator2::tabsize;
    109103                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    110                                 output << string( cur_indent, ' ' );
     104                                before << string( cur_indent, ' ' );
    111105                                (*i)->accept(*this );
    112                                 output << ";" << endl;
     106                                before << ";" << endl;
    113107                        }
    114108
    115                         cur_indent -= CodeGenerator::tabsize;
    116 
    117                         output << string( cur_indent, ' ' ) << "}";
    118                 } // if
    119         }
    120 
    121         void CodeGenerator::visit( StructDecl *structDecl ) {
    122                 output << "struct ";
     109                        cur_indent -= CodeGenerator2::tabsize;
     110
     111                        before << string( cur_indent, ' ' ) << "}";
     112                } // if
     113        }
     114
     115        void CodeGenerator2::visit( StructDecl *structDecl ) {
     116                before << "struct ";
    123117                handleAggregate( structDecl );
    124118        }
    125119
    126         void CodeGenerator::visit( UnionDecl *aggregateDecl ) {
    127                 output << "union ";
     120        void CodeGenerator2::visit( UnionDecl *aggregateDecl ) {
     121                before << "union ";
    128122                handleAggregate( aggregateDecl );
    129123        }
    130124 
    131         void CodeGenerator::visit( EnumDecl *aggDecl ) {
    132                 output << "enum ";
     125        void CodeGenerator2::visit( EnumDecl *aggDecl ) {
     126                before << "enum ";
    133127
    134128                if ( aggDecl->get_name() != "" )
    135                         output << aggDecl->get_name();
     129                        before << aggDecl->get_name();
    136130       
    137131                std::list< Declaration* > &memb = aggDecl->get_members();
    138132
    139133                if ( ! memb.empty() ) {
    140                         output << endl << "{" << endl;
    141 
    142                         cur_indent += CodeGenerator::tabsize;
     134                        before << endl << "{" << endl;
     135
     136                        cur_indent += CodeGenerator2::tabsize;
    143137                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    144138                                ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
    145139                                assert( obj );
    146                                 output << string( cur_indent, ' ' ) << mangleName( obj );
     140                                before << string( cur_indent, ' ' ) << mangleName( obj );
    147141                                if ( obj->get_init() ) {
    148                                         output << " = ";
     142                                        before << " = ";
    149143                                        obj->get_init()->accept(*this );
    150144                                } // if
    151                                 output << "," << endl;
     145                                before << "," << endl;
    152146                        } // for
    153147
    154                         cur_indent -= CodeGenerator::tabsize;
    155 
    156                         output << "}" << endl;
    157                 } // if
    158         }
    159  
    160         void CodeGenerator::visit( ContextDecl *aggregateDecl ) {}
    161  
    162         void CodeGenerator::visit( TypedefDecl *typeDecl ) {
    163                 output << "typedef ";
    164                 output << genType( typeDecl->get_base(), typeDecl->get_name() );
    165         }
    166  
    167         void CodeGenerator::visit( TypeDecl *typeDecl ) {
     148                        cur_indent -= CodeGenerator2::tabsize;
     149
     150                        before << "}" << endl;
     151                } // if
     152        }
     153 
     154        void CodeGenerator2::visit( ContextDecl *aggregateDecl ) {}
     155 
     156        void CodeGenerator2::visit( TypedefDecl *typeDecl ) {
     157                before << "typedef ";
     158                before << genType( typeDecl->get_base(), typeDecl->get_name() );
     159        }
     160 
     161        void CodeGenerator2::visit( TypeDecl *typeDecl ) {
    168162                // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
    169163                // still to be done
    170                 output << "extern unsigned long " << typeDecl->get_name();
     164                before << "extern unsigned long " << typeDecl->get_name();
    171165                if ( typeDecl->get_base() ) {
    172                         output << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";
    173                 } // if
    174         }
    175 
    176         void CodeGenerator::visit( SingleInit *init ) {
     166                        before << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";
     167                } // if
     168        }
     169
     170        void CodeGenerator2::visit( SingleInit *init ) {
    177171                init->get_value()->accept( *this );
    178172        }
    179173
    180         void CodeGenerator::visit( ListInit *init ) {
    181                 output << "{ ";
     174        void CodeGenerator2::visit( ListInit *init ) {
     175                before << "{ ";
    182176                genCommaList( init->begin_initializers(), init->end_initializers() );
    183                 output << " }";
    184         }
    185 
    186         void CodeGenerator::visit( Constant *constant ) {
    187                 output << constant->get_value() ;
     177                before << " }";
     178        }
     179
     180        void CodeGenerator2::visit( Constant *constant ) {
     181                before << constant->get_value() ;
    188182        }
    189183
    190184        //*** Expressions
    191         void CodeGenerator::visit( ApplicationExpr *applicationExpr ) {
     185        void CodeGenerator2::visit( ApplicationExpr *applicationExpr ) {
    192186                if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
    193187                        OperatorInfo opInfo;
     
    220214                                        assert( applicationExpr->get_args().size() == 2 );
    221215                                        (*arg++)->accept( *this );
    222                                         output << "[";
    223                                         (*arg)->accept( *this );
    224                                         output << "]";
     216                                        before << "[";
     217                                        (*arg)->accept( *this );
     218                                        before << "]";
    225219                                        break;
    226220             
     
    233227                                  case OT_PREFIXASSIGN:
    234228                                        assert( applicationExpr->get_args().size() == 1 );
    235                                         output << "(";
    236                                         output << opInfo.symbol;
    237                                         (*arg)->accept( *this );
    238                                         output << ")";
     229                                        before << "(";
     230                                        before << opInfo.symbol;
     231                                        (*arg)->accept( *this );
     232                                        before << ")";
    239233                                        break;
    240234             
     
    243237                                        assert( applicationExpr->get_args().size() == 1 );
    244238                                        (*arg)->accept( *this );
    245                                         output << opInfo.symbol;
     239                                        before << opInfo.symbol;
    246240                                        break;
    247241
     
    249243                                  case OT_INFIXASSIGN:
    250244                                        assert( applicationExpr->get_args().size() == 2 );
    251                                         output << "(";
     245                                        before << "(";
    252246                                        (*arg++)->accept( *this );
    253                                         output << opInfo.symbol;
    254                                         (*arg)->accept( *this );
    255                                         output << ")";
     247                                        before << opInfo.symbol;
     248                                        (*arg)->accept( *this );
     249                                        before << ")";
    256250                                        break;
    257251             
     
    262256                        } else {
    263257                                varExpr->accept( *this );
    264                                 output << "(";
     258                                before << "(";
    265259                                genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
    266                                 output << ")";
     260                                before << ")";
    267261                        } // if
    268262                } else {
    269263                        applicationExpr->get_function()->accept( *this );
    270                         output << "(";
     264                        before << "(";
    271265                        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
    272                         output << ")";
    273                 } // if
    274         }
    275  
    276         void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
     266                        before << ")";
     267                } // if
     268        }
     269 
     270        void CodeGenerator2::visit( UntypedExpr *untypedExpr ) {
    277271                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
    278272                        OperatorInfo opInfo;
     
    283277                                        assert( untypedExpr->get_args().size() == 2 );
    284278                                        (*arg++)->accept( *this );
    285                                         output << "[";
    286                                         (*arg)->accept( *this );
    287                                         output << "]";
     279                                        before << "[";
     280                                        (*arg)->accept( *this );
     281                                        before << "]";
    288282                                        break;
    289283             
     
    295289                                  case OT_PREFIXASSIGN:
    296290                                        assert( untypedExpr->get_args().size() == 1 );
    297                                         output << "(";
    298                                         output << opInfo.symbol;
    299                                         (*arg)->accept( *this );
    300                                         output << ")";
     291                                        before << "(";
     292                                        before << opInfo.symbol;
     293                                        (*arg)->accept( *this );
     294                                        before << ")";
    301295                                        break;
    302296             
     
    305299                                        assert( untypedExpr->get_args().size() == 1 );
    306300                                        (*arg)->accept( *this );
    307                                         output << opInfo.symbol;
     301                                        before << opInfo.symbol;
    308302                                        break;
    309303 
     
    311305                                  case OT_INFIXASSIGN:
    312306                                        assert( untypedExpr->get_args().size() == 2 );
    313                                         output << "(";
     307                                        before << "(";
    314308                                        (*arg++)->accept( *this );
    315                                         output << opInfo.symbol;
    316                                         (*arg)->accept( *this );
    317                                         output << ")";
     309                                        before << opInfo.symbol;
     310                                        (*arg)->accept( *this );
     311                                        before << ")";
    318312                                        break;
    319313             
     
    324318                        } else {
    325319                                nameExpr->accept( *this );
    326                                 output << "(";
     320                                before << "(";
    327321                                genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
    328                                 output << ")";
     322                                before << ")";
    329323                        } // if
    330324                } else {
    331325                        untypedExpr->get_function()->accept( *this );
    332                         output << "(";
     326                        before << "(";
    333327                        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
    334                         output << ")";
    335                 } // if
    336         }
    337  
    338         void CodeGenerator::visit( NameExpr *nameExpr ) {
     328                        before << ")";
     329                } // if
     330        }
     331 
     332        void CodeGenerator2::visit( NameExpr *nameExpr ) {
    339333                OperatorInfo opInfo;
    340334                if ( operatorLookup( nameExpr->get_name(), opInfo ) ) {
    341335                        assert( opInfo.type == OT_CONSTANT );
    342                         output << opInfo.symbol;
    343                 } else {
    344                         output << nameExpr->get_name();
    345                 } // if
    346         }
    347  
    348         void CodeGenerator::visit( AddressExpr *addressExpr ) {
    349                 output << "(&";
     336                        before << opInfo.symbol;
     337                } else {
     338                        before << nameExpr->get_name();
     339                } // if
     340        }
     341 
     342        void CodeGenerator2::visit( AddressExpr *addressExpr ) {
     343                before << "(&";
    350344                // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
    351345                if ( VariableExpr *variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {
    352                         output << mangleName( variableExpr->get_var() );
     346                        before << mangleName( variableExpr->get_var() );
    353347                } else {
    354348                        addressExpr->get_arg()->accept( *this );
    355349                } // if
    356                 output << ")";
    357         }
    358 
    359         void CodeGenerator::visit( CastExpr *castExpr ) {
    360                 output << "((";
     350                before << ")";
     351        }
     352
     353        void CodeGenerator2::visit( CastExpr *castExpr ) {
     354                before << "((";
    361355                if ( castExpr->get_results().empty() ) {
    362                         output << "void" ;
    363                 } else {
    364                         output << genType( castExpr->get_results().front(), "" );
    365                 } // if
    366                 output << ")";
     356                        before << "void" ;
     357                } else {
     358                        before << genType( castExpr->get_results().front(), "" );
     359                } // if
     360                before << ")";
    367361                castExpr->get_arg()->accept( *this );
    368                 output << ")";
    369         }
    370  
    371         void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
     362                before << ")";
     363        }
     364 
     365        void CodeGenerator2::visit( UntypedMemberExpr *memberExpr ) {
    372366                assert( false );
    373367        }
    374368 
    375         void CodeGenerator::visit( MemberExpr *memberExpr ) {
     369        void CodeGenerator2::visit( MemberExpr *memberExpr ) {
    376370                memberExpr->get_aggregate()->accept( *this );
    377                 output << "." << mangleName( memberExpr->get_member() );
    378         }
    379  
    380         void CodeGenerator::visit( VariableExpr *variableExpr ) {
     371                before << "." << mangleName( memberExpr->get_member() );
     372        }
     373 
     374        void CodeGenerator2::visit( VariableExpr *variableExpr ) {
    381375                OperatorInfo opInfo;
    382376                if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) {
    383                         output << opInfo.symbol;
    384                 } else {
    385                         output << mangleName( variableExpr->get_var() );
    386                 } // if
    387         }
    388  
    389         void CodeGenerator::visit( ConstantExpr *constantExpr ) {
     377                        before << opInfo.symbol;
     378                } else {
     379                        before << mangleName( variableExpr->get_var() );
     380                } // if
     381        }
     382 
     383        void CodeGenerator2::visit( ConstantExpr *constantExpr ) {
    390384                assert( constantExpr->get_constant() );
    391385                constantExpr->get_constant()->accept( *this );
    392386        }
    393387 
    394         void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
    395                 output << "sizeof(";
     388        void CodeGenerator2::visit( SizeofExpr *sizeofExpr ) {
     389                before << "sizeof(";
    396390                if ( sizeofExpr->get_isType() ) {
    397                         output << genType( sizeofExpr->get_type(), "" );
     391                        before << genType( sizeofExpr->get_type(), "" );
    398392                } else {
    399393                        sizeofExpr->get_expr()->accept( *this );
    400394                } // if
    401                 output << ")";
    402         }
    403  
    404         void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
    405                 output << "(";
     395                before << ")";
     396        }
     397 
     398        void CodeGenerator2::visit( LogicalExpr *logicalExpr ) {
     399                before << "(";
    406400                logicalExpr->get_arg1()->accept( *this );
    407401                if ( logicalExpr->get_isAnd() ) {
    408                         output << " && ";
    409                 } else {
    410                         output << " || ";
     402                        before << " && ";
     403                } else {
     404                        before << " || ";
    411405                } // if
    412406                logicalExpr->get_arg2()->accept( *this );
    413                 output << ")";
    414         }
    415  
    416         void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
    417                 output << "(";
     407                before << ")";
     408        }
     409 
     410        void CodeGenerator2::visit( ConditionalExpr *conditionalExpr ) {
     411                before << "(";
    418412                conditionalExpr->get_arg1()->accept( *this );
    419                 output << " ? ";
     413                before << " ? ";
    420414                conditionalExpr->get_arg2()->accept( *this );
    421                 output << " : ";
     415                before << " : ";
    422416                conditionalExpr->get_arg3()->accept( *this );
    423                 output << ")";
    424         }
    425  
    426         void CodeGenerator::visit( CommaExpr *commaExpr ) {
    427                 output << "(";
     417                before << ")";
     418        }
     419 
     420        void CodeGenerator2::visit( CommaExpr *commaExpr ) {
     421                before << "(";
    428422                commaExpr->get_arg1()->accept( *this );
    429                 output << " , ";
     423                before << " , ";
    430424                commaExpr->get_arg2()->accept( *this );
    431                 output << ")";
    432         }
    433  
    434         void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
    435  
    436         void CodeGenerator::visit( TypeExpr *typeExpr ) {}
    437 
     425                before << ")";
     426        }
     427 
     428        void CodeGenerator2::visit( TupleExpr *tupleExpr ) {}
     429 
     430        void CodeGenerator2::visit( TypeExpr *typeExpr ) {}
     431 
     432 
    438433        //*** Statements
    439         void CodeGenerator::visit( CompoundStmt *compoundStmt ) {
     434        void CodeGenerator2::visit( CompoundStmt *compoundStmt ) {
    440435                std::list<Statement*> ks = compoundStmt->get_kids();
    441                 output << "{" << endl;
    442 
    443                 cur_indent += CodeGenerator::tabsize;
     436
     437                before << endl << string( cur_indent, ' ' ) << "{" << endl;
     438
     439                cur_indent += CodeGenerator2::tabsize;
    444440
    445441                for ( std::list<Statement *>::iterator i = ks.begin(); i != ks.end();  i++) {
    446                         output << string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() );
     442                        before << string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() )  ;
    447443                        (*i)->accept(*this );
    448 
    449                         output << endl;
    450                         if ( wantSpacing( *i ) ) {
    451                                 output << endl;
    452                         }
     444                        shift_left();
     445                        before << endl;
    453446                }
    454                 cur_indent -= CodeGenerator::tabsize;
    455 
    456                 output << string( cur_indent, ' ' ) << "}";
    457         }
    458 
    459         void CodeGenerator::visit( ExprStmt *exprStmt ) {
    460                 // I don't see why this check is necessary.
    461                 // If this starts to cause problems then put it back in,
    462                 // with an explanation
    463                 assert( exprStmt );
    464 
    465                 // if ( exprStmt != 0 ) {
    466                 exprStmt->get_expr()->accept( *this );
    467                 output << ";" ;
    468                 // } // if
    469         }
    470 
    471         void CodeGenerator::visit( IfStmt *ifStmt ) {
    472                 output << "if (";
     447                cur_indent -= CodeGenerator2::tabsize;
     448
     449                before << string( cur_indent, ' ' ) << "}" << endl;
     450        }
     451
     452        void CodeGenerator2::visit( ExprStmt *exprStmt ) {
     453                if ( exprStmt != 0 ) {
     454                        exprStmt->get_expr()->accept( *this );
     455                        shift_left();
     456                        before << ";" ;
     457                } // if
     458        }
     459
     460        void CodeGenerator2::visit( IfStmt *ifStmt ) {
     461                before << "if (";
    473462                ifStmt->get_condition()->accept(*this );
    474                 output << ") ";
    475 
     463                after += ")\n";
     464                shift_left();
     465
     466                cur_indent += CodeGenerator2::tabsize;
     467                before << string( cur_indent, ' ' );
    476468                ifStmt->get_thenPart()->accept(*this );
     469                cur_indent -= CodeGenerator2::tabsize;
     470                shift_left(); before << endl;
    477471
    478472                if ( ifStmt->get_elsePart() != 0) {
    479                         output << " else ";
     473                        before << string( cur_indent, ' ' ) << " else " << endl ;
     474
     475                        cur_indent += CodeGenerator2::tabsize;
    480476                        ifStmt->get_elsePart()->accept(*this );
    481                 } // if
    482         }
    483 
    484         void CodeGenerator::visit( SwitchStmt *switchStmt ) {
    485                 output << "switch (" ;
     477                        cur_indent -= CodeGenerator2::tabsize;
     478                } // if
     479        }
     480
     481        void CodeGenerator2::visit( SwitchStmt *switchStmt ) {
     482                //before << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator2::printLabels( switchStmt->get_labels() )
     483                before << "switch (" ;
    486484                switchStmt->get_condition()->accept(*this );
    487                 output << ") ";
    488                
    489                 output << "{" << std::endl;
    490                 cur_indent += CodeGenerator::tabsize;
    491 
    492                 acceptAll( switchStmt->get_branches(), *this );
    493 
    494                 cur_indent -= CodeGenerator::tabsize;
    495 
    496                 output << string( cur_indent, ' ' ) << "}";
    497         }
    498 
    499         void CodeGenerator::visit( CaseStmt *caseStmt ) {
    500                 output << string( cur_indent, ' ' );
    501                 if ( caseStmt->isDefault()) {
    502                         output << "default";
    503                 } else {
    504                         output << "case ";
     485                after += ")\n";
     486                shift_left();
     487
     488                before << string( cur_indent, ' ' ) << "{" << std::endl;
     489                cur_indent += CodeGenerator2::tabsize;
     490
     491                std::list< Statement * > stmts = switchStmt->get_branches();
     492                bool lastBreak = false;
     493
     494                // horrible, horrible hack
     495                if ( dynamic_cast<BranchStmt *>( stmts.back() ) != 0 ) {
     496                        lastBreak = true;
     497                        stmts.pop_back();
     498                } // if
     499                acceptAll( stmts, *this );
     500                if ( lastBreak ) {
     501                        Statement *st = switchStmt->get_branches().back();
     502                        before << CodeGenerator2::printLabels( st->get_labels());
     503                        st->accept( *this );
     504                } // if
     505         
     506                cur_indent -= CodeGenerator2::tabsize;
     507
     508                before << /* "\r" << */ string( cur_indent, ' ' ) << "}" << endl ;
     509        }
     510
     511        void CodeGenerator2::visit( CaseStmt *caseStmt ) {
     512                before << string( cur_indent, ' ' );
     513                if ( caseStmt->isDefault())
     514                        before << "default "  ;
     515                else {
     516                        before << "case "  ;
    505517                        caseStmt->get_condition()->accept(*this );
    506518                } // if
    507                 output << ":\n";
    508                
     519                after += ":\n";
     520                shift_left();
     521
    509522                std::list<Statement *> sts = caseStmt->get_statements();
    510523
    511                 cur_indent += CodeGenerator::tabsize;
     524                cur_indent += CodeGenerator2::tabsize;
    512525                for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++) {
    513                         output << string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() )  ;
     526                        before << /* "\r" << */ string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() )  ;
    514527                        (*i)->accept(*this );
    515                         output << endl;
     528                        shift_left();
     529                        before << ";" << endl;
    516530                }
    517                 cur_indent -= CodeGenerator::tabsize;
    518         }
    519 
    520         void CodeGenerator::visit( BranchStmt *branchStmt ) {
     531                cur_indent -= CodeGenerator2::tabsize;
     532        }
     533
     534        void CodeGenerator2::visit( BranchStmt *branchStmt ) {
    521535                switch ( branchStmt->get_type()) {
    522536                  case BranchStmt::Goto:
    523537                        if ( ! branchStmt->get_target().empty() )
    524                                 output << "goto " << branchStmt->get_target();
     538                                before << "goto " << branchStmt->get_target();
    525539                        else {
    526540                                if ( branchStmt->get_computedTarget() != 0 ) {
    527                                         output << "goto *";
     541                                        before << "goto *";
    528542                                        branchStmt->get_computedTarget()->accept( *this );
    529543                                } // if
     
    531545                        break;
    532546                  case BranchStmt::Break:
    533                         output << "break";
     547                        before << "break";
    534548                        break;
    535549                  case BranchStmt::Continue:
    536                         output << "continue";
     550                        before << "continue";
    537551                        break;
    538552                }
    539                 output << ";";
    540         }
    541 
    542 
    543         void CodeGenerator::visit( ReturnStmt *returnStmt ) {
    544                 output << "return ";
     553                before << ";";
     554        }
     555
     556
     557        void CodeGenerator2::visit( ReturnStmt *returnStmt ) {
     558                before << "return ";
    545559
    546560                // xxx -- check for null expression;
     
    548562                        returnStmt->get_expr()->accept( *this );
    549563                } // if
    550                 output << ";";
    551         }
    552 
    553         void CodeGenerator::visit( WhileStmt *whileStmt ) {
     564                after += ";";
     565        }
     566
     567        void CodeGenerator2::visit( WhileStmt *whileStmt ) {
    554568                if ( whileStmt->get_isDoWhile() )
    555                         output << "do" ;
     569                        before << "do" ;
    556570                else {
    557                         output << "while (" ;
     571                        before << "while (" ;
    558572                        whileStmt->get_condition()->accept(*this );
    559                         output << ")";
    560                 } // if
    561                 output << " ";
    562 
    563                 output << CodeGenerator::printLabels( whileStmt->get_body()->get_labels() );
     573                        after += ")";
     574                } // if
     575                after += "{\n";
     576                shift_left();
     577
    564578                whileStmt->get_body()->accept( *this );
    565579
    566                 output << string( cur_indent, ' ' );
     580                before << /* "\r" << */ string( cur_indent, ' ' ) << "}" ;
    567581
    568582                if ( whileStmt->get_isDoWhile() ) {
    569                         output << " while (" ;
     583                        before << " while (" ;
    570584                        whileStmt->get_condition()->accept(*this );
    571                         output << ");";
    572                 } // if
    573         }
    574 
    575         void CodeGenerator::visit( ForStmt *forStmt ) {
    576                 output << "for (";
     585                        after += ");";
     586                } // if
     587
     588                after += "\n";
     589        }
     590
     591        void CodeGenerator2::visit( ForStmt *forStmt ) {
     592                before << "for (";
    577593
    578594                if ( forStmt->get_initialization() != 0 )
    579595                        forStmt->get_initialization()->accept( *this );
    580596                else
    581                         output << ";";
    582                
     597                        before << ";";
     598                shift_left();
     599
    583600                if ( forStmt->get_condition() != 0 )
    584601                        forStmt->get_condition()->accept( *this );
    585                 output << ";";
     602                shift_left(); before << ";";
    586603
    587604                if ( forStmt->get_increment() != 0 )
    588605                        forStmt->get_increment()->accept( *this );
    589                 output << ") ";
     606                shift_left(); before << ")" << endl;
    590607
    591608                if ( forStmt->get_body() != 0 ) {
    592                         output << CodeGenerator::printLabels( forStmt->get_body()->get_labels() );
     609                        cur_indent += CodeGenerator2::tabsize;
     610                        before << string( cur_indent, ' ' ) << CodeGenerator2::printLabels( forStmt->get_body()->get_labels() );
    593611                        forStmt->get_body()->accept( *this );
    594                 } // if
    595         }
    596 
    597         void CodeGenerator::visit( NullStmt *nullStmt ) {
    598                 //output << string( cur_indent, ' ' ) << CodeGenerator::printLabels( nullStmt->get_labels() );
    599                 output << "/* null statement */ ;";
    600         }
    601 
    602         void CodeGenerator::visit( DeclStmt *declStmt ) {
     612                        cur_indent -= CodeGenerator2::tabsize;
     613                } // if
     614        }
     615
     616        void CodeGenerator2::visit( NullStmt *nullStmt ) {
     617                //before << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator2::printLabels( nullStmt->get_labels() );
     618                before << "/* null statement */ ;";
     619        }
     620
     621        void CodeGenerator2::visit( DeclStmt *declStmt ) {
    603622                declStmt->get_decl()->accept( *this );
    604623       
    605624                if ( doSemicolon( declStmt->get_decl() ) ) {
    606                         output << ";";
    607                 } // if
    608         }
    609 
    610         std::string CodeGenerator::printLabels( std::list< Label > &l ) {
     625                        after += ";";
     626                } // if
     627                shift_left();
     628        }
     629
     630        std::string CodeGenerator2::printLabels( std::list< Label > &l ) {
    611631                std::string str( "" );
    612                 l.unique(); // assumes a sorted list. Why not use set?
     632                l.unique();
    613633
    614634                for ( std::list< Label >::iterator i = l.begin(); i != l.end(); i++ )
     
    618638        }
    619639
    620         void CodeGenerator::handleStorageClass( Declaration *decl ) {
     640        void CodeGenerator2::shift_left() {
     641                before << after;
     642                after = "";
     643        }
     644
     645        void CodeGenerator2::handleStorageClass( Declaration *decl ) {
    621646                switch ( decl->get_storageClass() ) {
    622647                  case Declaration::NoStorageClass:
    623648                        break;
    624649                  case Declaration::Extern:
    625                         output << "extern ";
     650                        before << "extern ";
    626651                        break;
    627652                  case Declaration::Static:
    628                         output << "static ";
     653                        before << "static ";
    629654                        break;
    630655                  case Declaration::Auto:
     
    632657                        break;
    633658                  case Declaration::Register:
    634                         output << "register ";
     659                        before << "register ";
    635660                        break;
    636661                  case Declaration::Inline:
Note: See TracChangeset for help on using the changeset viewer.