Browse Source

Simplify expressions by pushing negations inside.

Includes application of De Morgan's laws.
pull/1/head^2
David Srbecký 18 years ago
parent
commit
f1c1d34cba
  1. 1
      Decompiler.csproj
  2. 88
      bin/Debug/output.cs
  3. 1
      src/AstBuilder.cs
  4. 77
      src/Transforms/Ast/PushNegation.cs
  5. 9
      src/Transforms/Ast/RestoreLoop.cs

1
Decompiler.csproj

@ -66,6 +66,7 @@
<Compile Include="src\ByteCode.StackAnalysis.cs" /> <Compile Include="src\ByteCode.StackAnalysis.cs" />
<Compile Include="src\StackExpression.cs" /> <Compile Include="src\StackExpression.cs" />
<Compile Include="src\StackExpressionCollection.cs" /> <Compile Include="src\StackExpressionCollection.cs" />
<Compile Include="src\Transforms\Ast\PushNegation.cs" />
<Compile Include="src\Transforms\Ast\Idioms.cs" /> <Compile Include="src\Transforms\Ast\Idioms.cs" />
<Compile Include="src\Transforms\Ast\RemoveDeadLabels.cs" /> <Compile Include="src\Transforms\Ast\RemoveDeadLabels.cs" />
<Compile Include="src\Transforms\Ast\RemoveEmptyElseBody.cs" /> <Compile Include="src\Transforms\Ast\RemoveEmptyElseBody.cs" />

88
bin/Debug/output.cs

