@Override public void visit(WhileStatement statement) { if (statement.getBody().size() == 1 && statement.getBody().get(0) instanceof WhileStatement) { WhileStatement innerLoop = (WhileStatement) statement.getBody().get(0); BreakToContinueReplacer replacer = new BreakToContinueReplacer(innerLoop, statement); replacer.visitSequence(innerLoop.getBody()); statement.getBody().clear(); statement.getBody().addAll(innerLoop.getBody()); } List<Statement> statements = processSequence(statement.getBody()); for (int i = 0; i < statements.size(); ++i) { if (statements.get(i) instanceof ContinueStatement) { ContinueStatement continueStmt = (ContinueStatement) statements.get(i); if (continueStmt.getTarget() == statement) { statements.subList(i, statements.size()).clear(); break; } } } statement.getBody().clear(); statement.getBody().addAll(statements); if (statement.getCondition() != null) { List<Statement> sequenceBackup = resultSequence; resultSequence = new ArrayList<>(); statement.getCondition().acceptVisitor(this); statement.setCondition(resultExpr); resultSequence = sequenceBackup; } while (true) { if (!statement.getBody().isEmpty() && statement.getBody().get(0) instanceof ConditionalStatement) { ConditionalStatement cond = (ConditionalStatement) statement.getBody().get(0); if (cond.getConsequent().size() == 1 && cond.getConsequent().get(0) instanceof BreakStatement) { BreakStatement breakStmt = (BreakStatement) cond.getConsequent().get(0); if (breakStmt.getTarget() == statement) { statement.getBody().remove(0); if (statement.getCondition() != null) { Expr newCondition = Expr.binary( BinaryOperation.AND, statement.getCondition(), ExprOptimizer.invert(cond.getCondition())); newCondition.setLocation(statement.getCondition().getLocation()); statement.setCondition(newCondition); } else { statement.setCondition(ExprOptimizer.invert(cond.getCondition())); } continue; } } } break; } resultStmt = statement; }
private void normalizeConditional(ConditionalStatement stmt) { if (stmt.getConsequent().isEmpty()) { stmt.getConsequent().addAll(stmt.getAlternative()); stmt.getAlternative().clear(); stmt.setCondition(ExprOptimizer.invert(stmt.getCondition())); } }
@Override public void visit(BinaryExpr expr) { switch (expr.getOperation()) { case AND: case OR: resultExpr = expr; return; default: break; } expr.getSecondOperand().acceptVisitor(this); Expr b = resultExpr; if (b instanceof ConstantExpr && expr.getOperation() == BinaryOperation.SUBTRACT) { if (tryMakePositive((ConstantExpr) b)) { expr.setOperation(BinaryOperation.ADD); } } expr.getFirstOperand().acceptVisitor(this); Expr a = resultExpr; Expr p = a; Expr q = b; boolean invert = false; if (isZero(p)) { Expr tmp = p; p = q; q = tmp; invert = true; } if (isComparison(p) && isZero(q)) { switch (expr.getOperation()) { case EQUALS: case NOT_EQUALS: case LESS: case LESS_OR_EQUALS: case GREATER: case GREATER_OR_EQUALS: { BinaryExpr comparison = (BinaryExpr) p; Expr result = BinaryExpr.binary( expr.getOperation(), comparison.getFirstOperand(), comparison.getSecondOperand()); result.setLocation(comparison.getLocation()); if (invert) { result = ExprOptimizer.invert(result); } resultExpr = result; return; } default: break; } } expr.setFirstOperand(a); expr.setSecondOperand(b); resultExpr = expr; }
@Override public void visit(ConditionalStatement statement) { statement.getCondition().acceptVisitor(this); statement.setCondition(resultExpr); List<Statement> consequent = processSequence(statement.getConsequent()); List<Statement> alternative = processSequence(statement.getAlternative()); if (consequent.isEmpty()) { consequent.addAll(alternative); alternative.clear(); statement.setCondition(ExprOptimizer.invert(statement.getCondition())); } if (consequent.isEmpty()) { resultStmt = Statement.empty(); return; } statement.getConsequent().clear(); statement.getConsequent().addAll(consequent); statement.getAlternative().clear(); statement.getAlternative().addAll(alternative); resultStmt = statement; }
private void eliminateRedundantBreaks(List<Statement> statements, IdentifiedStatement exit) { if (statements.isEmpty()) { return; } Statement last = statements.get(statements.size() - 1); if (last instanceof BreakStatement && exit != null) { IdentifiedStatement target = ((BreakStatement) last).getTarget(); if (exit == target) { statements.remove(statements.size() - 1); } } if (statements.isEmpty()) { return; } for (int i = 0; i < statements.size(); ++i) { Statement stmt = statements.get(i); if (stmt instanceof ConditionalStatement) { ConditionalStatement cond = (ConditionalStatement) stmt; check_conditional: { last = cond.getConsequent().isEmpty() ? null : cond.getConsequent().get(cond.getConsequent().size() - 1); if (last instanceof BreakStatement) { BreakStatement breakStmt = (BreakStatement) last; if (exit != null && exit == breakStmt.getTarget()) { cond.getConsequent().remove(cond.getConsequent().size() - 1); List<Statement> remaining = statements.subList(i + 1, statements.size()); cond.getAlternative().addAll(remaining); remaining.clear(); break check_conditional; } } last = cond.getAlternative().isEmpty() ? null : cond.getAlternative().get(cond.getAlternative().size() - 1); if (last instanceof BreakStatement) { BreakStatement breakStmt = (BreakStatement) last; if (exit != null && exit == breakStmt.getTarget()) { cond.getAlternative().remove(cond.getAlternative().size() - 1); List<Statement> remaining = statements.subList(i + 1, statements.size()); cond.getConsequent().addAll(remaining); remaining.clear(); } } } if (i == statements.size() - 1) { eliminateRedundantBreaks(cond.getConsequent(), exit); eliminateRedundantBreaks(cond.getAlternative(), exit); } normalizeConditional(cond); if (cond.getConsequent().size() == 1 && cond.getConsequent().get(0) instanceof ConditionalStatement) { ConditionalStatement innerCond = (ConditionalStatement) cond.getConsequent().get(0); if (innerCond.getAlternative().isEmpty()) { if (cond.getAlternative().isEmpty()) { cond.getConsequent().clear(); cond.getConsequent().addAll(innerCond.getConsequent()); cond.setCondition( Expr.binary( BinaryOperation.AND, cond.getCondition(), innerCond.getCondition(), cond.getCondition().getLocation())); --i; } else if (cond.getAlternative().size() != 1 || !(cond.getAlternative().get(0) instanceof ConditionalStatement)) { cond.setCondition(ExprOptimizer.invert(cond.getCondition())); cond.getConsequent().clear(); cond.getConsequent().addAll(cond.getAlternative()); cond.getAlternative().clear(); cond.getAlternative().add(innerCond); --i; } } } } else if (stmt instanceof BlockStatement) { BlockStatement nestedBlock = (BlockStatement) stmt; eliminateRedundantBreaks(nestedBlock.getBody(), nestedBlock); } else if (stmt instanceof WhileStatement) { WhileStatement whileStmt = (WhileStatement) stmt; eliminateRedundantBreaks(whileStmt.getBody(), null); } else if (stmt instanceof SwitchStatement) { SwitchStatement switchStmt = (SwitchStatement) stmt; for (SwitchClause clause : switchStmt.getClauses()) { eliminateRedundantBreaks(clause.getBody(), null); } eliminateRedundantBreaks(switchStmt.getDefaultClause(), null); } } }