Index: src/ControlStruct/MLEMutator.cc
===================================================================
--- src/ControlStruct/MLEMutator.cc	(revision d939274d90e070f24aa2934b1c5d66d8c1e8dd24)
+++ src/ControlStruct/MLEMutator.cc	(revision 27de95521e8ffa312b8ff4c8a3684e27f7360ea3)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Tue Jun 02 13:43:01 2015
-// Update Count     : 92
+// 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,14 +27,9 @@
 	}
 
-	CompoundStmt* MLEMutator::mutate( CompoundStmt *cmpndStmt ) {
-		bool labeledBlock = false;
-		if ( !(cmpndStmt->get_labels().empty()) ) {
-			labeledBlock = true;
-			enclosingBlocks.push_back( Entry( cmpndStmt ) );
-		} // 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();
+	// 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);
@@ -51,9 +47,22 @@
 			} // 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();
@@ -63,26 +72,61 @@
 	}
 
-	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 ) );
-		forStmt->set_body( 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;
 	}
 
@@ -118,69 +162,24 @@
 					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
-
-			// 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);
-		}
-		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 );
 	}
 
@@ -193,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 - ensure these labels can be set at most once
-	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
 
