better ternary operator resolving
This commit is contained in:
@@ -68,24 +68,7 @@ public class ExpressionOptimizerBottomUp extends ExpressionModifier {
|
||||
var cond = modify(expr.getCond());
|
||||
var whenTrue = modify(expr.getWhenTrue());
|
||||
var whenFalse = modify(expr.getWhenFalse());
|
||||
if (whenTrue == ConstantExpression.V1 && whenFalse == ConstantExpression.V0) {
|
||||
//x ? 1 : 0 -> x
|
||||
return cond;
|
||||
} else if (whenTrue == ConstantExpression.V0 && whenFalse == ConstantExpression.V1) {
|
||||
//x ? 0 : 1 -> !x
|
||||
return modify(new UnaryExpression(cond, UnaryExpression.Operator.NOT));
|
||||
} else if (whenFalse == ConstantExpression.V0) {
|
||||
//x ? y : 0 -> x && y
|
||||
return modify(new AndExpression(cond, whenTrue));
|
||||
} else if (whenFalse == ConstantExpression.V1) {
|
||||
//x ? y : 1 -> !x or y
|
||||
return modify(new OrExpression(new UnaryExpression(cond, UnaryExpression.Operator.NOT), whenTrue));
|
||||
} else if (whenTrue instanceof TernaryExpression t && whenFalse == t.getWhenFalse()) {
|
||||
// x ? (y ? z : u) : u -> (x && y) ? z : u
|
||||
return new TernaryExpression(new AndExpression(cond, t.getCond()), t.getWhenTrue(), t.getWhenFalse());
|
||||
} else {
|
||||
return super.modifyTernary(expr);
|
||||
}
|
||||
return TernaryOptimizerUtil.optimizeTernary(new TernaryExpression(cond, whenTrue, whenFalse));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -63,24 +63,7 @@ public class ExpressionOptimizerTopDown extends ExpressionModifier {
|
||||
|
||||
@Override
|
||||
public Expression modifyTernary(TernaryExpression expr) {
|
||||
if (expr.getWhenFalse() == ConstantExpression.V1 && expr.getWhenFalse() == ConstantExpression.V0) {
|
||||
//x ? 1 : 0 -> x
|
||||
return modify(expr.getCond());
|
||||
} else if (expr.getWhenFalse() == ConstantExpression.V0 && expr.getWhenFalse() == ConstantExpression.V1) {
|
||||
//x ? 0 : 1 -> !x
|
||||
return modify(new UnaryExpression(expr.getCond(), UnaryExpression.Operator.NOT));
|
||||
} else if (expr.getWhenFalse() == ConstantExpression.V0) {
|
||||
//x ? y : 0 -> x && y
|
||||
return modify(new AndExpression(expr.getCond(), expr.getWhenTrue()));
|
||||
} else if (expr.getWhenFalse() == ConstantExpression.V1) {
|
||||
//x ? y : 1 -> !x or y
|
||||
return modify(new OrExpression(new UnaryExpression(expr.getCond(), UnaryExpression.Operator.NOT), expr.getWhenTrue()));
|
||||
} else if (expr.getWhenTrue() instanceof TernaryExpression t && expr.getWhenFalse() == t.getWhenFalse()) {
|
||||
// x ? (y ? z : u) : u -> (x && y) ? z : u
|
||||
return new TernaryExpression(new AndExpression(expr.getCond(), t.getCond()), t.getWhenTrue(), t.getWhenFalse());
|
||||
} else {
|
||||
return super.modifyTernary(expr);
|
||||
}
|
||||
return modify(TernaryOptimizerUtil.optimizeTernary(expr));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package jef.expressions.modifier;
|
||||
|
||||
import jef.expressions.AndExpression;
|
||||
import jef.expressions.ConstantExpression;
|
||||
import jef.expressions.Expression;
|
||||
import jef.expressions.OrExpression;
|
||||
import jef.expressions.TernaryExpression;
|
||||
import jef.expressions.UnaryExpression;
|
||||
|
||||
public abstract class TernaryOptimizerUtil {
|
||||
public static Expression optimizeTernary(TernaryExpression expr) {
|
||||
if (expr.getWhenFalse() == ConstantExpression.V1 && expr.getWhenFalse() == ConstantExpression.V0) {
|
||||
//x ? 1 : 0 -> x
|
||||
return expr.getCond();
|
||||
} else if (expr.getWhenFalse() == ConstantExpression.V0 && expr.getWhenFalse() == ConstantExpression.V1) {
|
||||
//x ? 0 : 1 -> !x
|
||||
return new UnaryExpression(expr.getCond(), UnaryExpression.Operator.NOT);
|
||||
} else if (expr.getWhenFalse() == ConstantExpression.V0) {
|
||||
//x ? y : 0 -> x && y
|
||||
return new AndExpression(expr.getCond(), expr.getWhenTrue());
|
||||
} else if (expr.getWhenFalse() == ConstantExpression.V1) {
|
||||
//x ? y : 1 -> !x or y
|
||||
return new OrExpression(new UnaryExpression(expr.getCond(), UnaryExpression.Operator.NOT), expr.getWhenTrue());
|
||||
} else if (expr.getWhenTrue() instanceof TernaryExpression t && expr.getWhenFalse() == t.getWhenFalse()) {
|
||||
// x ? (y ? z : u) : u -> (x && y) ? z : u
|
||||
return new TernaryExpression(new AndExpression(expr.getCond(), t.getCond()), t.getWhenTrue(), t.getWhenFalse());
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,23 @@
|
||||
package jef.expressions.modifier;
|
||||
|
||||
import jef.expressions.AndExpression;
|
||||
import jef.expressions.BinaryExpression;
|
||||
import jef.expressions.ConstantExpression;
|
||||
import jef.expressions.Expression;
|
||||
import jef.expressions.OrExpression;
|
||||
import jef.expressions.TernaryExpression;
|
||||
import jef.expressions.UnaryExpression;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TernaryRewriter extends ExpressionModifier {
|
||||
@Override
|
||||
public Expression modifyTernary(TernaryExpression expr) {
|
||||
return new OrExpression(new AndExpression(expr.getCond(), expr.getWhenTrue()),
|
||||
new AndExpression(new UnaryExpression(expr.getCond(), UnaryExpression.Operator.NOT), expr.getWhenFalse()));
|
||||
// return new OrExpression(new AndExpression(expr.getCond(), expr.getWhenTrue()), expr.getWhenFalse());
|
||||
//first optimize
|
||||
var newExpr = TernaryOptimizerUtil.optimizeTernary(expr);
|
||||
if (!(newExpr instanceof TernaryExpression)) {
|
||||
return modify(newExpr);
|
||||
}
|
||||
expr = (TernaryExpression) newExpr;
|
||||
|
||||
//rewrite
|
||||
return modify(new OrExpression(new AndExpression(expr.getCond(), expr.getWhenTrue()),
|
||||
new AndExpression(new UnaryExpression(expr.getCond(), UnaryExpression.Operator.NOT), expr.getWhenFalse())));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user