// ** This class was generated with DemFGen (vers:09/27/2009)

import gen.*;
import edu.neu.ccs.demeterf.lib.*;
import edu.neu.ccs.demeterf.lib.*;
import edu.neu.ccs.demeterf.*;
import edu.neu.ccs.demeterf.lib.*;

public class InlineSimplify{
   private Simplify func;
   public InlineSimplify(Simplify f){ func = f; }

   public Exp traverse(Exp _h){ return traverseExp(_h); }

   public Var traverseVar(Var _h){
      ident _id = func.combine(_h.getId());
      return func.combine((Var)_h,(ident)_id);
   }
   public Sub traverseSub(Sub _h){
      return func.combine((Sub)_h);
   }
   public Num traverseSimplify$Zero(Simplify.Zero _h){
      int _val = func.combine(_h.getVal());
      return func.combine((Num)_h,(int)_val);
   }
   public Sub traverseOper(Oper _h){
      if(_h instanceof Sub) return this.traverseSub((Sub)_h);
      else throw new RuntimeException("Unknown Oper Variant");
   }
   public Num traverseNum(Num _h){
      if(_h instanceof Simplify.Zero) return this.traverseSimplify$Zero((Simplify.Zero)_h);

      int _val = func.combine(_h.getVal());
      return func.combine((Num)_h,(int)_val);
   }
   public Exp traverseIfz(Ifz _h){
      Exp _cnd = traverseExp(_h.getCnd());
      Exp _thn = traverseExp(_h.getThn());
      Exp _els = traverseExp(_h.getEls());
      /*[1..1]*/
      if((_cnd instanceof Simplify.Zero)){
         return func.combine((Ifz)_h,(Simplify.Zero)_cnd, (Exp)_thn, (Exp)_els);
      }else
      /*[1..1]*/
      if((_cnd instanceof Num)){
         return func.combine((Ifz)_h,(Num)_cnd, (Exp)_thn, (Exp)_els);
      }else{
         return func.combine((Ifz)_h,(Exp)_cnd, (Exp)_thn, (Exp)_els);
      }
   }
   public Exp traverseExp(Exp _h){
      if(_h instanceof Ifz) return this.traverseIfz((Ifz)_h);
      if(_h instanceof Def) return this.traverseDef((Def)_h);
      if(_h instanceof Bin) return this.traverseBin((Bin)_h);
      if(_h instanceof Var) return this.traverseVar((Var)_h);
      if(_h instanceof Num) return this.traverseNum((Num)_h);
      else throw new RuntimeException("Unknown Exp Variant");
   }
   public Exp traverseDef(Def _h){
      ident _id = func.combine(_h.getId());
      Exp _e = traverseExp(_h.getE());
      Exp _body = traverseExp(_h.getBody());
      /*[3..3]*/
      if((_body instanceof Num)){
         return func.combine((Def)_h,(ident)_id, (Exp)_e, (Num)_body);
      }else{
         return func.combine((Def)_h,(ident)_id, (Exp)_e, (Exp)_body);
      }
   }
   public Exp traverseBin(Bin _h){
      Sub _op = traverseOper(_h.getOp());
      Exp _left = traverseExp(_h.getLeft());
      Exp _right = traverseExp(_h.getRight());
      /*[1..1]*/
      if((_op instanceof Sub)){
         /*[2..2]*/
         if((_left instanceof Num)){
            /*[3..3]*/
             if((_right instanceof Num)){
                 if((_right instanceof Simplify.Zero)){
                     return func.combine((Bin)_h,(Sub)_op, (Num)_left, (Simplify.Zero)_right);
                 }else{
                     return func.combine((Bin)_h,(Sub)_op, (Num)_left, (Num)_right);
                 }
             }else{
                 return func.combine((Bin)_h,(Oper)_op, (Exp)_left, (Exp)_right);
             }
         }else{
             if((_right instanceof Simplify.Zero)){
                 return func.combine((Bin)_h,(Sub)_op, (Exp)_left, (Simplify.Zero)_right);
             }else{
                 return func.combine((Bin)_h,(Oper)_op, (Exp)_left, (Exp)_right);
             }
         }
      }else{
          return func.combine((Bin)_h,(Oper)_op, (Exp)_left, (Exp)_right);
      }
   }

}