@ -52,7 +52,7 @@ namespace Reversi
(@this.squares).Set(row, col, color); (@this.squares).Set(row, col, color);
for (int i = -1; i <= 1; i = (i + 1)) { for (int i = -1; i <= 1; i = (i + 1)) {
for (int j = -1; j <= 1; j = (j + 1)) { for (int j = -1; j <= 1; j = (j + 1)) {
if (!((!i && (!j)) || (!(@this.IsOutflanking(color, row, col, i, j))))) { if (((i || j) && (@this.IsOutflanking(color, row, col, i, j)))) {
int k = (row + i); int k = (row + i);
for (int l = (col + j); ((@this.squares).Get(k, l)) == (-color); l = (l + j)) { for (int l = (col + j); ((@this.squares).Get(k, l)) == (-color); l = (l + j)) {
(@this.squares).Set(k, l, color); (@this.squares).Set(k, l, color);
@ -67,7 +67,7 @@ namespace Reversi
{ {
for (int i = 0; i < 8; i = (i + 1)) { for (int i = 0; i < 8; i = (i + 1)) {
for (int j = 0; j < 8; j = (j + 1)) { for (int j = 0; j < 8; j = (j + 1)) {
if (!(!(@this.IsValidMove(color, i, j)))) { if ((@this.IsValidMove(color, i, j))) {
return 1; return 1;
} }
} }
@ -76,12 +76,12 @@ namespace Reversi
} }
public bool IsValidMove(int color, int row, int col) public bool IsValidMove(int color, int row, int col)
{ {
if (!(((@this.squares).Get(row, col)) == IL__ldsfld(Empty))) { if ((!(((@this.squares).Get(row, col)) == IL__ldsfld(Empty)))) {
return 0; return 0;
} }
for (int i = -1; i <= 1; i = (i + 1)) { for (int i = -1; i <= 1; i = (i + 1)) {
for (int j = -1; j <= 1; j = (j + 1)) { for (int j = -1; j <= 1; j = (j + 1)) {
if (!((!i && (!j)) || (!(@this.IsOutflanking(color, row, col, i, j))))) { if (((i || j) && (@this.IsOutflanking(color, row, col, i, j)))) {
return 1; return 1;
} }
} }
@ -93,7 +93,7 @@ namespace Reversi
int i = 0; int i = 0;
for (int j = 0; j < 8; j = (j + 1)) { for (int j = 0; j < 8; j = (j + 1)) {
for (int k = 0; k < 8; k = (k + 1)) { for (int k = 0; k < 8; k = (k + 1)) {
if (!(!(@this.IsValidMove(color, j, k)))) { if ((@this.IsValidMove(color, j, k))) {
i = (i + 1); i = (i + 1);
} }
} }
@ -103,10 +103,10 @@ namespace Reversi
private bool IsOutflanking(int color, int row, int col, int dr, int dc) private bool IsOutflanking(int color, int row, int col, int dr, int dc)
{ {
int i = (row + dr); int i = (row + dr);
for (int j = (col + dc); !((((i < 0) || (i >= 8)) || (j < 0)) || (j >= 8)) && (((@this.squares).Get(i, j)) == (-color)); j = (j + dc)) { for (int j = (col + dc); ((((i >= 0) && (i < 8)) && (j >= 0)) && (j < 8)) && (((@this.squares).Get(i, j)) == (-color)); j = (j + dc)) {
i = (i + dr); i = (i + dr);
} }
if (!(!(((((i < 0) || (i > 7)) || (j < 0)) || (j > 7)) || (!((i - dr) != row) && ((j - dc) == col))) && (((@this.squares).Get(i, j)) == color))) { if ((((((!(i >= 0) || !(i <= 7)) || !(j >= 0)) || !(j <= 7)) || !(!((i - dr) == row) || !((j - dc) == col))) || !(((@this.squares).Get(i, j)) == color))) {
return 0; return 0;
} }
return 1; return 1;
@ -124,7 +124,7 @@ namespace Reversi
V_2 = 0; V_2 = 0;
for (int i = 0; i < 8; i = (i + 1)) { for (int i = 0; i < 8; i = (i + 1)) {
for (int j = 0; j < 8; j = (j + 1)) { for (int j = 0; j < 8; j = (j + 1)) {
if (!(((((@this.squares).Get(i, j)) == IL__ldsfld(Empty)) || ((@this.safeDiscs).Get(i, j))) || (@this.IsOutflankable(i, j)))) { if (((!(((@this.squares).Get(i, j)) == IL__ldsfld(Empty)) && (!((@this.safeDiscs).Get(i, j)))) && (!(@this.IsOutflankable(i, j))))) {
(@this.safeDiscs).Set(i, j, 1); (@this.safeDiscs).Set(i, j, 1);
V_2 = 1; V_2 = 1;
} }
@ -136,27 +136,27 @@ namespace Reversi
j = 0; j = 0;
for (; j < 8; j = (j + 1)) { for (; j < 8; j = (j + 1)) {
bool V_5 = 0; bool V_5 = 0;
if (!(((@this.squares).Get(i, j)) == IL__ldsfld(Empty))) { if ((!(((@this.squares).Get(i, j)) == IL__ldsfld(Empty)))) {
for (int k = -1; k <= 1; k = (k + 1)) { for (int k = -1; k <= 1; k = (k + 1)) {
for (int l = -1; l <= 1; l = (l + 1)) { for (int l = -1; l <= 1; l = (l + 1)) {
if (!((((((!k && (!l)) || ((i + k) < 0)) || ((i + k) >= 8)) || ((j + l) < 0)) || ((j + l) >= 8)) || (((@this.squares).Get((i + k), (j + l))) != IL__ldsfld(Empty)))) { if (((((((k || l) && ((i + k) >= 0)) && ((i + k) < 8)) && ((j + l) >= 0)) && ((j + l) < 8)) && !(((@this.squares).Get((i + k), (j + l))) != IL__ldsfld(Empty)))) {
V_5 = 1; V_5 = 1;
} }
} }
} }
} }
if (!(((@this.squares).Get(i, j)) != IL__ldsfld(Black))) { if ((!(((@this.squares).Get(i, j)) != IL__ldsfld(Black)))) {
IL__dup(@this); IL__dup(@this);
object expr123 = (expr122.blackCount); object expr123 = (expr122.blackCount);
int expr129 = (expr123 + 1); int expr129 = (expr123 + 1);
expr122.blackCount = expr129; expr122.blackCount = expr129;
if (!(!V_5)) { if (V_5) {
IL__dup(@this); IL__dup(@this);
object expr135 = (expr134.blackFrontierCount); object expr135 = (expr134.blackFrontierCount);
int expr13B = (expr135 + 1); int expr13B = (expr135 + 1);
expr134.blackFrontierCount = expr13B; expr134.blackFrontierCount = expr13B;
} }
if (!(!((@this.safeDiscs).Get(i, j)))) { if (((@this.safeDiscs).Get(i, j))) {
IL__dup(@this); IL__dup(@this);
object expr152 = (expr151.blackSafeCount); object expr152 = (expr151.blackSafeCount);
int expr158 = (expr152 + 1); int expr158 = (expr152 + 1);
@ -164,18 +164,18 @@ namespace Reversi
} }
} }
else { else {
if (!(((@this.squares).Get(i, j)) != IL__ldsfld(White))) { if ((!(((@this.squares).Get(i, j)) != IL__ldsfld(White)))) {
IL__dup(@this); IL__dup(@this);
object expr176 = (expr175.whiteCount); object expr176 = (expr175.whiteCount);
int expr17C = (expr176 + 1); int expr17C = (expr176 + 1);
expr175.whiteCount = expr17C; expr175.whiteCount = expr17C;
if (!(!V_5)) { if (V_5) {
IL__dup(@this); IL__dup(@this);
object expr188 = (expr187.whiteFrontierCount); object expr188 = (expr187.whiteFrontierCount);
int expr18E = (expr188 + 1); int expr18E = (expr188 + 1);
expr187.whiteFrontierCount = expr18E; expr187.whiteFrontierCount = expr18E;
} }
if (!(!((@this.safeDiscs).Get(i, j)))) { if (((@this.safeDiscs).Get(i, j))) {
IL__dup(@this); IL__dup(@this);
object expr1A5 = (expr1A4.whiteSafeCount); object expr1A5 = (expr1A4.whiteSafeCount);
int expr1AB = (expr1A5 + 1); int expr1AB = (expr1A5 + 1);
@ -201,56 +201,56 @@ namespace Reversi
bool V_5 = 0; bool V_5 = 0;
bool V_4 = 0; bool V_4 = 0;
bool V_6 = 0; bool V_6 = 0;
for (int k = 0; !(k >= col) && (!V_3); k = (k + 1)) { for (int k = 0; (k < col) && (!V_3); k = (k + 1)) {
if (!(((@this.squares).Get(row, k)) != IL__ldsfld(Empty))) { if ((!(((@this.squares).Get(row, k)) != IL__ldsfld(Empty)))) {
V_3 = 1; V_3 = 1;
} }
else { else {
if (!(!(((@this.squares).Get(row, k)) != i) && ((@this.safeDiscs).Get(row, k)))) { if ((!(((@this.squares).Get(row, k)) == i) || !((@this.safeDiscs).Get(row, k)))) {
V_5 = 1; V_5 = 1;
} }
} }
} }
k = (col + 1); k = (col + 1);
for (; !(k >= 8) && (!V_4); k = (k + 1)) { for (; (k < 8) && (!V_4); k = (k + 1)) {
if (!(((@this.squares).Get(row, k)) != IL__ldsfld(Empty))) { if ((!(((@this.squares).Get(row, k)) != IL__ldsfld(Empty)))) {
V_4 = 1; V_4 = 1;
} }
else { else {
if (!(!(((@this.squares).Get(row, k)) != i) && ((@this.safeDiscs).Get(row, k)))) { if ((!(((@this.squares).Get(row, k)) == i) || !((@this.safeDiscs).Get(row, k)))) {
V_6 = 1; V_6 = 1;
} }
} }
} }
if (!(!((!(!V_3) && V_4) || (!(!V_3) && V_6)) && ((!V_5) || (!V_4)))) { if (((!(!V_3 || !V_4) || !(!V_3 || !V_6)) || (V_5 && V_4))) {
return 1; return 1;
} }
V_3 = 0; V_3 = 0;
V_4 = 0; V_4 = 0;
V_5 = 0; V_5 = 0;
V_6 = 0; V_6 = 0;
for (int j = 0; !(j >= row) && (!V_3); j = (j + 1)) { for (int j = 0; (j < row) && (!V_3); j = (j + 1)) {
if (!(((@this.squares).Get(j, col)) != IL__ldsfld(Empty))) { if ((!(((@this.squares).Get(j, col)) != IL__ldsfld(Empty)))) {
V_3 = 1; V_3 = 1;
} }
else { else {
if (!(!(((@this.squares).Get(j, col)) != i) && ((@this.safeDiscs).Get(j, col)))) { if ((!(((@this.squares).Get(j, col)) == i) || !((@this.safeDiscs).Get(j, col)))) {
V_5 = 1; V_5 = 1;
} }
} }
} }
j = (row + 1); j = (row + 1);
for (; !(j >= 8) && (!V_4); j = (j + 1)) { for (; (j < 8) && (!V_4); j = (j + 1)) {
if (!(((@this.squares).Get(j, col)) != IL__ldsfld(Empty))) { if ((!(((@this.squares).Get(j, col)) != IL__ldsfld(Empty)))) {
V_4 = 1; V_4 = 1;
} }
else { else {
if (!(!(((@this.squares).Get(j, col)) != i) && ((@this.safeDiscs).Get(j, col)))) { if ((!(((@this.squares).Get(j, col)) == i) || !((@this.safeDiscs).Get(j, col)))) {
V_6 = 1; V_6 = 1;
} }
} }
} }
if (!(!((!(!V_3) && V_4) || (!(!V_3) && V_6)) && ((!V_5) || (!V_4)))) { if (((!(!V_3 || !V_4) || !(!V_3 || !V_6)) || (V_5 && V_4))) {
return 1; return 1;
} }
V_3 = 0; V_3 = 0;
@ -259,12 +259,12 @@ namespace Reversi
V_6 = 0; V_6 = 0;
j = (row - 1); j = (row - 1);
k = (col - 1); k = (col - 1);
for (; !((j < 0) || (k < 0)) && (!V_3); k = (k - 1)) { for (; ((j >= 0) && (k >= 0)) && (!V_3); k = (k - 1)) {
if (!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty))) { if ((!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty)))) {
V_3 = 1; V_3 = 1;
} }
else { else {
if (!(!(((@this.squares).Get(j, k)) != i) && ((@this.safeDiscs).Get(j, k)))) { if ((!(((@this.squares).Get(j, k)) == i) || !((@this.safeDiscs).Get(j, k)))) {
V_5 = 1; V_5 = 1;
} }
} }
@ -272,18 +272,18 @@ namespace Reversi
} }
j = (row + 1); j = (row + 1);
k = (col + 1); k = (col + 1);
for (; !((j >= 8) || (k >= 8)) && (!V_4); k = (k + 1)) { for (; ((j < 8) && (k < 8)) && (!V_4); k = (k + 1)) {
if (!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty))) { if ((!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty)))) {
V_4 = 1; V_4 = 1;
} }
else { else {
if (!(!(((@this.squares).Get(j, k)) != i) && ((@this.safeDiscs).Get(j, k)))) { if ((!(((@this.squares).Get(j, k)) == i) || !((@this.safeDiscs).Get(j, k)))) {
V_6 = 1; V_6 = 1;
} }
} }
j = (j + 1); j = (j + 1);
} }
if (!(!((!(!V_3) && V_4) || (!(!V_3) && V_6)) && ((!V_5) || (!V_4)))) { if (((!(!V_3 || !V_4) || !(!V_3 || !V_6)) || (V_5 && V_4))) {
return 1; return 1;
} }
V_3 = 0; V_3 = 0;
@ -292,12 +292,12 @@ namespace Reversi
V_6 = 0; V_6 = 0;
j = (row - 1); j = (row - 1);
k = (col + 1); k = (col + 1);
for (; !((j < 0) || (k >= 8)) && (!V_3); k = (k + 1)) { for (; ((j >= 0) && (k < 8)) && (!V_3); k = (k + 1)) {
if (!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty))) { if ((!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty)))) {
V_3 = 1; V_3 = 1;
} }
else { else {
if (!(!(((@this.squares).Get(j, k)) != i) && ((@this.safeDiscs).Get(j, k)))) { if ((!(((@this.squares).Get(j, k)) == i) || !((@this.safeDiscs).Get(j, k)))) {
V_5 = 1; V_5 = 1;
} }
} }
@ -305,18 +305,18 @@ namespace Reversi
} }
j = (row + 1); j = (row + 1);
k = (col - 1); k = (col - 1);
for (; !((j >= 8) || (k < 0)) && (!V_4); k = (k - 1)) { for (; ((j < 8) && (k >= 0)) && (!V_4); k = (k - 1)) {
if (!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty))) { if ((!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty)))) {
V_4 = 1; V_4 = 1;
} }
else { else {
if (!(!(((@this.squares).Get(j, k)) != i) && ((@this.safeDiscs).Get(j, k)))) { if ((!(((@this.squares).Get(j, k)) == i) || !((@this.safeDiscs).Get(j, k)))) {
V_6 = 1; V_6 = 1;
} }
} }
j = (j + 1); j = (j + 1);
} }
if (!(!((!(!V_3) && V_4) || (!(!V_3) && V_6)) && ((!V_5) || (!V_4)))) { if (((!(!V_3 || !V_4) || !(!V_3 || !V_6)) || (V_5 && V_4))) {
return 1; return 1;
} }
return 0; return 0;

1
src/AstBuilder.cs

@ -34,6 +34,7 @@ namespace Decompiler
astCompileUnit.AcceptVisitor(new Transforms.Ast.SimplifyTypeReferences(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.SimplifyTypeReferences(), null);
astCompileUnit.AcceptVisitor(new Transforms.Ast.Idioms(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.Idioms(), null);
astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveEmptyElseBody(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveEmptyElseBody(), null);
astCompileUnit.AcceptVisitor(new Transforms.Ast.PushNegation(), null);
astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveParenthesis(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveParenthesis(), null);
} }
} }

77
src/Transforms/Ast/PushNegation.cs

@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Visitors;
namespace Decompiler.Transforms.Ast
{
public class PushNegation: AbstractAstTransformer
{
public override object VisitUnaryOperatorExpression(UnaryOperatorExpression unary, object data)
{
// Basic assumtion is that we have something in form !(a)
if (unary.Op == UnaryOperatorType.Not &&
unary.Expression is ParenthesizedExpression) {
ParenthesizedExpression parenth = ((ParenthesizedExpression)unary.Expression);
// Push through two parenthesis
// !((a))
if (parenth.Expression is ParenthesizedExpression) {
parenth.Expression = new UnaryOperatorExpression(parenth.Expression, UnaryOperatorType.Not);
ReplaceCurrentNode(parenth);
return parenth.AcceptVisitor(this, data);
}
// Remove double negation
// !(!a)
if (parenth.Expression is UnaryOperatorExpression &&
(parenth.Expression as UnaryOperatorExpression).Op == UnaryOperatorType.Not) {
parenth.Expression = (parenth.Expression as UnaryOperatorExpression).Expression;
ReplaceCurrentNode(parenth);
return parenth.AcceptVisitor(this, data);
}
// Push through binary operation
// !((a) op (b))
BinaryOperatorExpression binaryOp = parenth.Expression as BinaryOperatorExpression;
if (binaryOp != null &&
binaryOp.Left is ParenthesizedExpression &&
binaryOp.Right is ParenthesizedExpression) {
bool sucessful = true;
switch(binaryOp.Op) {
case BinaryOperatorType.Equality: binaryOp.Op = BinaryOperatorType.InEquality; break;
case BinaryOperatorType.InEquality: binaryOp.Op = BinaryOperatorType.Equality; break;
case BinaryOperatorType.GreaterThan: binaryOp.Op = BinaryOperatorType.LessThanOrEqual; break;
case BinaryOperatorType.GreaterThanOrEqual: binaryOp.Op = BinaryOperatorType.LessThan; break;
case BinaryOperatorType.LessThanOrEqual: binaryOp.Op = BinaryOperatorType.GreaterThan; break;
case BinaryOperatorType.LessThan: binaryOp.Op = BinaryOperatorType.GreaterThanOrEqual; break;
default: sucessful = false; break;
}
if (sucessful) {
ReplaceCurrentNode(parenth);
return parenth.AcceptVisitor(this, data);
}
sucessful = true;
switch(binaryOp.Op) {
case BinaryOperatorType.BitwiseAnd: binaryOp.Op = BinaryOperatorType.BitwiseOr; break;
case BinaryOperatorType.BitwiseOr: binaryOp.Op = BinaryOperatorType.BitwiseAnd; break;
case BinaryOperatorType.LogicalAnd: binaryOp.Op = BinaryOperatorType.LogicalOr; break;
case BinaryOperatorType.LogicalOr: binaryOp.Op = BinaryOperatorType.LogicalAnd; break;
default: sucessful = false; break;
}
if (sucessful) {
binaryOp.Left = new UnaryOperatorExpression(binaryOp.Left, UnaryOperatorType.Not);
binaryOp.Right = new UnaryOperatorExpression(binaryOp.Right, UnaryOperatorType.Not);
ReplaceCurrentNode(parenth);
return parenth.AcceptVisitor(this, data);
}
}
}
return base.VisitUnaryOperatorExpression(unary, data);
}
}
}

9
src/Transforms/Ast/RestoreLoop.cs

@ -44,19 +44,16 @@ namespace Decompiler.Transforms.Ast
if (forStatement.Condition.IsNull) { if (forStatement.Condition.IsNull) {
IfElseStatement condition = forStatement.EmbeddedStatement.Children.First as IfElseStatement; IfElseStatement condition = forStatement.EmbeddedStatement.Children.First as IfElseStatement;
if (condition != null && if (condition != null &&
condition.TrueStatement.Count == 1 &&
condition.TrueStatement[0] is BlockStatement && condition.TrueStatement[0] is BlockStatement &&
condition.TrueStatement[0].Children.Count == 1 && condition.TrueStatement[0].Children.Count == 1 &&
condition.TrueStatement[0].Children.First is BreakStatement && condition.TrueStatement[0].Children.First is BreakStatement &&
condition.FalseStatement.Count == 1 &&
condition.FalseStatement[0] is BlockStatement && condition.FalseStatement[0] is BlockStatement &&
condition.FalseStatement[0].Children.Count == 0) condition.FalseStatement[0].Children.Count == 0)
{ {
UnaryOperatorExpression negExpr = condition.Condition as UnaryOperatorExpression;
if (negExpr != null &&
negExpr.Op == UnaryOperatorType.Not) {
condition.Remove(); condition.Remove();
forStatement.Condition = negExpr.Expression; forStatement.Condition = new UnaryOperatorExpression(condition.Condition, UnaryOperatorType.Not);
}
} }
} }

Loading…
Cancel
Save