Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/CodeGen/CodeGenerator.cc	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// CodeGenerator2.cc -- 
+// CodeGenerator.cc -- 
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jun  3 11:53:32 2015
-// Update Count     : 13
+// Last Modified On : Thu Jun  4 14:05:45 2015
+// Update Count     : 120
 //
 
@@ -35,16 +35,22 @@
 
 namespace CodeGen {
-	int CodeGenerator2::tabsize = 4;
-
-	CodeGenerator2::CodeGenerator2( std::ostream &os ) : cur_indent( 0 ), insideFunction( false ), before( os ), after() { }
-
-	CodeGenerator2::CodeGenerator2( std::ostream &os, std::string init, int indent, bool infunp )
-			: cur_indent( indent ), insideFunction( infunp ), before( os ) {
-		//before << std::string( init );
-	}
-
-	CodeGenerator2::CodeGenerator2( std::ostream &os, char *init, int indent, bool infunp )
-			: cur_indent( indent ), insideFunction( infunp ), before( os ) {
-		//before << std::string( init );
+	int CodeGenerator::tabsize = 4;
+
+	// the kinds of statements that would ideally be separated by more whitespace
+	bool wantSpacing( Statement * stmt) {
+		return dynamic_cast< IfStmt * >( stmt ) || dynamic_cast< CompoundStmt * >( stmt ) ||
+			dynamic_cast< WhileStmt * >( stmt ) || dynamic_cast< ForStmt * > ( stmt ) || dynamic_cast< SwitchStmt *>( stmt );
+	}
+
+	CodeGenerator::CodeGenerator( std::ostream &os ) : cur_indent( 0 ), insideFunction( false ), output( os ) { }
+
+	CodeGenerator::CodeGenerator( std::ostream &os, std::string init, int indent, bool infunp )
+			: cur_indent( indent ), insideFunction( infunp ), output( os ) {
+		//output << std::string( init );
+	}
+
+	CodeGenerator::CodeGenerator( std::ostream &os, char *init, int indent, bool infunp )
+			: cur_indent( indent ), insideFunction( infunp ), output( os ) {
+		//output << std::string( init );
 	}
 
@@ -58,15 +64,15 @@
   
 	//*** Declarations
-	void CodeGenerator2::visit( FunctionDecl *functionDecl ) {
+	void CodeGenerator::visit( FunctionDecl *functionDecl ) {
 		handleStorageClass( functionDecl );
 		if ( functionDecl->get_isInline() ) {
-			before << "inline ";
-		} // if
-		before << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );
+			output << "inline ";
+		} // if
+		output << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );
 
 		// how to get this to the Functype?
 		std::list< Declaration * > olds = functionDecl->get_oldDecls();
 		if ( ! olds.empty() ) {
-			before << " /* function has old declaration */";
+			output << " /* function has old declaration */";
 		} // if
 
@@ -77,111 +83,111 @@
 	}
 
-	void CodeGenerator2::visit( ObjectDecl *objectDecl ) {
+	void CodeGenerator::visit( ObjectDecl *objectDecl ) {
 		handleStorageClass( objectDecl );
-		before << genType( objectDecl->get_type(), mangleName( objectDecl ) );
+		output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
 	
 		if ( objectDecl->get_init() ) {
-			before << " = ";
+			output << " = ";
 			objectDecl->get_init()->accept( *this );
 		} // if
 		if ( objectDecl->get_bitfieldWidth() ) {
-			before << ":";
+			output << ":";
 			objectDecl->get_bitfieldWidth()->accept( *this );
 		} // if
 	}
 
-	void CodeGenerator2::handleAggregate( AggregateDecl *aggDecl ) {
+	void CodeGenerator::handleAggregate( AggregateDecl *aggDecl ) {
 		if ( aggDecl->get_name() != "" )
-			before << aggDecl->get_name();
+			output << aggDecl->get_name();
 	
 		std::list< Declaration * > &memb = aggDecl->get_members();
 
 		if ( ! memb.empty() ) {
-			before << endl << string( cur_indent, ' ' ) << "{" << endl;
-
-			cur_indent += CodeGenerator2::tabsize; 
+			output << endl << string( cur_indent, ' ' ) << "{" << endl;
+
+			cur_indent += CodeGenerator::tabsize; 
 			for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
-				before << string( cur_indent, ' ' ); 
+				output << string( cur_indent, ' ' ); 
 				(*i)->accept(*this );
-				before << ";" << endl;
+				output << ";" << endl;
 			}
 
-			cur_indent -= CodeGenerator2::tabsize; 
-
-			before << string( cur_indent, ' ' ) << "}";
-		} // if
-	}
-
-	void CodeGenerator2::visit( StructDecl *structDecl ) {
-		before << "struct ";
+			cur_indent -= CodeGenerator::tabsize; 
+
+			output << string( cur_indent, ' ' ) << "}";
+		} // if
+	}
+
+	void CodeGenerator::visit( StructDecl *structDecl ) {
+		output << "struct ";
 		handleAggregate( structDecl );
 	}
 
-	void CodeGenerator2::visit( UnionDecl *aggregateDecl ) {
-		before << "union ";
+	void CodeGenerator::visit( UnionDecl *aggregateDecl ) {
+		output << "union ";
 		handleAggregate( aggregateDecl );
 	}
   
-	void CodeGenerator2::visit( EnumDecl *aggDecl ) {
-		before << "enum ";
+	void CodeGenerator::visit( EnumDecl *aggDecl ) {
+		output << "enum ";
 
 		if ( aggDecl->get_name() != "" )
-			before << aggDecl->get_name();
+			output << aggDecl->get_name();
 	
 		std::list< Declaration* > &memb = aggDecl->get_members();
 
 		if ( ! memb.empty() ) {
-			before << endl << "{" << endl;
-
-			cur_indent += CodeGenerator2::tabsize; 
+			output << endl << "{" << endl;
+
+			cur_indent += CodeGenerator::tabsize; 
 			for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
 				ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
 				assert( obj );
-				before << string( cur_indent, ' ' ) << mangleName( obj ); 
+				output << string( cur_indent, ' ' ) << mangleName( obj ); 
 				if ( obj->get_init() ) {
-					before << " = ";
+					output << " = ";
 					obj->get_init()->accept(*this );
 				} // if
-				before << "," << endl;
+				output << "," << endl;
 			} // for
 
-			cur_indent -= CodeGenerator2::tabsize; 
-
-			before << "}" << endl;
-		} // if
-	}
-  
-	void CodeGenerator2::visit( ContextDecl *aggregateDecl ) {}
-  
-	void CodeGenerator2::visit( TypedefDecl *typeDecl ) {
-		before << "typedef ";
-		before << genType( typeDecl->get_base(), typeDecl->get_name() );
-	}
-  
-	void CodeGenerator2::visit( TypeDecl *typeDecl ) {
+			cur_indent -= CodeGenerator::tabsize; 
+
+			output << "}" << endl;
+		} // if
+	}
+  
+	void CodeGenerator::visit( ContextDecl *aggregateDecl ) {}
+  
+	void CodeGenerator::visit( TypedefDecl *typeDecl ) {
+		output << "typedef ";
+		output << genType( typeDecl->get_base(), typeDecl->get_name() );
+	}
+  
+	void CodeGenerator::visit( TypeDecl *typeDecl ) {
 		// really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
 		// still to be done
-		before << "extern unsigned long " << typeDecl->get_name();
+		output << "extern unsigned long " << typeDecl->get_name();
 		if ( typeDecl->get_base() ) {
-			before << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";
-		} // if
-	}
-
-	void CodeGenerator2::visit( SingleInit *init ) {
+			output << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";
+		} // if
+	}
+
+	void CodeGenerator::visit( SingleInit *init ) {
 		init->get_value()->accept( *this );
 	}
 
