// created by jag 1.0 (c) 2002 ats@cs.rit.edu

package expr.type;
import edu.rit.cs.jag.Visitor;
/** filter to evaluate a {@link TVM} tree.
  */
public class Eval extends Filter implements Visitor {
  /** last computed values.
    */
  protected boolean b;
  protected int i;
  protected double d;
  protected String s;
  /** print action stream.
      Can be replaced to reroute output.
      BUG: should be a self-flushing <tt>PrintWriter</tt>.
    */
  protected transient java.io.PrintStream out;
  /** returns print action stream. Defaults to System.out.
    */
  protected java.io.PrintStream out () {
    return out != null ? out : (out = System.out);
  }
  /** visits an object.
      This is a facade for the class search.
      @param object to be visited, not null.
      @return result of action.
      @throws NoRuleException if no rule can be found.
    */
  public Object visit (Object object) throws Exception {
    java.util.List list =
      object instanceof java.util.List ? (java.util.List)object : null;
    int degree = list != null ? list.size() : 0;
    return edu.rit.cs.jag.Rule.visit(this, _rules, object, degree, list);
  }
  /** visits an object, ignoring possible descendants.
      This is a facade for the class search with degree zero.
      @param object to be visited, not null.
      @return result of action.
      @throws NoRuleException if no rule can be found.
    */
  public Object visit0 (Object object) throws Exception {
    return edu.rit.cs.jag.Rule.visit(this, _rules, object, 0, null);
  }
  /** visits an object.
      @param _action index.
      @param _object to be visited, not null.
      @return result of action.
      @throws NoRuleException if no rule can be found.
    */
  public Object visit (int _action, Object _object) throws Exception {
    Object _result = null;
    switch (_action) {

    case 14:
 for (int n = 0; n < ((TVM.Lines)_object).size(); ++n)
                                            visit(((TVM.Lines)_object).get(n));
                                        
      break;

    case 20:
{ visit(((java.util.List)_object).get(0));
 boolean left = b; visit(((java.util.List)_object).get(1));
 b = left & b; }
      break;

    case 21:
 visit(((java.util.List)_object).get(0));
 if (b) visit(((java.util.List)_object).get(1));
 
      break;

    case 22:
{ visit(((java.util.List)_object).get(0));
 boolean left = b; visit(((java.util.List)_object).get(1));
 b = left == b; }
      break;

    case 23:
{ visit(((java.util.List)_object).get(0));
 boolean left = b; visit(((java.util.List)_object).get(1));
 b = left != b; }
      break;

    case 24:
 visit(((java.util.List)_object).get(0));
 b = !b; 
      break;

    case 25:
{ visit(((java.util.List)_object).get(0));
 boolean left = b; visit(((java.util.List)_object).get(1));
 b = left | b; }
      break;

    case 26:
 visit(((java.util.List)_object).get(0));
 if (!b) visit(((java.util.List)_object).get(1));
 
      break;

    case 27:
 visit(((java.util.List)_object).get(0));
 System.err.println(b); 
      break;

    case 28:
{ visit(((java.util.List)_object).get(0));
 boolean left = b; visit(((java.util.List)_object).get(1));
 b = left ^ b; }
      break;

    case 29:
 b = ((Boolean)((java.util.List)_object).get(0)).booleanValue(); 
      break;

    case 33:
{ visit(((java.util.List)_object).get(0));
 double left = d; visit(((java.util.List)_object).get(1));
 d = left + d; }
      break;

    case 34:
{ visit(((java.util.List)_object).get(0));
 double left = d; visit(((java.util.List)_object).get(1));
 d = left / d; }
      break;

    case 35:
{ visit(((java.util.List)_object).get(0));
 double left = d; visit(((java.util.List)_object).get(1));
 b = left == d; }
      break;

    case 36:
{ visit(((java.util.List)_object).get(0));
 double left = d; visit(((java.util.List)_object).get(1));
 b = left >= d; }
      break;

    case 37:
{ visit(((java.util.List)_object).get(0));
 double left = d; visit(((java.util.List)_object).get(1));
 b = left > d; }
      break;

    case 38:
{ visit(((java.util.List)_object).get(0));
 double left = d; visit(((java.util.List)_object).get(1));
 b = left <= d; }
      break;

    case 39:
{ visit(((java.util.List)_object).get(0));
 double left = d; visit(((java.util.List)_object).get(1));
 b = left < d; }
      break;

    case 40:
 visit(((java.util.List)_object).get(0));
 d = -d; 
      break;

    case 41:
{ visit(((java.util.List)_object).get(0));
 double left = d; visit(((java.util.List)_object).get(1));
 d = left * d; }
      break;

    case 42:
{ visit(((java.util.List)_object).get(0));
 double left = d; visit(((java.util.List)_object).get(1));
 b = left != d; }
      break;

    case 43:
 visit(((java.util.List)_object).get(0));
 System.err.println(d); 
      break;

    case 44:
{ visit(((java.util.List)_object).get(0));
 double left = d; visit(((java.util.List)_object).get(1));
 d = left - d; }
      break;

    case 45:
 d = ((Double)((java.util.List)_object).get(0)).doubleValue(); 
      break;

    case 49:
 visit(((java.util.List)_object).get(0));
 d = i; 
      break;

    case 50:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 i = left + i; }
      break;

    case 51:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 i = left & i; }
      break;

