From eee94e9c452987e51be488bc7a4ed74e92b8f90a Mon Sep 17 00:00:00 2001 From: wea_ondara Date: Thu, 14 Jul 2022 18:05:03 +0200 Subject: [PATCH] better ternary operator resolving --- .../modifier/ExpressionOptimizerBottomUp.java | 19 +----------- .../modifier/ExpressionOptimizerTopDown.java | 19 +----------- .../modifier/TernaryOptimizerUtil.java | 30 +++++++++++++++++++ .../expressions/modifier/TernaryRewriter.java | 17 ++++++----- 4 files changed, 42 insertions(+), 43 deletions(-) create mode 100644 src/main/java/jef/expressions/modifier/TernaryOptimizerUtil.java diff --git a/src/main/java/jef/expressions/modifier/ExpressionOptimizerBottomUp.java b/src/main/java/jef/expressions/modifier/ExpressionOptimizerBottomUp.java index ed66d43..01dd8ee 100644 --- a/src/main/java/jef/expressions/modifier/ExpressionOptimizerBottomUp.java +++ b/src/main/java/jef/expressions/modifier/ExpressionOptimizerBottomUp.java @@ -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 diff --git a/src/main/java/jef/expressions/modifier/ExpressionOptimizerTopDown.java b/src/main/java/jef/expressions/modifier/ExpressionOptimizerTopDown.java index 5556897..e244f32 100644 --- a/src/main/java/jef/expressions/modifier/ExpressionOptimizerTopDown.java +++ b/src/main/java/jef/expressions/modifier/ExpressionOptimizerTopDown.java @@ -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 diff --git a/src/main/java/jef/expressions/modifier/TernaryOptimizerUtil.java b/src/main/java/jef/expressions/modifier/TernaryOptimizerUtil.java new file mode 100644 index 0000000..3157d9e --- /dev/null +++ b/src/main/java/jef/expressions/modifier/TernaryOptimizerUtil.java @@ -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; + } +} diff --git a/src/main/java/jef/expressions/modifier/TernaryRewriter.java b/src/main/java/jef/expressions/modifier/TernaryRewriter.java index 4e3ddd1..642839e 100644 --- a/src/main/java/jef/expressions/modifier/TernaryRewriter.java +++ b/src/main/java/jef/expressions/modifier/TernaryRewriter.java @@ -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()))); } }