-	void CodeGenerator2::visit( ListInit *init ) {
-		before << "{ ";
+	void CodeGenerator::visit( ListInit *init ) {
+		output << "{ ";
 		genCommaList( init->begin_initializers(), init->end_initializers() );
-		before << " }";
-	}
-
-	void CodeGenerator2::visit( Constant *constant ) { 
-		before << constant->get_value() ;
+		output << " }";
+	}
+
+	void CodeGenerator::visit( Constant *constant ) { 
+		output << constant->get_value() ;
 	}
 
 	//*** Expressions
-	void CodeGenerator2::visit( ApplicationExpr *applicationExpr ) {
+	void CodeGenerator::visit( ApplicationExpr *applicationExpr ) {
 		if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
 			OperatorInfo opInfo;
@@ -214,7 +220,7 @@
 					assert( applicationExpr->get_args().size() == 2 );
 					(*arg++)->accept( *this );
-					before << "[";
-					(*arg)->accept( *this );
-					before << "]";
+					output << "[";
+					(*arg)->accept( *this );
+					output << "]";
 					break;
 	      
@@ -227,8 +233,8 @@
 				  case OT_PREFIXASSIGN:
 					assert( applicationExpr->get_args().size() == 1 );
-					before << "(";
-					before << opInfo.symbol;
-					(*arg)->accept( *this );
-					before << ")";
+					output << "(";
+					output << opInfo.symbol;
+					(*arg)->accept( *this );
+					output << ")";
 					break;
 	      
@@ -237,5 +243,5 @@
 					assert( applicationExpr->get_args().size() == 1 );
 					(*arg)->accept( *this );
-					before << opInfo.symbol;
+					output << opInfo.symbol;
 					break;
 
@@ -243,9 +249,9 @@
 				  case OT_INFIXASSIGN:
 					assert( applicationExpr->get_args().size() == 2 );
-					before << "(";
+					output << "(";
 					(*arg++)->accept( *this );
-					before << opInfo.symbol;
-					(*arg)->accept( *this );
-					before << ")";
+					output << opInfo.symbol;
+					(*arg)->accept( *this );
+					output << ")";
 					break;
 	      
@@ -256,17 +262,17 @@
 			} else {
 				varExpr->accept( *this );
-				before << "(";
+				output << "(";
 				genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
-				before << ")";
+				output << ")";
 			} // if
 		} else {
 			applicationExpr->get_function()->accept( *this );
-			before << "(";
+			output << "(";
 			genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
-			before << ")";
-		} // if
-	}
-  
-	void CodeGenerator2::visit( UntypedExpr *untypedExpr ) {
+			output << ")";
+		} // if
+	}
+  
+	void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
 		if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
 			OperatorInfo opInfo;
@@ -277,7 +283,7 @@
 					assert( untypedExpr->get_args().size() == 2 );
 					(*arg++)->accept( *this );
-					before << "[";
-					(*arg)->accept( *this );
-					before << "]";
+					output << "[";
+					(*arg)->accept( *this );
+					output << "]";
 					break;
 	      
@@ -289,8 +295,8 @@
 				  case OT_PREFIXASSIGN:
 					assert( untypedExpr->get_args().size() == 1 );
-					before << "(";
-					before << opInfo.symbol;
-					(*arg)->accept( *this );
-					before << ")";
+					output << "(";
+					output << opInfo.symbol;
+					(*arg)->accept( *this );
+					output << ")";
 					break;
 	      
@@ -299,5 +305,5 @@
 					assert( untypedExpr->get_args().size() == 1 );
 					(*arg)->accept( *this );
-					before << opInfo.symbol;
+					output << opInfo.symbol;
 					break;
   
@@ -305,9 +311,9 @@
 				  case OT_INFIXASSIGN:
 					assert( untypedExpr->get_args().size() == 2 );
-					before << "(";
+					output << "(";
 					(*arg++)->accept( *this );
-					before << opInfo.symbol;
-					(*arg)->accept( *this );
-					before << ")";
+					output << opInfo.symbol;
+					(*arg)->accept( *this );
+					output << ")";
 					break;
 	      
@@ -318,226 +324,210 @@
 			} else {
 				nameExpr->accept( *this );
-				before << "(";
+				output << "(";
 				genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
-				before << ")";
+				output << ")";
 			} // if
 		} else {
 			untypedExpr->get_function()->accept( *this );
-			before << "(";
+			output << "(";
 			genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
-			before << ")";
-		} // if
-	}
-  
-	void CodeGenerator2::visit( NameExpr *nameExpr ) {
+			output << ")";
+		} // if
+	}
+  
+	void CodeGenerator::visit( NameExpr *nameExpr ) {
 		OperatorInfo opInfo;
 		if ( operatorLookup( nameExpr->get_name(), opInfo ) ) {
 			assert( opInfo.type == OT_CONSTANT );
-			before << opInfo.symbol;
-		} else {
-			before << nameExpr->get_name();
-		} // if
-	}
-  
-	void CodeGenerator2::visit( AddressExpr *addressExpr ) {
-		before << "(&";
+			output << opInfo.symbol;
+		} else {
+			output << nameExpr->get_name();
+		} // if
+	}
+  
+	void CodeGenerator::visit( AddressExpr *addressExpr ) {
+		output << "(&";
 		// this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
 		if ( VariableExpr *variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {
-			before << mangleName( variableExpr->get_var() );
+			output << mangleName( variableExpr->get_var() );
 		} else {
 			addressExpr->get_arg()->accept( *this );
 		} // if
-		before << ")";
-	}
-
-	void CodeGenerator2::visit( CastExpr *castExpr ) {
-		before << "((";
+		output << ")";
+	}
+
+	void CodeGenerator::visit( CastExpr *castExpr ) {
+		output << "((";
 		if ( castExpr->get_results().empty() ) {
-			before << "void" ;
-		} else {
-			before << genType( castExpr->get_results().front(), "" );
-		} // if
-		before << ")";
+			output << "void" ;
+		} else {
+			output << genType( castExpr->get_results().front(), "" );
+		} // if
+		output << ")";
 		castExpr->get_arg()->accept( *this );
-		before << ")";
-	}
-  
-	void CodeGenerator2::visit( UntypedMemberExpr *memberExpr ) {
+		output << ")";
+	}
+  
+	void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
 		assert( false );
 	}
   
-	void CodeGenerator2::visit( MemberExpr *memberExpr ) {
+	void CodeGenerator::visit( MemberExpr *memberExpr ) {
 		memberExpr->get_aggregate()->accept( *this );
-		before << "." << mangleName( memberExpr->get_member() );
-	}
-  
-	void CodeGenerator2::visit( VariableExpr *variableExpr ) {
+		output << "." << mangleName( memberExpr->get_member() );
+	}
+  
+	void CodeGenerator::visit( VariableExpr *variableExpr ) {
 		OperatorInfo opInfo;
 		if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) {
-			before << opInfo.symbol;
-		} else {
-			before << mangleName( variableExpr->get_var() );
-		} // if
-	}
-  
-	void CodeGenerator2::visit( ConstantExpr *constantExpr ) {
+			output << opInfo.symbol;
+		} else {
+			output << mangleName( variableExpr->get_var() );
+		} // if
+	}
+  
+	void CodeGenerator::visit( ConstantExpr *constantExpr ) {
 		assert( constantExpr->get_constant() );
 		constantExpr->get_constant()->accept( *this );
 	}
   