    case 52:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 i = left / i; }
      break;

    case 53:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 b = left == i; }
      break;

    case 54:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 b = left >= i; }
      break;

    case 55:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 b = left > i; }
      break;

    case 56:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 b = left <= i; }
      break;

    case 57:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 i = left << i; }
      break;

    case 58:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 b = left < i; }
      break;

    case 59:
 visit(((java.util.List)_object).get(0));
 i = -i; 
      break;

    case 60:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 i = left % i; }
      break;

    case 61:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 i = left * i; }
      break;

    case 62:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 b = left != i; }
      break;

    case 64:
 visit(((java.util.List)_object).get(0));
 i = ~i; 
      break;

    case 65:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 i = left | i; }
      break;

    case 66:
 visit(((java.util.List)_object).get(0));
 System.err.println(i); 
      break;

    case 67:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 i = left >> i; }
      break;

    case 68:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 i = left - i; }
      break;

    case 69:
{ visit(((java.util.List)_object).get(0));
 int left = i; visit(((java.util.List)_object).get(1));
 i = left ^ i; }
      break;

    case 70:
 i = ((Long)((java.util.List)_object).get(0)).intValue(); 
      break;

    case 74:
{ visit(((java.util.List)_object).get(0));
 String left = s; visit(((java.util.List)_object).get(1));
 s = left + s; }
      break;

    case 75:
{ visit(((java.util.List)_object).get(0));
 String left = s; visit(((java.util.List)_object).get(1));
 b = left.equals(s); }
      break;

    case 76:
{ visit(((java.util.List)_object).get(0));
 String left = s; visit(((java.util.List)_object).get(1));
 b = left.compareTo(s) >= 0; }
      break;

    case 77:
{ visit(((java.util.List)_object).get(0));
 String left = s; visit(((java.util.List)_object).get(1));
 b = left.compareTo(s) > 0; }
      break;

    case 78:
{ visit(((java.util.List)_object).get(0));
 String left = s; visit(((java.util.List)_object).get(1));
 b = left.compareTo(s) <= 0; }
      break;

    case 79:
{ visit(((java.util.List)_object).get(0));
 String left = s; visit(((java.util.List)_object).get(1));
 b = left.compareTo(s) < 0; }
      break;

    case 80:
{ visit(((java.util.List)_object).get(0));
 String left = s; visit(((java.util.List)_object).get(1));
 b = !left.equals(s); }
      break;

    case 81:
 visit(((java.util.List)_object).get(0));
 System.err.println(s); 
      break;

    case 82:
 s = (((String)((java.util.List)_object).get(0))); 
      break;

    default:
      throw new Error(_action+": unexpected action index");
    }
    return _result;
  }
  /** maps class to array of {@link edu.rit.cs.jag.Rule}.
    */
  protected final java.util.HashMap _rules = new java.util.HashMap();
  {
    _rules.put(TVM.BPrint.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Boolean.class, }, false, 27),
    });
    _rules.put(TVM.ILe.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 56),
    });
    _rules.put(TVM.I2D.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, }, false, 49),
    });
    _rules.put(TVM.DPrint.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Double.class, }, false, 43),
    });
    _rules.put(TVM.BXor.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Boolean.class, TVM.Boolean.class, }, false, 28),
    });
    _rules.put(TVM.IOr.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 65),
    });
    _rules.put(TVM.BEq.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Boolean.class, TVM.Boolean.class, }, false, 22),
    });
    _rules.put(TVM.IEq.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 53),
    });
    _rules.put(TVM.IGe.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 54),
    });
    _rules.put(TVM.IMod.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 60),
    });
    _rules.put(TVM.DMul.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Double.class, TVM.Double.class, }, false, 41),
    });
    _rules.put(TVM.IGt.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 55),
    });
    _rules.put(TVM.DAdd.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Double.class, TVM.Double.class, }, false, 33),
    });
    _rules.put(TVM.DGt.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Double.class, TVM.Double.class, }, false, 37),
    });
    _rules.put(TVM.BNe.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Boolean.class, TVM.Boolean.class, }, false, 23),
    });
    _rules.put(TVM.BAndIf.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Boolean.class, TVM.Boolean.class, }, false, 21),
    });
    _rules.put(TVM.ILt.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 58),
    });
    _rules.put(TVM.DLe.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Double.class, TVM.Double.class, }, false, 38),
    });
    _rules.put(TVM.IDiv.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 52),
    });
    _rules.put(TVM.INeg.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, }, false, 64),
    });
    _rules.put(TVM.DEq.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Double.class, TVM.Double.class, }, false, 35),
    });
    _rules.put(TVM.ISub.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 68),
    });
    _rules.put(TVM.BAnd.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Boolean.class, TVM.Boolean.class, }, false, 20),
    });
    _rules.put(TVM.SLt.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.String.class, TVM.String.class, }, false, 79),
    });
    _rules.put(TVM.Boolean.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ Boolean.class, }, false, 29),
    });
    _rules.put(TVM.IXor.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 69),
    });
    _rules.put(TVM.ILsh.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 57),
    });
    _rules.put(TVM.DNe.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Double.class, TVM.Double.class, }, false, 42),
    });
    _rules.put(TVM.DLt.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Double.class, TVM.Double.class, }, false, 39),
    });
    _rules.put(TVM.SEq.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.String.class, TVM.String.class, }, false, 75),
    });
    _rules.put(TVM.DGe.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Double.class, TVM.Double.class, }, false, 36),
    });
    _rules.put(TVM.BNot.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Boolean.class, }, false, 24),
    });
    _rules.put(TVM.DSub.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Double.class, TVM.Double.class, }, false, 44),
    });
    _rules.put(TVM.Int.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ Long.class, }, false, 70),
    });
    _rules.put(TVM.BOrIf.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Boolean.class, TVM.Boolean.class, }, false, 26),
    });
    _rules.put(TVM.IMul.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 61),
    });
    _rules.put(TVM.SGt.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.String.class, TVM.String.class, }, false, 77),
    });
    _rules.put(TVM.BOr.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Boolean.class, TVM.Boolean.class, }, false, 25),
    });
    _rules.put(TVM.Double.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ Double.class, }, false, 45),
    });
    _rules.put(TVM.SPrint.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.String.class, }, false, 81),
    });
    _rules.put(TVM.Lines.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Node.class, }, true, 14),
    });
    _rules.put(TVM.String.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ String.class, }, false, 82),
    });
    _rules.put(TVM.DDiv.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Double.class, TVM.Double.class, }, false, 34),
    });
    _rules.put(TVM.SLe.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.String.class, TVM.String.class, }, false, 78),
    });
    _rules.put(TVM.IMinus.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, }, false, 59),
    });
    _rules.put(TVM.IAnd.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 51),
    });
    _rules.put(TVM.SAdd.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.String.class, TVM.String.class, }, false, 74),
    });
    _rules.put(TVM.IPrint.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, }, false, 66),
    });
    _rules.put(TVM.INe.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 62),
    });
    _rules.put(TVM.DMinus.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Double.class, }, false, 40),
    });
    _rules.put(TVM.IRsh.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 67),
    });
    _rules.put(TVM.SNe.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.String.class, TVM.String.class, }, false, 80),
    });
    _rules.put(TVM.SGe.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.String.class, TVM.String.class, }, false, 76),
    });
    _rules.put(TVM.IAdd.class, new edu.rit.cs.jag.Rule[]{
      new edu.rit.cs.jag.Rule(new Class[]{ TVM.Int.class, TVM.Int.class, }, false, 50),
    });
  }
  static {
    visitor = new Eval();
  }
}

