better ternary operator resolving
This commit is contained in:
@@ -68,24 +68,7 @@ public class ExpressionOptimizerBottomUp extends ExpressionModifier {
|
|||||||
var cond = modify(expr.getCond());
|
var cond = modify(expr.getCond());
|
||||||
var whenTrue = modify(expr.getWhenTrue());
|
var whenTrue = modify(expr.getWhenTrue());
|
||||||
var whenFalse = modify(expr.getWhenFalse());
|
var whenFalse = modify(expr.getWhenFalse());
|
||||||
if (whenTrue == ConstantExpression.V1 && whenFalse == ConstantExpression.V0) {
|
return TernaryOptimizerUtil.optimizeTernary(new TernaryExpression(cond, whenTrue, whenFalse));
|
||||||
//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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -63,24 +63,7 @@ public class ExpressionOptimizerTopDown extends ExpressionModifier {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Expression modifyTernary(TernaryExpression expr) {
|
public Expression modifyTernary(TernaryExpression expr) {
|
||||||
if (expr.getWhenFalse() == ConstantExpression.V1 && expr.getWhenFalse() == ConstantExpression.V0) {
|
return modify(TernaryOptimizerUtil.optimizeTernary(expr));
|
||||||
//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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
package jef.expressions.modifier;
|
||||||
|
|
||||||
import jef.expressions.AndExpression;
|
import jef.expressions.AndExpression;
|
||||||
import jef.expressions.BinaryExpression;
|
|
||||||
import jef.expressions.ConstantExpression;
|
|
||||||
import jef.expressions.Expression;
|
import jef.expressions.Expression;
|
||||||
import jef.expressions.OrExpression;
|
import jef.expressions.OrExpression;
|
||||||
import jef.expressions.TernaryExpression;
|
import jef.expressions.TernaryExpression;
|
||||||
import jef.expressions.UnaryExpression;
|
import jef.expressions.UnaryExpression;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class TernaryRewriter extends ExpressionModifier {
|
public class TernaryRewriter extends ExpressionModifier {
|
||||||
@Override
|
@Override
|
||||||
public Expression modifyTernary(TernaryExpression expr) {
|
public Expression modifyTernary(TernaryExpression expr) {
|
||||||
return new OrExpression(new AndExpression(expr.getCond(), expr.getWhenTrue()),
|
//first optimize
|
||||||
new AndExpression(new UnaryExpression(expr.getCond(), UnaryExpression.Operator.NOT), expr.getWhenFalse()));
|
var newExpr = TernaryOptimizerUtil.optimizeTernary(expr);
|
||||||
// return new OrExpression(new AndExpression(expr.getCond(), expr.getWhenTrue()), expr.getWhenFalse());
|
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