-	void CodeGenerator2::visit( SizeofExpr *sizeofExpr ) {
-		before << "sizeof(";
+	void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
+		output << "sizeof(";
 		if ( sizeofExpr->get_isType() ) {
-			before << genType( sizeofExpr->get_type(), "" );
+			output << genType( sizeofExpr->get_type(), "" );
 		} else {
 			sizeofExpr->get_expr()->accept( *this );
 		} // if
-		before << ")";
-	}
-  
-	void CodeGenerator2::visit( LogicalExpr *logicalExpr ) {
-		before << "(";
+		output << ")";
+	}
+  
+	void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
+		output << "(";
 		logicalExpr->get_arg1()->accept( *this );
 		if ( logicalExpr->get_isAnd() ) {
-			before << " && ";
-		} else {
-			before << " || ";
+			output << " && ";
+		} else {
+			output << " || ";
 		} // if
 		logicalExpr->get_arg2()->accept( *this );
-		before << ")";
-	}
-  
-	void CodeGenerator2::visit( ConditionalExpr *conditionalExpr ) {
-		before << "(";
+		output << ")";
+	}
+  
+	void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
+		output << "(";
 		conditionalExpr->get_arg1()->accept( *this );
-		before << " ? ";
+		output << " ? ";
 		conditionalExpr->get_arg2()->accept( *this );
-		before << " : ";
+		output << " : ";
 		conditionalExpr->get_arg3()->accept( *this );
-		before << ")";
-	}
-  
-	void CodeGenerator2::visit( CommaExpr *commaExpr ) {
-		before << "(";
+		output << ")";
+	}
+  
+	void CodeGenerator::visit( CommaExpr *commaExpr ) {
+		output << "(";
 		commaExpr->get_arg1()->accept( *this );
-		before << " , ";
+		output << " , ";
 		commaExpr->get_arg2()->accept( *this );
-		before << ")";
-	}
-  
-	void CodeGenerator2::visit( TupleExpr *tupleExpr ) {}
-  
-	void CodeGenerator2::visit( TypeExpr *typeExpr ) {}
-  
-  
+		output << ")";
+	}
+  
+	void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
+  
+	void CodeGenerator::visit( TypeExpr *typeExpr ) {}
+
 	//*** Statements
-	void CodeGenerator2::visit( CompoundStmt *compoundStmt ) {
+	void CodeGenerator::visit( CompoundStmt *compoundStmt ) {
 		std::list<Statement*> ks = compoundStmt->get_kids();
-
-		before << endl << string( cur_indent, ' ' ) << "{" << endl;
-
-		cur_indent += CodeGenerator2::tabsize; 
+		output << "{" << endl;
+
+		cur_indent += CodeGenerator::tabsize;
 
 		for ( std::list<Statement *>::iterator i = ks.begin(); i != ks.end();  i++) {
-			before << string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() )  ;
+			output << string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() );
 			(*i)->accept(*this );
-			shift_left();
-			before << endl;
+
+			output << endl;
+			if ( wantSpacing( *i ) ) {
+				output << endl;
+			}
 		}
-		cur_indent -= CodeGenerator2::tabsize; 
-
-		before << string( cur_indent, ' ' ) << "}" << endl;
-	}
-
-	void CodeGenerator2::visit( ExprStmt *exprStmt ) {
-		if ( exprStmt != 0 ) {
-			exprStmt->get_expr()->accept( *this );
-			shift_left();
-			before << ";" ;
-		} // if
-	}
-
-	void CodeGenerator2::visit( IfStmt *ifStmt ) {
-		before << "if (";
+		cur_indent -= CodeGenerator::tabsize; 
+
+		output << string( cur_indent, ' ' ) << "}";
+	}
+
+	void CodeGenerator::visit( ExprStmt *exprStmt ) {
+		// I don't see why this check is necessary. 
+		// If this starts to cause problems then put it back in, 
+		// with an explanation
+		assert( exprStmt );
+
+		// if ( exprStmt != 0 ) {
+		exprStmt->get_expr()->accept( *this );
+		output << ";" ;
+		// } // if
+	}
+
+	void CodeGenerator::visit( IfStmt *ifStmt ) {
+		output << "if (";
 		ifStmt->get_condition()->accept(*this );
-		after += ")\n";
-		shift_left(); 
-
-		cur_indent += CodeGenerator2::tabsize;
-		before << string( cur_indent, ' ' );
+		output << ") ";
+
 		ifStmt->get_thenPart()->accept(*this );
-		cur_indent -= CodeGenerator2::tabsize; 
-		shift_left(); before << endl;
 
 		if ( ifStmt->get_elsePart() != 0) {
-			before << string( cur_indent, ' ' ) << " else " << endl ;
-
-			cur_indent += CodeGenerator2::tabsize; 
+			output << " else ";
 			ifStmt->get_elsePart()->accept(*this );
-			cur_indent -= CodeGenerator2::tabsize; 
-		} // if
-	}
-
-	void CodeGenerator2::visit( SwitchStmt *switchStmt ) {
-		//before << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator2::printLabels( switchStmt->get_labels() ) 
-		before << "switch (" ;
+		} // if
+	}
+
+	void CodeGenerator::visit( SwitchStmt *switchStmt ) {
+		//output << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator::printLabels( switchStmt->get_labels() ) 
+		output << "switch (" ;
 		switchStmt->get_condition()->accept(*this );
-		after += ")\n";
-		shift_left();
-
-		before << string( cur_indent, ' ' ) << "{" << std::endl;
-		cur_indent += CodeGenerator2::tabsize;
-
-		std::list< Statement * > stmts = switchStmt->get_branches();
-		bool lastBreak = false; 
-
-		// horrible, horrible hack
-		if ( dynamic_cast<BranchStmt *>( stmts.back() ) != 0 ) {
-			lastBreak = true;
-			stmts.pop_back();
-		} // if
-		acceptAll( stmts, *this );
-		if ( lastBreak ) {
-			Statement *st = switchStmt->get_branches().back();
-			before << CodeGenerator2::printLabels( st->get_labels());
-			st->accept( *this );
-		} // if
-	  
-		cur_indent -= CodeGenerator2::tabsize; 
-
-		before << /* "\r" << */ string( cur_indent, ' ' ) << "}" << endl ;
-	}
-
-	void CodeGenerator2::visit( CaseStmt *caseStmt ) {
-		before << string( cur_indent, ' ' );
+		output << ") ";
+		
+		output << "{" << std::endl;
+		cur_indent += CodeGenerator::tabsize;
+
+		acceptAll( switchStmt->get_branches(), *this );
+
+		cur_indent -= CodeGenerator::tabsize;
+
+		output << string( cur_indent, ' ' ) << "}";
+	}
+
+	void CodeGenerator::visit( CaseStmt *caseStmt ) {
+		output << string( cur_indent, ' ' );
 		if ( caseStmt->isDefault()) 
-			before << "default "  ;
+			output << "default";
 		else {
-			before << "case "  ;
+			output << "case ";
 			caseStmt->get_condition()->accept(*this );
 		} // if
-		after += ":\n";
-		shift_left();
-
+		output << ":\n";
+		
 		std::list<Statement *> sts = caseStmt->get_statements();
 
-		cur_indent += CodeGenerator2::tabsize;
+		cur_indent += CodeGenerator::tabsize;
 		for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++) {
-			before << /* "\r" << */ string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() )  ;
+			output << /* "\r" << */ string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() )  ;
 			(*i)->accept(*this );
