Alexey Andreev 2015-05-14 17:38:07 +04:00
parent bf5af7ef6a
commit 07b65a92c7
3 changed files with 44 additions and 1 deletions

View File

@ -54,6 +54,11 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
} }
expr.getSecondOperand().acceptVisitor(this); expr.getSecondOperand().acceptVisitor(this);
Expr b = resultExpr; Expr b = resultExpr;
if (b instanceof ConstantExpr && expr.getOperation() == BinaryOperation.SUBTRACT) {
if (tryMakePositive((ConstantExpr)b)) {
expr.setOperation(BinaryOperation.ADD);
}
}
expr.getFirstOperand().acceptVisitor(this); expr.getFirstOperand().acceptVisitor(this);
Expr a = resultExpr; Expr a = resultExpr;
Expr p = a; Expr p = a;
@ -96,10 +101,41 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
public void visit(UnaryExpr expr) { public void visit(UnaryExpr expr) {
expr.getOperand().acceptVisitor(this); expr.getOperand().acceptVisitor(this);
Expr operand = resultExpr; Expr operand = resultExpr;
if (expr.getOperation() == UnaryOperation.NEGATE && operand instanceof ConstantExpr) {
ConstantExpr constantExpr = (ConstantExpr)operand;
if (tryMakePositive(constantExpr)) {
resultExpr = expr;
return;
}
}
expr.setOperand(operand); expr.setOperand(operand);
resultExpr = expr; resultExpr = expr;
} }
private boolean tryMakePositive(ConstantExpr constantExpr) {
Object value = constantExpr.getValue();
if (value instanceof Integer && (Integer)value < 0) {
constantExpr.setValue(-(Integer)value);
return true;
} else if (value instanceof Float && (Float)value < 0) {
constantExpr.setValue(-(Float)value);
return true;
} else if (value instanceof Byte && (Byte)value < 0) {
constantExpr.setValue(-(Byte)value);
return true;
} else if (value instanceof Short && (Short)value < 0) {
constantExpr.setValue(-(Short)value);
return true;
} else if (value instanceof Long && (Long)value < 0) {
constantExpr.setValue(-(Long)value);
return true;
} else if (value instanceof Double && (Double)value < 0) {
constantExpr.setValue(-(Double)value);
return true;
}
return false;
}
@Override @Override
public void visit(ConditionalExpr expr) { public void visit(ConditionalExpr expr) {
expr.getCondition().acceptVisitor(this); expr.getCondition().acceptVisitor(this);

View File

@ -1532,7 +1532,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
} }
String str = constantToString(expr.getValue()); String str = constantToString(expr.getValue());
if (str.startsWith("-")) { if (str.startsWith("-")) {
enterPriority(Priority.MULTIPLICATION, Associativity.RIGHT, true); enterPriority(Priority.MULTIPLICATION, Associativity.NONE, true);
} }
writer.append(str); writer.append(str);
if (str.startsWith("-")) { if (str.startsWith("-")) {

View File

@ -84,6 +84,13 @@ public class VMTest {
assertEquals(0xDDC2, "a\uDDC2b".charAt(1)); assertEquals(0xDDC2, "a\uDDC2b".charAt(1));
} }
@Test
public void subtractingNegativeWorks() {
int a = 23;
int b = a - 0xFFFFFFFF;
assertEquals(24, b);
}
@Test @Test
public void separatesExceptionAndVariable() { public void separatesExceptionAndVariable() {
int n = foo(); int n = foo();