diff --git a/Decompiler.csproj b/Decompiler.csproj index 9f529ee6c..b8c2a17eb 100644 --- a/Decompiler.csproj +++ b/Decompiler.csproj @@ -66,6 +66,7 @@ + diff --git a/bin/Debug/output.cs b/bin/Debug/output.cs index d7cf7d715..6994391ec 100644 --- a/bin/Debug/output.cs +++ b/bin/Debug/output.cs @@ -52,7 +52,7 @@ namespace Reversi (@this.squares).Set(row, col, color); for (int i = -1; i <= 1; i = (i + 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); for (int l = (col + j); ((@this.squares).Get(k, l)) == (-color); l = (l + j)) { (@this.squares).Set(k, l, color); @@ -67,7 +67,7 @@ namespace Reversi { for (int i = 0; i < 8; i = (i + 1)) { for (int j = 0; j < 8; j = (j + 1)) { - if (!(!(@this.IsValidMove(color, i, j)))) { + if ((@this.IsValidMove(color, i, j))) { return 1; } } @@ -76,12 +76,12 @@ namespace Reversi } 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; } for (int i = -1; i <= 1; i = (i + 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; } } @@ -93,7 +93,7 @@ namespace Reversi int i = 0; for (int j = 0; j < 8; j = (j + 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); } } @@ -103,10 +103,10 @@ namespace Reversi private bool IsOutflanking(int color, int row, int col, int dr, int dc) { 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); } - 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 1; @@ -124,7 +124,7 @@ namespace Reversi V_2 = 0; for (int i = 0; i < 8; i = (i + 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); V_2 = 1; } @@ -136,27 +136,27 @@ namespace Reversi j = 0; for (; j < 8; j = (j + 1)) { 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 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; } } } } - if (!(((@this.squares).Get(i, j)) != IL__ldsfld(Black))) { + if ((!(((@this.squares).Get(i, j)) != IL__ldsfld(Black)))) { IL__dup(@this); object expr123 = (expr122.blackCount); int expr129 = (expr123 + 1); expr122.blackCount = expr129; - if (!(!V_5)) { + if (V_5) { IL__dup(@this); object expr135 = (expr134.blackFrontierCount); int expr13B = (expr135 + 1); expr134.blackFrontierCount = expr13B; } - if (!(!((@this.safeDiscs).Get(i, j)))) { + if (((@this.safeDiscs).Get(i, j))) { IL__dup(@this); object expr152 = (expr151.blackSafeCount); int expr158 = (expr152 + 1); @@ -164,18 +164,18 @@ namespace Reversi } } else { - if (!(((@this.squares).Get(i, j)) != IL__ldsfld(White))) { + if ((!(((@this.squares).Get(i, j)) != IL__ldsfld(White)))) { IL__dup(@this); object expr176 = (expr175.whiteCount); int expr17C = (expr176 + 1); expr175.whiteCount = expr17C; - if (!(!V_5)) { + if (V_5) { IL__dup(@this); object expr188 = (expr187.whiteFrontierCount); int expr18E = (expr188 + 1); expr187.whiteFrontierCount = expr18E; } - if (!(!((@this.safeDiscs).Get(i, j)))) { + if (((@this.safeDiscs).Get(i, j))) { IL__dup(@this); object expr1A5 = (expr1A4.whiteSafeCount); int expr1AB = (expr1A5 + 1); @@ -201,56 +201,56 @@ namespace Reversi bool V_5 = 0; bool V_4 = 0; bool V_6 = 0; - for (int k = 0; !(k >= col) && (!V_3); k = (k + 1)) { - if (!(((@this.squares).Get(row, k)) != IL__ldsfld(Empty))) { + for (int k = 0; (k < col) && (!V_3); k = (k + 1)) { + if ((!(((@this.squares).Get(row, k)) != IL__ldsfld(Empty)))) { V_3 = 1; } 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; } } } k = (col + 1); - for (; !(k >= 8) && (!V_4); k = (k + 1)) { - if (!(((@this.squares).Get(row, k)) != IL__ldsfld(Empty))) { + for (; (k < 8) && (!V_4); k = (k + 1)) { + if ((!(((@this.squares).Get(row, k)) != IL__ldsfld(Empty)))) { V_4 = 1; } 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; } } } - 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; } V_3 = 0; V_4 = 0; V_5 = 0; V_6 = 0; - for (int j = 0; !(j >= row) && (!V_3); j = (j + 1)) { - if (!(((@this.squares).Get(j, col)) != IL__ldsfld(Empty))) { + for (int j = 0; (j < row) && (!V_3); j = (j + 1)) { + if ((!(((@this.squares).Get(j, col)) != IL__ldsfld(Empty)))) { V_3 = 1; } 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; } } } j = (row + 1); - for (; !(j >= 8) && (!V_4); j = (j + 1)) { - if (!(((@this.squares).Get(j, col)) != IL__ldsfld(Empty))) { + for (; (j < 8) && (!V_4); j = (j + 1)) { + if ((!(((@this.squares).Get(j, col)) != IL__ldsfld(Empty)))) { V_4 = 1; } 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; } } } - 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; } V_3 = 0; @@ -259,12 +259,12 @@ namespace Reversi V_6 = 0; j = (row - 1); k = (col - 1); - for (; !((j < 0) || (k < 0)) && (!V_3); k = (k - 1)) { - if (!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty))) { + for (; ((j >= 0) && (k >= 0)) && (!V_3); k = (k - 1)) { + if ((!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty)))) { V_3 = 1; } 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; } } @@ -272,18 +272,18 @@ namespace Reversi } j = (row + 1); k = (col + 1); - for (; !((j >= 8) || (k >= 8)) && (!V_4); k = (k + 1)) { - if (!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty))) { + for (; ((j < 8) && (k < 8)) && (!V_4); k = (k + 1)) { + if ((!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty)))) { V_4 = 1; } 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; } } 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; } V_3 = 0; @@ -292,12 +292,12 @@ namespace Reversi V_6 = 0; j = (row - 1); k = (col + 1); - for (; !((j < 0) || (k >= 8)) && (!V_3); k = (k + 1)) { - if (!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty))) { + for (; ((j >= 0) && (k < 8)) && (!V_3); k = (k + 1)) { + if ((!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty)))) { V_3 = 1; } 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; } } @@ -305,18 +305,18 @@ namespace Reversi } j = (row + 1); k = (col - 1); - for (; !((j >= 8) || (k < 0)) && (!V_4); k = (k - 1)) { - if (!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty))) { + for (; ((j < 8) && (k >= 0)) && (!V_4); k = (k - 1)) { + if ((!(((@this.squares).Get(j, k)) != IL__ldsfld(Empty)))) { V_4 = 1; } 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; } } 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 0; diff --git a/src/AstBuilder.cs b/src/AstBuilder.cs index 5b5a863ca..f01ff36ff 100644 --- a/src/AstBuilder.cs +++ b/src/AstBuilder.cs @@ -34,6 +34,7 @@ namespace Decompiler astCompileUnit.AcceptVisitor(new Transforms.Ast.SimplifyTypeReferences(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.Idioms(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveEmptyElseBody(), null); + astCompileUnit.AcceptVisitor(new Transforms.Ast.PushNegation(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveParenthesis(), null); } } diff --git a/src/Transforms/Ast/PushNegation.cs b/src/Transforms/Ast/PushNegation.cs new file mode 100644 index 000000000..f63eb81f1 --- /dev/null +++ b/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); + } + } +} diff --git a/src/Transforms/Ast/RestoreLoop.cs b/src/Transforms/Ast/RestoreLoop.cs index b4aa400a8..5c1a7ca23 100644 --- a/src/Transforms/Ast/RestoreLoop.cs +++ b/src/Transforms/Ast/RestoreLoop.cs @@ -44,19 +44,16 @@ namespace Decompiler.Transforms.Ast if (forStatement.Condition.IsNull) { IfElseStatement condition = forStatement.EmbeddedStatement.Children.First as IfElseStatement; if (condition != null && + condition.TrueStatement.Count == 1 && condition.TrueStatement[0] is BlockStatement && condition.TrueStatement[0].Children.Count == 1 && condition.TrueStatement[0].Children.First is BreakStatement && + condition.FalseStatement.Count == 1 && condition.FalseStatement[0] is BlockStatement && condition.FalseStatement[0].Children.Count == 0) { - UnaryOperatorExpression negExpr = condition.Condition as UnaryOperatorExpression; - if (negExpr != null && - negExpr.Op == UnaryOperatorType.Not) { - - condition.Remove(); - forStatement.Condition = negExpr.Expression; - } + condition.Remove(); + forStatement.Condition = new UnaryOperatorExpression(condition.Condition, UnaryOperatorType.Not); } }