-			shift_left();
-			before << ";" << endl;
+			output << endl;
 		}
-		cur_indent -= CodeGenerator2::tabsize;
-	}
-
-	void CodeGenerator2::visit( BranchStmt *branchStmt ) {
+		cur_indent -= CodeGenerator::tabsize;
+	}
+
+	void CodeGenerator::visit( BranchStmt *branchStmt ) {
+		output << "\r" << string( cur_indent, ' ' );
+		output << CodeGenerator::printLabels( branchStmt->get_labels());
+
 		switch ( branchStmt->get_type()) {
 		  case BranchStmt::Goto:
 			if ( ! branchStmt->get_target().empty() )
-				before << "goto " << branchStmt->get_target();
+				output << "goto " << branchStmt->get_target();
 			else { 
 				if ( branchStmt->get_computedTarget() != 0 ) {
-					before << "goto *";
+					output << "goto *";
 					branchStmt->get_computedTarget()->accept( *this );
 				} // if
@@ -545,16 +535,16 @@
 			break;
 		  case BranchStmt::Break:
-			before << "break";
+			output << "break";
 			break;
 		  case BranchStmt::Continue:
-			before << "continue";
+			output << "continue";
 			break;
 		}
-		before << ";";
-	}
-
-
-	void CodeGenerator2::visit( ReturnStmt *returnStmt ) {
-		before << "return ";
+		output << ";";
+	}
+
+
+	void CodeGenerator::visit( ReturnStmt *returnStmt ) {
+		output << "return ";
 
 		// xxx -- check for null expression;
@@ -562,73 +552,67 @@
 			returnStmt->get_expr()->accept( *this );
 		} // if
-		after += ";";
-	}
-
-	void CodeGenerator2::visit( WhileStmt *whileStmt ) {
+		output << ";";
+	}
+
+	void CodeGenerator::visit( WhileStmt *whileStmt ) {
 		if ( whileStmt->get_isDoWhile() )
-			before << "do" ;
+			output << "do" ;
 		else {
-			before << "while (" ;
+			output << "while (" ;
 			whileStmt->get_condition()->accept(*this );
-			after += ")";
-		} // if
-		after += "{\n";
-		shift_left();
-
+			output << ")";
+		} // if
+		output << " ";
+
+		output << CodeGenerator::printLabels( whileStmt->get_body()->get_labels() );
 		whileStmt->get_body()->accept( *this );
 
-		before << /* "\r" << */ string( cur_indent, ' ' ) << "}" ;
+		output << /* "\r" << */ string( cur_indent, ' ' );
 
 		if ( whileStmt->get_isDoWhile() ) {
-			before << " while (" ;
+			output << " while (" ;
 			whileStmt->get_condition()->accept(*this );
-			after += ");";
-		} // if
-
-		after += "\n";
-	}
-
-	void CodeGenerator2::visit( ForStmt *forStmt ) {
-		before << "for (";
+			output << ");";
+		} // if
+	}
+
+	void CodeGenerator::visit( ForStmt *forStmt ) {
+		output << "for (";
 
 		if ( forStmt->get_initialization() != 0 )
 			forStmt->get_initialization()->accept( *this );
 		else
-			before << ";";
-		shift_left();
-
+			output << ";";
+		
 		if ( forStmt->get_condition() != 0 )
 			forStmt->get_condition()->accept( *this );
-		shift_left(); before << ";";
+		output << ";";
 
 		if ( forStmt->get_increment() != 0 )
 			forStmt->get_increment()->accept( *this );
-		shift_left(); before << ")" << endl;
+		output << ") ";
 
 		if ( forStmt->get_body() != 0 ) {
-			cur_indent += CodeGenerator2::tabsize; 
-			before << string( cur_indent, ' ' ) << CodeGenerator2::printLabels( forStmt->get_body()->get_labels() );
+			output << CodeGenerator::printLabels( forStmt->get_body()->get_labels() );
 			forStmt->get_body()->accept( *this );
-			cur_indent -= CodeGenerator2::tabsize; 
-		} // if
-	}
-
-	void CodeGenerator2::visit( NullStmt *nullStmt ) {
-		//before << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator2::printLabels( nullStmt->get_labels() );
-		before << "/* null statement */ ;";
-	}
-
-	void CodeGenerator2::visit( DeclStmt *declStmt ) {
+		} // if
+	}
+
+	void CodeGenerator::visit( NullStmt *nullStmt ) {
+		//output << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator::printLabels( nullStmt->get_labels() );
+		output << "/* null statement */ ;";
+	}
+
+	void CodeGenerator::visit( DeclStmt *declStmt ) {
 		declStmt->get_decl()->accept( *this );
 	
 		if ( doSemicolon( declStmt->get_decl() ) ) {
-			after += ";";
-		} // if
-		shift_left();
-	}
-
-	std::string CodeGenerator2::printLabels( std::list< Label > &l ) {
+			output << ";";
+		} // if
+	}
+
+	std::string CodeGenerator::printLabels( std::list< Label > &l ) {
 		std::string str( "" );
-		l.unique();
+		l.unique(); // assumes a sorted list. Why not use set?
 
 		for ( std::list< Label >::iterator i = l.begin(); i != l.end(); i++ )
@@ -638,18 +622,13 @@
 	}
 
