/** Our internal representation of a IfZero expr * in the A0 language. * See http://www.radford.edu/itec380/2022spring-ibarland/Project * * @author Ian Barland * @version 2018.Nov.16 */ public class IfZero extends Expr { static final String START_TOKEN = "zro"; static final String CONT1_TOKEN = "?"; static final String CONT2_TOKEN = ":"; Expr test, thenAns, elseAns; IfZero( Expr _test, Expr _thenAns, Expr _elseAns) { this.test = _test; this.thenAns = _thenAns; this.elseAns = _elseAns; } public String toString( /* IfZero this */ ) { return START_TOKEN + " " + this.test.toString() + " " + CONT1_TOKEN + " " + this.thenAns.toString() + " " + CONT2_TOKEN + " " + this.elseAns.toString() ; } public static IfZero parse( java.util.Scanner s, String punctuation ) { UtilIan.verifyToken( UtilIan.nextSplittingBy(s,punctuation), START_TOKEN ); // consume&verify the "zro" // NOTE: recur with `Expr.parse` -- not `parse` = `IfZero.parse` which is NOT what we want! Expr theTest = Expr.parse(s,punctuation); UtilIan.verifyToken( UtilIan.nextSplittingBy(s,punctuation), CONT1_TOKEN ); // consume&verify the "?" Expr theThenAnswer = Expr.parse(s,punctuation); UtilIan.verifyToken( UtilIan.nextSplittingBy(s,punctuation), CONT2_TOKEN ); // consume&verify the ":" Expr theElseAnswer = Expr.parse(s,punctuation); return new IfZero(theTest,theThenAnswer,theElseAnswer); } static final double EPSILON = 1e-10; public Value eval() { if ( Math.abs(((Num)(this.test.eval())).doubleValue()) < EPSILON ) { return this.thenAns.eval(); } else { return this.elseAns.eval(); } } @Override public boolean equals( /* IfZero this, */ Object that) { if (this==that) { return true; } else if (that==null) { return false; } else if (this.getClass() != that.getClass()) { return false; } else { IfZero thatt = (IfZero) that; return this.test.equals(thatt.test) && this.thenAns.equals(thatt.thenAns) && this.elseAns.equals(thatt.elseAns); } } @Override public int hashCode() { if (cachedHash == null) { int hashSoFar = 0; hashSoFar += this.test.hashCode(); hashSoFar *= 31; hashSoFar += this.thenAns.hashCode(); hashSoFar *= 31; hashSoFar += this.elseAns.hashCode(); cachedHash = hashSoFar; } return cachedHash; } private Integer cachedHash = null; }