package calc;

/** Binary formulas, like (a+b).
 * @author Gary T. Leavens
 */
public abstract class BinaryFormula extends UnaryFormula {
    /** The right register */
    private /*@ spec_public @*/ int right;
    
    /** Initialize this formula object to contain the given registers.
     * @param left, the left register's number.
     * @param right, the right register's number
     */
    //@ requires 0 <= left && left < Registers.NUM_REGS;
    //@ requires 0 <= right && right < Registers.NUM_REGS;
    //@ assignable this.left, this.right;
    //@ ensures this.left == left && this.right == right;
    public BinaryFormula(int left, int right) {
        super(left);
        this.right=right;
    }
       
    /** Return the value of the right register.
     * @return the right register's value
     */
    //@ assignable \nothing;
    //@ ensures \result == Registers.get(right);
    protected /*@ pure @*/ double rightValue() {
        return Registers.get(right);
    }
    
    // documentation comment and specification inherited    
    public int hashCode() {
        return super.hashCode() + right;
    }

    // documentation comment inherited
    //@ also
    //@   ensures \result ==> o instanceof BinaryFormula;
    //@   ensures \result ==> ((BinaryFormula)o).right == this.right;
    public boolean equals(Object o) {
        return super.equals(o) && o instanceof BinaryFormula
            && ((BinaryFormula)o).right == this.right;
    }
    
    public String toString() {
        return super.toString() + " " + this.opString()
             + " r" + right;
    }
    
    /** A string that represents the operation.
     * This is used in decoding.
     * @see #toString() */
    //@ assignable \nothing;
    //@ ensures \result != null;
    protected abstract String opString();

}