-	void CodeGenerator2::shift_left() {
-		before << after;
-		after = "";
-	}
-
-	void CodeGenerator2::handleStorageClass( Declaration *decl ) {
+	void CodeGenerator::handleStorageClass( Declaration *decl ) {
 		switch ( decl->get_storageClass() ) {
 		  case Declaration::NoStorageClass:
 			break;
 		  case Declaration::Extern:
-			before << "extern ";
+			output << "extern ";
 			break;
 		  case Declaration::Static:
-			before << "static ";
+			output << "static ";
 			break;
 		  case Declaration::Auto:
@@ -657,5 +636,5 @@
 			break;
 		  case Declaration::Register:
-			before << "register ";
+			output << "register ";
 			break;
 		  case Declaration::Inline:
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/CodeGen/CodeGenerator.h	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// CodeGenerator2.h -- 
+// CodeGenerator.h -- 
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 23:35:37 2015
-// Update Count     : 2
+// Last Modified By : Rob Schluntz
+// Last Modified On : Tue Jun 02 13:43:29 2015
+// Update Count     : 14
 //
 
@@ -25,13 +25,11 @@
 
 namespace CodeGen {
-	class CodeGenerator2 : public Visitor {
+	class CodeGenerator : public Visitor {
 	  public:
 		static int tabsize;
 
-		CodeGenerator2( std::ostream &os );
-		CodeGenerator2( std::ostream &os, std::string, int indent = 0, bool infun = false );
-		CodeGenerator2( std::ostream &os, char *, int indent = 0, bool infun = false );
-
-		CodeGenerator2( CodeGenerator2 & );
+		CodeGenerator( std::ostream &os );
+		CodeGenerator( std::ostream &os, std::string, int indent = 0, bool infun = false );
+		CodeGenerator( std::ostream &os, char *, int indent = 0, bool infun = false );
 
 		//*** Declaration
@@ -82,13 +80,9 @@
 		virtual void visit( DeclStmt * ); 
 
-		std::string get_string( void );
-		void add_string_left( std::string s ) { before << s; }
-		void shift_left();
 		template< class Iterator > void genCommaList( Iterator begin, Iterator end );
 	  private:
 		int cur_indent;
 		bool insideFunction;
-		std::ostream &before;
-		std::string after;
+		std::ostream &output;
 
 		static std::string printLabels ( std::list < Label > & );
@@ -100,5 +94,5 @@
 	
 	template< class Iterator >
-	void CodeGenerator2::genCommaList( Iterator begin, Iterator end ) {
+	void CodeGenerator::genCommaList( Iterator begin, Iterator end ) {
 		if ( begin == end ) return;
 
@@ -106,5 +100,5 @@
 			(*begin++)->accept( *this );
 			if ( begin == end ) return;
-			before << ", ";
+			output << ", ";
 		} // for
 	}
Index: src/CodeGen/GenType.cc
===================================================================
--- src/CodeGen/GenType.cc	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/CodeGen/GenType.cc	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jun  2 11:21:32 2015
-// Update Count     : 3
+// Last Modified On : Thu Jun  4 14:04:58 2015
+// Update Count     : 4
 //
 
@@ -97,5 +97,5 @@
 		} // if
 		if ( dimension != 0 ) {
-			CodeGenerator2 cg( os );
+			CodeGenerator cg( os );
 			dimension->accept( cg );
 		} // if
@@ -148,5 +148,5 @@
 			} // if
 		} else {
-			CodeGenerator2 cg( os );
+			CodeGenerator cg( os );
 			os << "(" ;
 
Index: src/CodeGen/Generate.cc
===================================================================
--- src/CodeGen/Generate.cc	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/CodeGen/Generate.cc	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jun  2 11:21:06 2015
-// Update Count     : 2
+// Last Modified On : Thu Jun  4 14:04:25 2015
+// Update Count     : 5
 //
 
@@ -27,10 +27,9 @@
 namespace CodeGen {
 	void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics ) {
-		CodeGen::CodeGenerator2 cgv( os );
+		CodeGen::CodeGenerator cgv( os );
 
 		for ( std::list<Declaration *>::iterator i = translationUnit.begin(); i != translationUnit.end();  i++ ) {
 			if ( LinkageSpec::isGeneratable( (*i)->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) ) {
 				(*i)->accept(cgv);
-				cgv.shift_left();
 				if ( doSemicolon( *i ) ) {
 					os << ";";
Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/Common/utility.h	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 15:34:57 2015
-// Update Count     : 3
+// Last Modified By : Rob Schluntz
+// Last Modified On : Fri May 29 16:17:02 2015
+// Update Count     : 7
 //
 
@@ -198,4 +198,14 @@
 }
 
+// it's nice to actually be able to increment iterators by an arbitrary amount
+template< typename Iterator >
+Iterator operator+(Iterator i, int inc) {
+	while ( inc > 0 ) {
+		++i;
+		--inc;
+	}
+	return i;
+}
+
 #endif // _UTILITY_H
 
Index: src/ControlStruct/ChooseMutator.cc
===================================================================
--- src/ControlStruct/ChooseMutator.cc	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/ControlStruct/ChooseMutator.cc	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 15:31:39 2015
-// Update Count     : 2
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Jun 03 15:30:20 2015
+// Update Count     : 5
 //
 
@@ -44,4 +44,9 @@
 		std::list< Statement * > &stmts = caseStmt->get_statements();
 
+		// the difference between switch and choose is that switch has an implicit fallthrough
+		// to the next case, whereas choose has an implicit break at the end of the current case.
+		// thus to transform a choose statement into a switch, we only need to insert breaks at the
+		// end of any case that doesn't already end in a break and that doesn't end in a fallthru
+
 		if ( insideChoose ) {
 			BranchStmt *posBrk;
Index: src/ControlStruct/LabelFixer.cc
===================================================================
--- src/ControlStruct/LabelFixer.cc	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/ControlStruct/LabelFixer.cc	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Wed May 27 16:16:14 2015
-// Update Count     : 4
+// Last Modified On : Tue Jun 02 15:30:32 2015
+// Update Count     : 93
 //
 
@@ -23,6 +23,8 @@
 #include "utility.h"
 
+#include <iostream>
+
 namespace ControlStruct {
-	LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) {
+	LabelFixer::Entry::Entry( Statement *to, BranchStmt *from ) : definition ( to ) {
 		if ( from != 0 )
 			usage.push_back( from );
@@ -31,5 +33,5 @@
 	bool LabelFixer::Entry::insideLoop() {
 		return ( dynamic_cast< ForStmt * > ( definition ) ||
-				 dynamic_cast< WhileStmt * > ( definition )  );
+			dynamic_cast< WhileStmt * > ( definition )  );
 	}
 
@@ -46,8 +48,10 @@
 	}
 
+	// prune to at most one label definition for each statement
 	void LabelFixer::visit( Statement *stmt ) {
 		std::list< Label > &labels = stmt->get_labels();
 
 		if ( ! labels.empty() ) {
+			// only remember one label for each statement
 			Label current = setLabelsDef( labels, stmt );
 			labels.clear();
@@ -57,85 +61,103 @@
 
 	void LabelFixer::visit( BranchStmt *branchStmt ) {
-		visit ( ( Statement * )branchStmt );  // the labels this statement might have
+		visit ( ( Statement * )branchStmt );
 
-		Label target;
-		if ( (target = branchStmt->get_target()) != "" ) {
+		// for labeled branches, add an entry to the label table
+		Label target = branchStmt->get_target();
+		if ( target != "" ) {
 			setLabelsUsg( target, branchStmt );
-		} //else       /* computed goto or normal exit-loop statements */
+		}
 	}
 
+	// sets the definition of the labelTable entry to be the provided 
+	// statement for every label in the list parameter. Happens for every kind of statement
 	Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
 		assert( definition != 0 );
-		Entry *entry = new Entry( definition );
-		bool used = false;
+		assert( llabel.size() > 0 );
 
-		for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ )
-			if ( labelTable.find( *i ) == labelTable.end() )
-				{ used = true; labelTable[ *i ] = entry; } // undefined and unused
-			else
-				if ( labelTable[ *i ]->defined() )
-					throw SemanticError( "Duplicate definition of label: " + *i );
-				else
-					labelTable[ *i ]->set_definition( definition );
+		Entry * e = new Entry( definition );
 
-		if ( ! used ) delete entry;
+		for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) {
+			if ( labelTable.find( *i ) == labelTable.end() ) {
+				// all labels on this statement need to use the same entry, so this should only be created once
+				// undefined and unused until now, add an entry
+				labelTable[ *i ] =  e;
+			} else if ( labelTable[ *i ]->defined() ) {
+				// defined twice, error
+				throw SemanticError( "Duplicate definition of label: " + *i );
+			}	else {
+				// used previously, but undefined until now -> link with this entry
+				Entry * oldEntry = labelTable[ *i ];
+				e->add_uses( oldEntry->get_uses() );
+				labelTable[ *i ] = e;
+			} // if
+		} // for
 
-		return labelTable[ llabel.front() ]->get_label();  // this *must* exist
+		// produce one of the labels attached to this statement to be 
+		// temporarily used as the canonical label
+		return labelTable[ llabel.front() ]->get_label();
 	}
 
-	Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
+	// Remember all uses of a label.
+	void LabelFixer::setLabelsUsg( Label orgValue, BranchStmt *use ) {
 		assert( use != 0 );
 
-		if ( labelTable.find( orgValue ) != labelTable.end() )
-			labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
-		else
+		if ( labelTable.find( orgValue ) != labelTable.end() ) {
+			// the label has been defined or used before
+			labelTable[ orgValue ]->add_use( use );
+		} else {
 			labelTable[ orgValue ] = new Entry( 0, use );
-
-		return labelTable[ orgValue ]->get_label();
+		}
 	}
 
+	// Ultimately builds a table that maps a label to its defining statement.
+	// In the process, 
 	std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
 		std::map< Statement *, Entry * > def_us;
 
-		for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
+		// combine the entries for all labels that target the same location
+		for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
 			Entry *e = i->second;
 
 			if ( def_us.find ( e->get_definition() ) == def_us.end() ) {
 				def_us[ e->get_definition() ] = e;				
-			} else {
-				if ( e->used() )
-					def_us[ e->get_definition() ]->add_uses( e->get_uses() );
+			} else if ( e->used() ) {
+				def_us[ e->get_definition() ]->add_uses( e->get_uses() );
 			}
 		}
 
-		// get rid of labelTable
-		for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
+		// create a unique label for each target location. 
+		for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
 			Statement *to = (*i).first;
-			std::list< Statement *> &from = (*i).second->get_uses();
-			Label finalLabel = generator->newLabel();
-			(*i).second->set_label( finalLabel );
+			Entry * entry = (*i).second;
+			std::list< BranchStmt *> &from = entry->get_uses();
 
+			// no label definition found
 			if ( to == 0 ) {
-				BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back());
-				Label undef("");
-				if ( first_use != 0 )
-					undef = first_use->get_target();
+				Label undef = from.back()->get_target();
 				throw SemanticError ( "'" + undef + "' label not defined");
 			}
+
+			// generate a new label, and attach it to its defining statement
+			// as the only label on that statement
+			Label finalLabel = generator->newLabel();
+			entry->set_label( finalLabel );
 
 			to->get_labels().clear();
 			to->get_labels().push_back( finalLabel );
 
-			for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) {
-				BranchStmt *jumpTo = dynamic_cast< BranchStmt * > ( *j );
-				assert( jumpTo != 0 );
-				jumpTo->set_target( finalLabel );
+			// redirect each of the source branch statements to the new target label
+			for ( std::list< BranchStmt *>::iterator j = from.begin(); j != from.end(); ++j ) {
+				BranchStmt *jump = *j;
+				assert( jump != 0 );
+				jump->set_target( finalLabel );
 			} // for
 		} // for
 
-		// reverse table
+		// create a table where each label maps to its defining statement
 		std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
-		for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) 
+		for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
 			(*ret)[ (*i).second->get_label() ] = (*i).first;
+		}
 
 		return ret;
Index: src/ControlStruct/LabelFixer.h
===================================================================
--- src/ControlStruct/LabelFixer.h	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/ControlStruct/LabelFixer.h	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Tue May 26 12:55:10 2015
-// Update Count     : 4
+// Last Modified On : Fri May 29 15:25:55 2015
+// Update Count     : 11
 //
 
@@ -55,10 +55,10 @@
 
 		Label setLabelsDef( std::list< Label > &, Statement *definition );
-		Label setLabelsUsg( Label, Statement *usage = 0 );
+		void setLabelsUsg( Label, BranchStmt *usage = 0 );
 
 	  private:
 		class Entry {
 		  public:
-			Entry( Statement *to = 0, Statement *from = 0 );
+			Entry( Statement *to = 0, BranchStmt *from = 0 );
 			bool used() { return ( usage.empty() ); }
 			bool defined() { return ( definition != 0 ); }
@@ -71,11 +71,11 @@
 			void set_definition( Statement *def ) { definition = def; }
 
-			std::list< Statement *> &get_uses() { return usage; }
-			void add_use ( Statement *use ) { usage.push_back( use ); }
-			void add_uses ( std::list<Statement *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }
+			std::list< BranchStmt *> &get_uses() { return usage; }
+			void add_use ( BranchStmt *use ) { usage.push_back( use ); }
+			void add_uses ( std::list<BranchStmt *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }
 		  private:
 			Label label;  
 			Statement *definition;
-			std::list<Statement *> usage;
+			std::list<BranchStmt *> usage;
 		};
 	          
Index: src/ControlStruct/LabelGenerator.cc
===================================================================
--- src/ControlStruct/LabelGenerator.cc	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/ControlStruct/LabelGenerator.cc	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 15:32:04 2015
-// Update Count     : 2
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Jun 03 14:23:26 2015
+// Update Count     : 9
 //
 
@@ -29,7 +29,7 @@
 	}
 
-	Label LabelGenerator::newLabel() {
+	Label LabelGenerator::newLabel(std::string suffix) {
 		std::ostrstream os;
-		os << "__L" << current++ << "__";// << std::ends;
+		os << "__L" << current++ << "__" << suffix;
 		os.freeze( false );
 		std::string ret = std::string (os.str(), os.pcount());
Index: src/ControlStruct/LabelGenerator.h
===================================================================
--- src/ControlStruct/LabelGenerator.h	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/ControlStruct/LabelGenerator.h	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 15:33:20 2015
-// Update Count     : 3
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Jun 03 14:16:26 2015
+// Update Count     : 5
 //
 
@@ -18,4 +18,5 @@
 
 #include "SynTree/SynTree.h"
+#include <string>
 
 namespace ControlStruct {
@@ -23,5 +24,5 @@
 	  public:
 		static LabelGenerator *getGenerator();
-		Label newLabel();
+		Label newLabel(std::string suffix = "");
 		void reset() { current = 0; }
 		void rewind() { current--; }
Index: src/ControlStruct/MLEMutator.cc
===================================================================
--- src/ControlStruct/MLEMutator.cc	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/ControlStruct/MLEMutator.cc	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Wed May 27 16:19:32 2015
-// Update Count     : 44
+// Last Modified On : Wed Jun 03 15:09:27 2015
+// Update Count     : 170
 //
 
@@ -19,4 +19,5 @@
 #include "MLEMutator.h"
 #include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
 
 namespace ControlStruct {
@@ -26,17 +27,14 @@
 	}
 
-	CompoundStmt* MLEMutator::mutate( CompoundStmt *cmpndStmt ) {
-		bool labeledBlock = false;
-		if ( !(cmpndStmt->get_labels().empty()) ) {
-			labeledBlock = true;
-			enclosingBlocks.push_back( Entry( cmpndStmt ) );
-		} // if
-
-		std::list< Statement * > &kids = cmpndStmt->get_kids();
+	// break labels have to come after the statement they break out of, 
+	// so mutate a statement, then if they inform us through the breakLabel field
+	// tha they need a place to jump to on a break statement, add the break label 
+	// to the body of statements
+	void MLEMutator::fixBlock( std::list< Statement * > &kids ) {
 		for ( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) {
 			*k = (*k)->acceptMutator(*this);
 
 			if ( ! get_breakLabel().empty() ) {
-				std::list< Statement * >::iterator next = k; next++;
+				std::list< Statement * >::iterator next = k+1;
 				if ( next == kids.end() ) {
 					std::list<Label> ls; ls.push_back( get_breakLabel() );
@@ -49,39 +47,86 @@
 			} // if
 		} // for
+	}
+
+	CompoundStmt* MLEMutator::mutate( CompoundStmt *cmpndStmt ) {
+		bool labeledBlock = !(cmpndStmt->get_labels().empty());
+		if ( labeledBlock ) {
+			Label brkLabel = generator->newLabel();
+			enclosingBlocks.push_back( Entry( cmpndStmt, brkLabel ) );
+		} // if
+
+		// a child statement may set the break label
+		// - if they do, attach it to the next statement
+		std::list< Statement * > &kids = cmpndStmt->get_kids();
+		fixBlock( kids );
 
 		if ( labeledBlock ) {
 			assert( ! enclosingBlocks.empty() );
-			if ( ! enclosingBlocks.back().get_breakExit().empty() ) {
-				set_breakLabel( enclosingBlocks.back().get_breakExit() );
+			if ( ! enclosingBlocks.back().useBreakExit().empty() ) {
+				set_breakLabel( enclosingBlocks.back().useBreakExit() );
 			}
 			enclosingBlocks.pop_back();
 		} // if
 
-		//mutateAll( cmpndStmt->get_kids(), *this );
 		return cmpndStmt;
 	}
 
-	Statement *MLEMutator::mutate( WhileStmt *whileStmt ) {
-		enclosingLoops.push_back( Entry( whileStmt ) );
-		whileStmt->set_body ( whileStmt->get_body()->acceptMutator( *this ) );
-
+	template< typename LoopClass >
+	Statement *MLEMutator::handleLoopStmt( LoopClass *loopStmt ) {
+		// remember this as the most recent enclosing loop, then mutate 
+		// the body of the loop -- this will do SOMETHING with branch statements
+		// and will recursively do the same to nested loops
+		Label brkLabel = generator->newLabel("loopBreak");
+		Label contLabel = generator->newLabel("loopContinue");
+		enclosingLoops.push_back( Entry( loopStmt, brkLabel, contLabel ) );
+		loopStmt->set_body ( loopStmt->get_body()->acceptMutator( *this ) );
+
+		// sanity check that the enclosing loops have been popped correctly
 		Entry &e = enclosingLoops.back();
-		assert ( e == whileStmt );
-		whileStmt->set_body( mutateLoop( whileStmt->get_body(), e ) );
+		assert ( e == loopStmt );
+
+		// generate labels as needed
+		loopStmt->set_body( mutateLoop( loopStmt->get_body(), e ) );
 		enclosingLoops.pop_back();
 
-		return whileStmt;
-	}
-
-	Statement *MLEMutator::mutate( ForStmt *forStmt ) {
-		enclosingLoops.push_back( Entry( forStmt ) );
-		maybeMutate( forStmt->get_body(), *this );
-
-		Entry &e = enclosingLoops.back();
-		assert ( e == forStmt );
-		forStmt->set_body( mutateLoop( forStmt->get_body(), e ) );
-		enclosingLoops.pop_back();
-
-		return forStmt;
+		return loopStmt;
+	}
+
+	Statement *MLEMutator::mutate( CaseStmt *caseStmt ) {
+		caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) );
+		fixBlock( caseStmt->get_statements() );
+
+		return caseStmt;
+	}
+
+	template< typename SwitchClass >
+	Statement *MLEMutator::handleSwitchStmt( SwitchClass *switchStmt ) {
+		// generate a label for breaking out of a labeled switch 
+		Label brkLabel = generator->newLabel("switchBreak");
+		enclosingSwitches.push_back( Entry(switchStmt, brkLabel) );
+		mutateAll( switchStmt->get_branches(), *this ); 
+
+		Entry &e = enclosingSwitches.back();
+		assert ( e == switchStmt );
+
+		// only generate break label if labeled break is used
+		if (e.isBreakUsed()) {
+			// for the purposes of keeping switch statements uniform (i.e. all statements that are 
+			// direct children of a switch should be CastStmts), append the exit label + break to the 
+			// last case statement; create a default case if there are no cases
+			std::list< Statement * > &branches = switchStmt->get_branches();
+			if ( branches.empty() ) {
+				branches.push_back( CaseStmt::makeDefault() );
+			}
+
+			if ( CaseStmt * c = dynamic_cast< CaseStmt * >( branches.back() ) ) {
+				std::list<Label> temp; temp.push_back( brkLabel );
+				c->get_statements().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
+			} else assert(0); // as of this point, all branches of a switch are still CaseStmts
+		}
+
+		assert ( enclosingSwitches.back() == switchStmt );
+		enclosingSwitches.pop_back();
+		return switchStmt;
 	}
 
@@ -117,60 +162,28 @@
 					throw SemanticError("The target specified in the exit loop statement does not correspond to an enclosing control structure: " + originalTarget );
 
+		// what about exiting innermost block or switch???
 		if ( enclosingLoops.back() == (*check) )
 			return branchStmt;				// exit the innermost loop (labels unnecessary)
 
-		Label newLabel;
+		// branch error checks, get the appropriate label name and create a goto
+		Label exitLabel;
 		switch ( branchStmt->get_type() ) {
 		  case BranchStmt::Break:
-				if ( check->get_breakExit() != "" ) {
-					newLabel = check->get_breakExit();
-				} else {
-					newLabel = generator->newLabel();
-					check->set_breakExit( newLabel );
-				} // if
+				assert( check->useBreakExit() != "");
+				exitLabel = check->useBreakExit();
 				break;
 		  case BranchStmt::Continue:
-				if ( check->get_contExit() != "" ) {
-					newLabel = check->get_contExit();
-				} else {
-					newLabel = generator->newLabel();
-					check->set_contExit( newLabel );
-				} // if
+				assert( check->useContExit() != "");
+				exitLabel = check->useContExit();
 				break;
 		  default:
-				return 0;					// shouldn't be here
+				assert(0);					// shouldn't be here
 		} // switch
 
-		return new BranchStmt( std::list<Label>(), newLabel, BranchStmt::Goto );
-	}
-
-	template< typename SwitchClass >
-	Statement *handleSwitchStmt( SwitchClass *switchStmt, MLEMutator &mutator ) {
-		// set up some aliases so that the rest of the code isn't messy
-		typedef MLEMutator::Entry Entry;
-		LabelGenerator *generator = mutator.generator;
-		std::list< Entry > &enclosingSwitches = mutator.enclosingSwitches;
-
-		Label brkLabel = generator->newLabel();
-		enclosingSwitches.push_back( Entry(switchStmt, "", brkLabel) );
-		mutateAll( switchStmt->get_branches(), mutator ); {
-			// check if this is necessary (if there is a break to this point, otherwise do not generate
-			std::list<Label> temp; temp.push_back( brkLabel );
-			switchStmt->get_branches().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
-		}
-		assert ( enclosingSwitches.back() == switchStmt );
-		enclosingSwitches.pop_back();
-		return switchStmt;
-	}
-
-	Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) {
-		return handleSwitchStmt( switchStmt, *this );
-	}
-
-	Statement *MLEMutator::mutate( ChooseStmt *switchStmt ) {
-		return handleSwitchStmt( switchStmt, *this );		
+		return new BranchStmt( std::list<Label>(), exitLabel, BranchStmt::Goto );
 	}
 
 	Statement *MLEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) {
+		// ensure loop body is a block
 		CompoundStmt *newBody;
 		if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) {
@@ -179,39 +192,37 @@
 		} // if
 
-		Label endLabel = e.get_contExit();
-
-		if ( e.get_breakExit() != "" ) {
-			if ( endLabel == "" ) endLabel = generator->newLabel();
-			// check for whether this label is used or not, so as to not generate extraneous gotos
-			if (e.breakExitUsed)
-				newBody->get_kids().push_back( new BranchStmt( std::list< Label >(), endLabel, BranchStmt::Goto ) );
-			// xxx
-			//std::list< Label > ls; ls.push_back( e.get_breakExit() );
-			set_breakLabel( e.get_breakExit() );
-			//newBody->get_kids().push_back( new BranchStmt( ls, "", BranchStmt::Break ) );
-		} // if
-
-		if ( e.get_breakExit() != "" || e.get_contExit() != "" ) {
-			if (dynamic_cast< NullStmt *>( newBody->get_kids().back() ))
-				newBody->get_kids().back()->get_labels().push_back( endLabel );
-			else {
-				std::list < Label > ls; ls.push_back( endLabel );
-				newBody->get_kids().push_back( new NullStmt( ls ) );
-			} // if
-		} // if
+		// only generate these when needed
+
+		if ( e.isContUsed() ) {
+			// continue label goes in the body as the last statement
+			std::list< Label > labels; labels.push_back( e.useContExit() );
+			newBody->get_kids().push_back( new NullStmt( labels ) );			
+		}
+
+		if ( e.isBreakUsed() ) {
+			// break label goes after the loop -- it'll get set by the 
+			// outer mutator if we do this
+			set_breakLabel( e.useBreakExit() );			
+		}
 
 		return newBody;
 	}
 
-	//*** Entry's methods
-	void MLEMutator::Entry::set_contExit( Label l ) {
-		assert ( contExit == "" || contExit == l );
-		contExit = l;
-	}
-
-	void MLEMutator::Entry::set_breakExit( Label l ) {
-		assert ( breakExit == "" || breakExit == l );
-		breakExit = l;
-	}
+	Statement *MLEMutator::mutate( WhileStmt *whileStmt ) {
+		return handleLoopStmt( whileStmt );
+	}
+
+	Statement *MLEMutator::mutate( ForStmt *forStmt ) {
+		return handleLoopStmt( forStmt );
+	}
+
+	Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) {
+		return handleSwitchStmt( switchStmt );
+	}
+
+	Statement *MLEMutator::mutate( ChooseStmt *switchStmt ) {
+		return handleSwitchStmt( switchStmt );		
+	}
+
 } // namespace ControlStruct
 
