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

package gen;

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




/** Representation of Bin */
public class Bin extends Exp{
    protected final Oper op;
    protected final Exp left;
    protected final Exp right;

    /** Construct a(n) Bin Instance */
    public Bin(Oper op, Exp left, Exp right){
        this.op = op;
        this.left = left;
        this.right = right;
    }
    /** Is the given object Equal to this Bin? */
    public boolean equals(Object o){
        if(!(o instanceof Bin))return false;
        if(o == this)return true;
        Bin oo = (Bin)o;
        return (((Object)op).equals(oo.op))&&(((Object)left).equals(oo.left))&&(((Object)right).equals(oo.right));
    }
    /** Parse an instance of Bin from the given String */
    public static Bin parse(String inpt) throws ParseException{
        return new TheParser(new java.io.StringReader(inpt)).parse_Bin();
    }
    /** Parse an instance of Bin from the given Stream */
    public static Bin parse(java.io.InputStream inpt) throws ParseException{
        return new TheParser(inpt).parse_Bin();
    }
    /** Parse an instance of Bin from the given Reader */
    public static Bin parse(java.io.Reader inpt) throws ParseException{
        return new TheParser(inpt).parse_Bin();
    }

    /** Field Class for Bin.op */
    public static class op extends edu.neu.ccs.demeterf.control.Fields.any{}
    /** Field Class for Bin.left */
    public static class left extends edu.neu.ccs.demeterf.control.Fields.any{}
    /** Field Class for Bin.right */
    public static class right extends edu.neu.ccs.demeterf.control.Fields.any{}

    public int eval(Env ev){ return op.eval(left.eval(ev), right.eval(ev)); }
    public List<Op> compile(List<ident> env){
        return right.compile(env)
            .append(left.compile(env))
            .append(op.compile(env));
    }
    public <X> X accept(Vis<X> v){ return v.visit(this); }
    public Exp simplify(){
        Exp l = left.simplify(),
            r = right.simplify();
        if(op.isSub()){
            if(left.isNum()){
                if(right.isNum()){
                    if(right.isZero()){
                        return left;
                    }else{
                        return new Num(((Num)left).val-((Num)right).val).simplify();
                    }
                }
            }else{
                if(right.isZero()){
                    return left;
                }
            }
        }
        return new Bin(op,l,r);
    }
    public int maxEnv(){ return Math.max(left.maxEnv(),right.maxEnv()); }
 
    /** DGP method from Class Print */
    public String print(){ return gen.Print.PrintM(this); }
    /** Getter for field Bin.right */
    public Exp getRight(){ return right; }
    /** Getter for field Bin.left */
    public Exp getLeft(){ return left; }
    /** Getter for field Bin.op */
    public Oper getOp(){ return op; }

}