/** Our internal representation of a IfZero expr * in the E0 language. * See http://www.radford.edu/itec380/2022fall-ibarland/Project * * @author Ian Barland * @version 2023.Apr.10 */ public record IfZero(Expr test, Expr thenAns, Expr elseAns) implements Expr { static final String START_TOKEN = "if"; static final String CONT_TOKEN1a = "!"; static final String CONT_TOKEN1b = "="; static final String CONT_TOKEN2 = "?"; static final String CONT_TOKEN3 = ":"; @Override public String toString() { return START_TOKEN + " " + this.test.toString() + " " + CONT_TOKEN1a + CONT_TOKEN1b + "0" + " " + CONT_TOKEN2 + " " + this.thenAns.toString() + " " + CONT_TOKEN3 + " " + this.elseAns.toString() ; } /** “@Override” {@link Expr#parse} */ public static IfZero parse( java.util.Scanner s, String punctuation ) { UtilIan.verifyToken( UtilIan.nextSplittingBy(s,punctuation), START_TOKEN ); // consume&verify the "if" // 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), CONT_TOKEN1a ); // consume&verify the "!" of "!=0 ?" UtilIan.verifyToken( UtilIan.nextSplittingBy(s,punctuation), CONT_TOKEN1b ); // consume&verify the "=" double cont_token1c = Num.parse(s,punctuation).doubleValue(); // consume&verify the "0", via Num.parse assert cont_token1c == 0.0; UtilIan.verifyToken( UtilIan.nextSplittingBy(s,punctuation), CONT_TOKEN2 ); // consume&verify the "?" Expr theThenAnswer = Expr.parse(s,punctuation); UtilIan.verifyToken( UtilIan.nextSplittingBy(s,punctuation), CONT_TOKEN3 ); // consume&verify the ":" Expr theElseAnswer = Expr.parse(s,punctuation); return new IfZero(theTest,theThenAnswer,theElseAnswer); } static final double EPSILON = 1e-10; @Override public Value eval() { if ( Math.abs(((Num)(this.test.eval())).doubleValue()) < EPSILON ) { return this.thenAns.eval(); } else { return this.elseAns.eval(); } } }