Index: src/ControlStruct/MLEMutator.h
===================================================================
--- src/ControlStruct/MLEMutator.h	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/ControlStruct/MLEMutator.h	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Tue May 26 15:04:21 2015
-// Update Count     : 7
+// Last Modified On : Wed Jun 03 15:06:36 2015
+// Update Count     : 25
 //
 
@@ -38,4 +38,5 @@
 		Statement *mutate( BranchStmt *branchStmt ) throw ( SemanticError );
 
+		Statement *mutate( CaseStmt *caseStmt ); 
 		Statement *mutate( SwitchStmt *switchStmt );
 		Statement *mutate( ChooseStmt *switchStmt );
@@ -48,6 +49,6 @@
 		class Entry {
 		  public:
-			explicit Entry( Statement *_loop = 0, Label _contExit = Label(""), Label _breakExit = Label("") ) :
-				loop( _loop ), contExit( _contExit ), breakExit( _breakExit ), contExitUsed( false ), breakExitUsed( false ) {}
+			explicit Entry( Statement *_loop, Label _breakExit, Label _contExit = Label("") ) :
+				loop( _loop ), breakExit( _breakExit ), contExit( _contExit ), breakUsed(false), contUsed(false) {}
 
 			bool operator==( const Statement *stmt ) { return ( loop == stmt ); }
@@ -58,15 +59,14 @@
 			Statement *get_loop() const { return loop; }
 
-			Label get_contExit() const { return contExit; }
-			void set_contExit( Label );
+			Label useContExit() { contUsed = true; return contExit; }
+			Label useBreakExit() { breakUsed = true; return breakExit; }
 
-			Label get_breakExit() const { return breakExit; }
-			void set_breakExit( Label );
+			bool isContUsed() const { return contUsed; }
+			bool isBreakUsed() const { return breakUsed; }
 
 		  private:
 			Statement *loop;
-			Label contExit, breakExit;
-		  public: // hack, provide proper [sg]etters
-			bool contExitUsed, breakExitUsed;
+			Label breakExit, contExit;
+			bool breakUsed, contUsed;
 		};
 
