package net.jhorstmann.i18n.tools.expr;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
public class TernaryExpression extends Expression {
private Expression ifExpr;
private Expression thenExpr;
private Expression elseExpr;
public TernaryExpression(Expression ifExpr, Expression thenExpr, Expression elseExpr) {
this.ifExpr = ifExpr;
this.thenExpr = thenExpr;
this.elseExpr = elseExpr;
}
@Override
public long eval(long n) {
long cond = ifExpr.eval(n);
return cond != 0 ? thenExpr.eval(n) : elseExpr.eval(n);
}
@Override
public boolean isBool() {
return thenExpr.isBool() && elseExpr.isBool();
}
@Override
public void validate() throws InvalidExpressionException {
if (!ifExpr.isBool()) {
throw new InvalidExpressionException("Condition must be of boolean type");
}
}
@Override
public String toString() {
return "(" + ifExpr + ") ? (" + thenExpr + ") : (" + elseExpr + ")";
}
@Override
public void compile(GeneratorAdapter ga, int narg) {
Label thenLabel = new Label();
Label retLabel = new Label();
ifExpr.compile(ga, narg);
ga.push(0L);
ga.ifCmp(Type.LONG_TYPE, GeneratorAdapter.NE, thenLabel);
elseExpr.compile(ga, narg);
ga.goTo(retLabel);
ga.mark(thenLabel);
thenExpr.compile(ga, narg);
ga.mark(retLabel);
}
@Override
public int computeStackSize() {
return Math.max(2+ifExpr.computeStackSize(), Math.max(thenExpr.computeStackSize(), elseExpr.computeStackSize()));
}
}