// ** 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 InlineCompile{
   private Compile func;
   public InlineCompile(Compile f){ func = f; }

   public List<Op> traverse(Exp _h, List<ident> _targ_){ return traverseExp(_h, _targ_); }

   public List<Op> traverseVar(Var _h, List<ident> _targ_){
       ident _id = _h.getId();
      return func.combine((Var)_h,(ident)_id, (List<ident>)_targ_);
   }
   public List<Op> traverseSub(Sub _h, List<ident> _targ_){
      return func.combine((Sub)_h);
   }
   public List<Op> traverseOper(Oper _h, List<ident> _targ_){
      if(_h instanceof Sub) return this.traverseSub((Sub)_h, _targ_);
      else throw new RuntimeException("Unknown Oper Variant");
   }
   public List<Op> traverseNum(Num _h, List<ident> _targ_){
       int _val = _h.getVal();
      return func.combine((Num)_h,(int)_val);
   }
   public List<Op> traverseIfz(Ifz _h, List<ident> _targ_){
       List<Op> _cnd = traverseExp(_h.getCnd(), _targ_);
      List<Op> _thn = traverseExp(_h.getThn(), _targ_);
      List<Op> _els = traverseExp(_h.getEls(), _targ_);
      return func.combine((Ifz)_h,(List<Op>)_cnd, (List<Op>)_thn, (List<Op>)_els);
   }
   public List<Op> traverseExp(Exp _h, List<ident> _targ_){
      if(_h instanceof Ifz) return this.traverseIfz((Ifz)_h, _targ_);
      if(_h instanceof Def) return this.traverseDef((Def)_h, _targ_);
      if(_h instanceof Bin) return this.traverseBin((Bin)_h, _targ_);
      if(_h instanceof Var) return this.traverseVar((Var)_h, _targ_);
      if(_h instanceof Num) return this.traverseNum((Num)_h, _targ_);
      else throw new RuntimeException("Unknown Exp Variant");
   }
   public List<Op> traverseDef(Def _h, List<ident> _targ_){
       ident _id = _h.getId();
       List<Op> _e = traverseExp(_h.getE(), _targ_);
       List<Op> _body = traverseExp(_h.getBody(), func.update(_h, new Def.body(), _targ_));
      return func.combine((Def)_h,(ident)_id, (List<Op>)_e, (List<Op>)_body);
   }
   public List<Op> traverseBin(Bin _h, List<ident> _targ_){
       List<Op> _op = traverseOper(_h.getOp(), _targ_);
       List<Op> _left = traverseExp(_h.getLeft(), _targ_);
       List<Op> _right = traverseExp(_h.getRight(), _targ_);
      return func.combine((Bin)_h,(List<Op>)_op, (List<Op>)_left, (List<Op>)_right);
   }

}