@@ -76,6 +76,11 @@
 		LabelGenerator *generator;
 
+		template< typename LoopClass >
+		Statement *handleLoopStmt( LoopClass *loopStmt );
+
 		template< typename SwitchClass > 
-		friend Statement *handleSwitchStmt( SwitchClass *switchStmt, MLEMutator &mutator );
+		Statement *handleSwitchStmt( SwitchClass *switchStmt );
+
+		void fixBlock( std::list< Statement * > &kids );
 	};
 } // namespace ControlStruct
Index: src/ControlStruct/Mutate.cc
===================================================================
--- src/ControlStruct/Mutate.cc	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/ControlStruct/Mutate.cc	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 15:32:52 2015
-// Update Count     : 2
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Jun 03 23:08:43 2015
+// Update Count     : 5
 //
 
@@ -37,7 +37,15 @@
 	void mutate( std::list< Declaration * > translationUnit ) {
 		// ForExprMutator formut;
+
+		// normalizes label definitions and generates multi-level
+		// exit labels
 		LabelFixer lfix;
+
+		// transform choose statements into switch statements
 		ChooseMutator chmut;
+
+		// expand case ranges and turn fallthru into a null statement
 		CaseRangeMutator ranges;  // has to run after ChooseMutator
+
 		//ExceptMutator exc;
 		// LabelTypeChecker lbl;
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/SynTree/Mutator.h	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 10:12:28 2015
-// Update Count     : 3
+// Last Modified By : Rob Schluntz
+// Last Modified On : Fri May 29 16:34:08 2015
+// Update Count     : 4
 //
 #include <cassert>
@@ -104,5 +104,4 @@
 		assert( newnode );
 		return newnode;
-///	    return tree->acceptMutator( mutator );
 	} else {
 		return 0;
Index: src/SynTree/ObjectDecl.cc
===================================================================
--- src/SynTree/ObjectDecl.cc	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/SynTree/ObjectDecl.cc	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 10:14:18 2015
-// Update Count     : 2
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu May 28 14:10:02 2015
+// Update Count     : 8
 //
 
@@ -65,4 +65,9 @@
 
 void ObjectDecl::printShort( std::ostream &os, int indent ) const {
+#if 0
+	if ( get_mangleName() != "") {
+		os << get_mangleName() << ": a "; 
+	} else 
+#endif
 	if ( get_name() != "" ) {
 		os << get_name() << ": a ";
Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/SynTree/Statement.cc	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Wed May 27 15:41:13 2015
-// Update Count     : 8
+// Last Modified On : Tue Jun 02 13:07:09 2015
+// Update Count     : 14
 //
 
@@ -124,4 +124,8 @@
 CaseStmt::~CaseStmt() {
 	delete condition;
+}
+
+CaseStmt * CaseStmt::makeDefault( std::list<Label> labels, std::list<Statement *> branches ) {
+	return new CaseStmt( labels, 0, branches, true );
 }
 
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/SynTree/Statement.h	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jun  3 11:55:15 2015
-// Update Count     : 6
+// Last Modified On : Thu Jun  4 14:03:31 2015
+// Update Count     : 14
 //
 
@@ -149,4 +149,7 @@
 	      std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
 	virtual ~CaseStmt();
+
+	static CaseStmt * makeDefault( std::list<Label> labels = std::list<Label>(),
+		std::list<Statement *> stmts = std::list<Statement *>() );
 
 	bool isDefault() { return _isDefault; }
Index: src/examples/control_structures.c
===================================================================
--- src/examples/control_structures.c	(revision a61fea9ae36d50374d924b984ee54318ba2d7f61)
+++ src/examples/control_structures.c	(revision 9a8930f5bb61faf0b3acd02c38d9af3f76c294a6)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jun  4 11:21:12 2015
-// Update Count     : 23
+// Last Modified On : Thu Jun  4 14:02:50 2015
+// Update Count     : 24
 //
 
