Improve AddSubTransformer

This commit improves support for simplifying a series of multiple
additions/subtractions and doing so in a single pass.

Signed-off-by: Graham <gpe@openrs2.dev>
pull/132/head
Graham 4 years ago
parent d33c03c708
commit 504e832872
  1. 77
      deob-ast/src/main/java/dev/openrs2/deob/ast/transform/AddSubTransformer.kt

@ -19,32 +19,71 @@ class AddSubTransformer : Transformer() {
override fun transformUnit(group: LibraryGroup, library: Library, unit: CompilationUnit) { override fun transformUnit(group: LibraryGroup, library: Library, unit: CompilationUnit) {
unit.walk { expr: BinaryExpr -> unit.walk { expr: BinaryExpr ->
val op = expr.operator val op = expr.operator
val left = expr.left if (op != BinaryExpr.Operator.PLUS && op != BinaryExpr.Operator.MINUS) {
val right = expr.right return@walk
val type = expr.calculateResolvedType() }
if (op == BinaryExpr.Operator.PLUS && type.isString()) { val type = expr.calculateResolvedType()
if (type.isString()) {
return@walk return@walk
} }
if (op == BinaryExpr.Operator.PLUS && right.isNegative()) { val terms = mutableListOf<Expression>()
// x + -y => x - y addTerms(terms, expr, negate = false)
expr.operator = BinaryExpr.Operator.MINUS
expr.right = right.negate() terms.sortWith(Comparator { a, b ->
} else if (op == BinaryExpr.Operator.PLUS && left.isNegative()) { // preserve the order of adjacent expressions with side effects
if (expr.hasSideEffects()) { val aHasSideEffects = a.hasSideEffects()
return@walk val bHasSideEffects = b.hasSideEffects()
if (aHasSideEffects && bHasSideEffects) {
return@Comparator 0
} }
// -x + y => y - x // push negative expressions to the right so we can replace unary minus with binary minus
expr.operator = BinaryExpr.Operator.MINUS val aNegative = a.isNegative()
expr.left = right.clone() val bNegative = b.isNegative()
expr.right = left.negate() if (aNegative && !bNegative) {
} else if (op == BinaryExpr.Operator.MINUS && right.isNegative()) { return@Comparator 1
// x - -y => x + y } else if (!aNegative && bNegative) {
expr.operator = BinaryExpr.Operator.PLUS return@Comparator -1
expr.right = right.negate() }
return@Comparator 0
})
val newExpr = terms.reduce { left, right ->
if (right.isNegative()) {
BinaryExpr(left.clone(), right.negate(), BinaryExpr.Operator.MINUS)
} else {
BinaryExpr(left.clone(), right.clone(), BinaryExpr.Operator.PLUS)
}
}
expr.replace(newExpr)
}
}
private fun addTerms(terms: MutableList<Expression>, expr: Expression, negate: Boolean) {
when {
expr is UnaryExpr -> when {
expr.operator == UnaryExpr.Operator.MINUS -> addTerms(terms, expr.expression, !negate)
negate -> terms += expr.negate()
else -> terms += expr
}
expr is BinaryExpr -> when {
expr.operator == BinaryExpr.Operator.PLUS -> {
addTerms(terms, expr.left, negate)
addTerms(terms, expr.right, negate)
}
expr.operator == BinaryExpr.Operator.MINUS -> {
addTerms(terms, expr.left, negate)
addTerms(terms, expr.right, !negate)
}
negate -> terms += expr.negate()
else -> terms += expr
} }
negate -> terms += expr.negate()
else -> terms += expr
} }
} }

Loading…
Cancel
Save