/*
 * This file is part of the Cforall project
 *
 * $Id: PolyMutator.h,v 1.8 2005/08/29 20:14:13 rcbilson Exp $
 *
 */

#ifndef GENPOLY_POLYMUTATOR_H
#define GENPOLY_POLYMUTATOR_H

#include <map>
#include <string>
#include <list>

#include "GenPoly.h"

#include "SynTree/SynTree.h"
#include "SynTree/Declaration.h"
#include "SynTree/Mutator.h"

namespace GenPoly {

class PolyMutator : public Mutator
{
public:
  PolyMutator();

  virtual CompoundStmt* mutate(CompoundStmt *compoundStmt);
  virtual Statement* mutate(IfStmt *ifStmt);
  virtual Statement* mutate(WhileStmt *whileStmt);
  virtual Statement* mutate(ForStmt *forStmt);
  virtual Statement* mutate(SwitchStmt *switchStmt);
  virtual Statement* mutate(ChooseStmt *chooseStmt);
  virtual Statement* mutate(CaseStmt *caseStmt);
  virtual Statement* mutate(TryStmt *returnStmt);
  virtual Statement* mutate(CatchStmt *catchStmt);
  virtual Statement* mutate(ExprStmt *catchStmt);
  virtual Statement* mutate(ReturnStmt *catchStmt);
  
  virtual Expression* mutate(UntypedExpr *untypedExpr);
  
  // template method
  virtual void doEndScope() {}

protected:
  void mutateStatementList( std::list< Statement* > &statements );
  Statement* mutateStatement( Statement *stmt );
  Expression* mutateExpression( Expression *expr );
  static void makeTyVarMap( Type *type, TyVarMap &tyVarMap );
  
  TyVarMap scopeTyVars;
  TypeSubstitution *env;
  std::list< Statement* > stmtsToAdd;
  std::list< Statement* > stmtsToAddAfter;
};

} // namespace 

#endif /* #ifndef GENPOLY_POLYMUTATOR_H */
