// // 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. // // PolyMutator.cc -- // // Author : Richard C. Bilson // Created On : Mon May 18 07:44:20 2015 // Last Modified By : Andrew Beach // Last Modified On : Thu Jun 22 13:47:00 2017 // Update Count : 17 // #include "PolyMutator.h" #include "SynTree/Declaration.h" #include "SynTree/Type.h" #include "SynTree/Expression.h" #include "SynTree/Statement.h" #include "SynTree/Mutator.h" #include "SynTree/Initializer.h" namespace GenPoly { PolyMutator::PolyMutator() : scopeTyVars( TypeDecl::Data{} ), env( 0 ) {} void PolyMutator::mutateStatementList( std::list< Statement* > &statements ) { SemanticError errors; for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) { if ( ! stmtsToAddAfter.empty() ) { statements.splice( i, stmtsToAddAfter ); } // if try { *i = (*i)->acceptMutator( *this ); } catch ( SemanticError &e ) { errors.append( e ); } // try if ( ! stmtsToAdd.empty() ) { statements.splice( i, stmtsToAdd ); } // if } // for if ( ! stmtsToAddAfter.empty() ) { statements.splice( statements.end(), stmtsToAddAfter ); } // if if ( ! errors.isEmpty() ) { throw errors; } } Statement * PolyMutator::mutateStatement( Statement *stmt ) { // don't want statements from outer CompoundStmts to be added to this CompoundStmt ValueGuard< std::list< Statement* > > oldStmtsToAdd( stmtsToAdd ); ValueGuard< std::list< Statement* > > oldStmtsToAddAfter( stmtsToAddAfter ); ValueGuard< TypeSubstitution * > oldEnv( env ); stmtsToAdd.clear(); stmtsToAddAfter.clear(); Statement *newStmt = maybeMutate( 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( newStmt ); compound->get_kids().splice( compound->get_kids().end(), stmtsToAddAfter ); // doEndScope(); return compound; } else { return newStmt; } } Expression * PolyMutator::mutateExpression( Expression *expr ) { if ( expr ) { if ( expr->get_env() ) { env = expr->get_env(); } // xxx - should env be cloned (or moved) onto the result of the mutate? return expr->acceptMutator( *this ); } else { return expr; } } CompoundStmt * PolyMutator::mutate(CompoundStmt *compoundStmt) { doBeginScope(); mutateStatementList( compoundStmt->get_kids() ); doEndScope(); return compoundStmt; } Statement * PolyMutator::mutate(IfStmt *ifStmt) { ifStmt->set_condition( mutateExpression( ifStmt->get_condition() ) ); ifStmt->set_thenPart( mutateStatement( ifStmt->get_thenPart() ) ); ifStmt->set_elsePart( mutateStatement( ifStmt->get_elsePart() ) ); return ifStmt; } Statement * PolyMutator::mutate(WhileStmt *whileStmt) { whileStmt->set_condition( mutateExpression( whileStmt->get_condition() ) ); whileStmt->set_body( mutateStatement( whileStmt->get_body() ) ); return whileStmt; } Statement * PolyMutator::mutate(ForStmt *forStmt) { mutateAll( forStmt->get_initialization(), *this ); forStmt->set_condition( mutateExpression( forStmt->get_condition() ) ); forStmt->set_increment( mutateExpression( forStmt->get_increment() ) ); forStmt->set_body( mutateStatement( forStmt->get_body() ) ); return forStmt; } Statement * PolyMutator::mutate(SwitchStmt *switchStmt) { switchStmt->set_condition( mutateExpression( switchStmt->get_condition() ) ); mutateStatementList( switchStmt->get_statements() ); return switchStmt; } Statement * PolyMutator::mutate(CaseStmt *caseStmt) { caseStmt->set_condition( mutateExpression( caseStmt->get_condition() ) ); mutateStatementList( caseStmt->get_statements() ); return caseStmt; } Statement * PolyMutator::mutate(TryStmt *tryStmt) { tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) ); mutateAll( tryStmt->get_catchers(), *this ); tryStmt->set_finally( maybeMutate( tryStmt->get_finally(), *this ) ); return tryStmt; } Statement * PolyMutator::mutate(CatchStmt *cathStmt) { cathStmt->set_body( mutateStatement( cathStmt->get_body() ) ); cathStmt->set_cond( maybeMutate( cathStmt->get_cond(), *this ) ); cathStmt->set_decl( maybeMutate( cathStmt->get_decl(), *this ) ); return cathStmt; } Statement * PolyMutator::mutate(ReturnStmt *retStmt) { retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); return retStmt; } Statement * PolyMutator::mutate(ExprStmt *exprStmt) { exprStmt->set_expr( mutateExpression( exprStmt->get_expr() ) ); return exprStmt; } Expression * PolyMutator::mutate(UntypedExpr *untypedExpr) { for ( std::list< Expression* >::iterator i = untypedExpr->get_args().begin(); i != untypedExpr->get_args().end(); ++i ) { *i = mutateExpression( *i ); } // for return untypedExpr; } Expression *PolyMutator::mutate( StmtExpr * stmtExpr ) { // don't want statements from outer CompoundStmts to be added to this StmtExpr ValueGuard< std::list< Statement* > > oldStmtsToAdd( stmtsToAdd ); ValueGuard< std::list< Statement* > > oldStmtsToAddAfter( stmtsToAddAfter ); ValueGuard< TypeSubstitution * > oldEnv( env ); // xxx - not sure if this is needed, along with appropriate reset, but I don't think so... // ValueGuard< TyVarMap > oldScopeTyVars( scopeTyVars ); stmtsToAdd.clear(); stmtsToAddAfter.clear(); // scopeTyVars.clear(); return Parent::mutate( stmtExpr ); } Initializer *PolyMutator::mutate( SingleInit *singleInit ) { singleInit->set_value( mutateExpression( singleInit->get_value() ) ); return singleInit; } } // namespace GenPoly // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //