//
// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
//
// AddStmtVisitor.cc --
//
// Author           : Rob Schluntz
// Created On       : Wed Jun 22 12:11:17 2016
// Last Modified By : Peter A. Buhr
// Last Modified On : Thu Aug  4 11:23:47 2016
// Update Count     : 16
//

#include "AddStmtVisitor.h"

#include "Common/SemanticError.h"  // for SemanticError
#include "Declaration.h"           // for Declaration
#include "Expression.h"            // for Expression
#include "Statement.h"             // for CompoundStmt, ForStmt, IfStmt, Sta...
#include "SynTree/Label.h"         // for Label, noLabels

void AddStmtVisitor::visitStatementList( std::list< Statement* > &statements ) {
	for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
		if ( ! stmtsToAddAfter.empty() ) {
			statements.splice( i, stmtsToAddAfter );
		} // if
		(*i)->accept( *this );
		if ( ! stmtsToAdd.empty() ) {
			statements.splice( i, stmtsToAdd );
		} // if
	} // for
	if ( ! stmtsToAddAfter.empty() ) {
		statements.splice( statements.end(), stmtsToAddAfter );
	} // if
}

Statement * AddStmtVisitor::visitStatement( Statement *stmt ) {
	maybeAccept( stmt, *this );
	if ( ! stmtsToAdd.empty() || ! stmtsToAddAfter.empty() ) {
		CompoundStmt *compound = new CompoundStmt( noLabels );
		compound->get_kids().splice( compound->get_kids().end(), stmtsToAdd );
		compound->get_kids().push_back( stmt );
		compound->get_kids().splice( compound->get_kids().end(), stmtsToAddAfter );
		return compound;
	} else {
		return stmt;
	}
}

void AddStmtVisitor::visit(CompoundStmt *compoundStmt) {
	visitStatementList( compoundStmt->get_kids() );
}

void AddStmtVisitor::visit(IfStmt *ifStmt) {
	ifStmt->set_thenPart( visitStatement( ifStmt->get_thenPart() ) );
	ifStmt->set_elsePart( visitStatement( ifStmt->get_elsePart() ) );
	maybeAccept( ifStmt->get_condition(), *this );
}

void AddStmtVisitor::visit(WhileStmt *whileStmt) {
	whileStmt->set_body( visitStatement( whileStmt->get_body() ) );
	maybeAccept( whileStmt->get_condition(), *this );
}

void AddStmtVisitor::visit(ForStmt *forStmt) {
	forStmt->set_body( visitStatement( forStmt->get_body() ) );
	acceptAll( forStmt->get_initialization(), *this );
	maybeAccept( forStmt->get_condition(), *this );
	maybeAccept( forStmt->get_increment(), *this );
}

void AddStmtVisitor::visit(SwitchStmt *switchStmt) {
	visitStatementList( switchStmt->get_statements() );
	maybeAccept( switchStmt->get_condition(), *this );
}

void AddStmtVisitor::visit(CaseStmt *caseStmt) {
	visitStatementList( caseStmt->get_statements() );
	maybeAccept( caseStmt->get_condition(), *this );
}

void AddStmtVisitor::visit(CatchStmt *catchStmt) {
	catchStmt->set_body( visitStatement( catchStmt->get_body() ) );
	maybeAccept( catchStmt->get_decl(), *this );
}

// Local Variables: //
// tab-width: 4 //
// mode: c++ //
// compile-command: "make install" //
// End: //
