Browse Source

Track the type of expression.

Zero and One are tracked as special types so that they can be substituted with 'true' or 'false'.
pull/1/head^2
David Srbecký 18 years ago
parent
commit
a87a9468e7
  1. 112
      bin/Debug/output.cs
  2. 3
      lib/NRefactory/Project/Src/Ast/AbstractNode.cs
  3. 2
      lib/NRefactory/Project/Src/Ast/INode.cs
  4. 2
      lib/NRefactory/Project/Src/SnippetParser.cs
  5. 37
      src/AstMetodBodyBuilder.cs
  6. 15
      src/ByteCode.Type.cs

112
bin/Debug/output.cs

@ -80,26 +80,26 @@ namespace Reversi
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) { for (int j = 0; j < 8; j++) {
if (IsValidMove(color, i, j)) { if (IsValidMove(color, i, j)) {
return 1; return true;
} }
} }
} }
return 0; return false;
} }
public bool IsValidMove(int color, int row, int col) public bool IsValidMove(int color, int row, int col)
{ {
if (squares[row, col] != Empty) { if (squares[row, col] != Empty) {
return 0; return false;
} }
for (int i = -1; i <= 1; i++) { for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) { for (int j = -1; j <= 1; j++) {
if ((i || j) && IsOutflanking(color, row, col, i, j)) { if ((i || j) && IsOutflanking(color, row, col, i, j)) {
return 1; return true;
} }
} }
} }
return 0; return false;
} }
public int GetValidMoveCount(int color) public int GetValidMoveCount(int color)
@ -122,9 +122,9 @@ namespace Reversi
i += dr; i += dr;
} }
if (i < 0 || i > 7 || j < 0 || j > 7 || i - dr == row && j - dc == col || squares[i, j] != color) { if (i < 0 || i > 7 || j < 0 || j > 7 || i - dr == row && j - dc == col || squares[i, j] != color) {
return 0; return false;
} }
return 1; return true;
} }
private void UpdateCounts() private void UpdateCounts()
@ -136,13 +136,13 @@ namespace Reversi
whiteFrontierCount = 0; whiteFrontierCount = 0;
whiteSafeCount = 0; whiteSafeCount = 0;
blackSafeCount = 0; blackSafeCount = 0;
for (bool V_2 = 1; V_2;) { for (bool V_2 = true; V_2;) {
V_2 = 0; V_2 = false;
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) { for (int j = 0; j < 8; j++) {
if (squares[i, j] != Empty && !safeDiscs[i, j] && !IsOutflankable(i, j)) { if (squares[i, j] != Empty && !safeDiscs[i, j] && !IsOutflankable(i, j)) {
safeDiscs[i, j] = 1; safeDiscs[i, j] = 1;
V_2 = 1; V_2 = true;
} }
} }
} }
@ -151,48 +151,48 @@ namespace Reversi
for (; i < 8; i++) { for (; i < 8; i++) {
j = 0; j = 0;
for (; j < 8; j++) { for (; j < 8; j++) {
bool V_5 = 0; bool V_5 = false;
if (squares[i, j] != Empty) { if (squares[i, j] != Empty) {
for (int k = -1; k <= 1; k++) { for (int k = -1; k <= 1; k++) {
for (int l = -1; l <= 1; l++) { for (int l = -1; l <= 1; l++) {
if ((k || l) && i + k >= 0 && i + k < 8 && j + l >= 0 && j + l < 8 && squares[(i + k), (j + l)] == Empty) { if ((k || l) && i + k >= 0 && i + k < 8 && j + l >= 0 && j + l < 8 && squares[(i + k), (j + l)] == Empty) {
V_5 = 1; V_5 = true;
} }
} }
} }
} }
if (squares[i, j] == Black) { if (squares[i, j] == Black) {
IL__dup(this); IL__dup(this);
object expr123 = expr122.blackCount; int 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; int expr135 = expr134.blackFrontierCount;
int expr13B = expr135 + 1; int expr13B = expr135 + 1;
expr134.blackFrontierCount = expr13B; expr134.blackFrontierCount = expr13B;
} }
if (safeDiscs[i, j]) { if (safeDiscs[i, j]) {
IL__dup(this); IL__dup(this);
object expr152 = expr151.blackSafeCount; int expr152 = expr151.blackSafeCount;
int expr158 = expr152 + 1; int expr158 = expr152 + 1;
expr151.blackSafeCount = expr158; expr151.blackSafeCount = expr158;
} }
} else { } else {
if (squares[i, j] == White) { if (squares[i, j] == White) {
IL__dup(this); IL__dup(this);
object expr176 = expr175.whiteCount; int 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; int expr188 = expr187.whiteFrontierCount;
int expr18E = expr188 + 1; int expr18E = expr188 + 1;
expr187.whiteFrontierCount = expr18E; expr187.whiteFrontierCount = expr18E;
} }
if (safeDiscs[i, j]) { if (safeDiscs[i, j]) {
IL__dup(this); IL__dup(this);
object expr1A5 = expr1A4.whiteSafeCount; int expr1A5 = expr1A4.whiteSafeCount;
int expr1AB = expr1A5 + 1; int expr1AB = expr1A5 + 1;
expr1A4.whiteSafeCount = expr1AB; expr1A4.whiteSafeCount = expr1AB;
goto BasicBlock_327; goto BasicBlock_327;
@ -201,7 +201,7 @@ namespace Reversi
} }
} }
IL__dup(this); IL__dup(this);
object expr1B5 = expr1B4.emptyCount; int expr1B5 = expr1B4.emptyCount;
int expr1BB = expr1B5 + 1; int expr1BB = expr1B5 + 1;
expr1B4.emptyCount = expr1BB; expr1B4.emptyCount = expr1BB;
} }
@ -213,70 +213,70 @@ namespace Reversi
private bool IsOutflankable(int row, int col) private bool IsOutflankable(int row, int col)
{ {
int i = squares[row, col]; int i = squares[row, col];
bool V_3 = 0; bool V_3 = false;
bool V_5 = 0; bool V_5 = false;
bool V_4 = 0; bool V_4 = false;
bool V_6 = 0; bool V_6 = false;
for (int k = 0; k < col && !V_3; k++) { for (int k = 0; k < col && !V_3; k++) {
if (squares[row, k] == Empty) { if (squares[row, k] == Empty) {
V_3 = 1; V_3 = true;
} else { } else {
if (squares[row, k] != i || !safeDiscs[row, k]) { if (squares[row, k] != i || !safeDiscs[row, k]) {
V_5 = 1; V_5 = true;
} }
} }
} }
k = col + 1; k = col + 1;
for (; k < 8 && !V_4; k++) { for (; k < 8 && !V_4; k++) {
if (squares[row, k] == Empty) { if (squares[row, k] == Empty) {
V_4 = 1; V_4 = true;
} else { } else {
if (squares[row, k] != i || !safeDiscs[row, k]) { if (squares[row, k] != i || !safeDiscs[row, k]) {
V_6 = 1; V_6 = true;
} }
} }
} }
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 true;
} }
V_3 = 0; V_3 = false;
V_4 = 0; V_4 = false;
V_5 = 0; V_5 = false;
V_6 = 0; V_6 = false;
for (int j = 0; j < row && !V_3; j++) { for (int j = 0; j < row && !V_3; j++) {
if (squares[j, col] == Empty) { if (squares[j, col] == Empty) {
V_3 = 1; V_3 = true;
} else { } else {
if (squares[j, col] != i || !safeDiscs[j, col]) { if (squares[j, col] != i || !safeDiscs[j, col]) {
V_5 = 1; V_5 = true;
} }
} }
} }
j = row + 1; j = row + 1;
for (; j < 8 && !V_4; j++) { for (; j < 8 && !V_4; j++) {
if (squares[j, col] == Empty) { if (squares[j, col] == Empty) {
V_4 = 1; V_4 = true;
} else { } else {
if (squares[j, col] != i || !safeDiscs[j, col]) { if (squares[j, col] != i || !safeDiscs[j, col]) {
V_6 = 1; V_6 = true;
} }
} }
} }
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 true;
} }
V_3 = 0; V_3 = false;
V_4 = 0; V_4 = false;
V_5 = 0; V_5 = false;
V_6 = 0; V_6 = false;
j = row - 1; j = row - 1;
k = col - 1; k = col - 1;
for (; j >= 0 && k >= 0 && !V_3; k--) { for (; j >= 0 && k >= 0 && !V_3; k--) {
if (squares[j, k] == Empty) { if (squares[j, k] == Empty) {
V_3 = 1; V_3 = true;
} else { } else {
if (squares[j, k] != i || !safeDiscs[j, k]) { if (squares[j, k] != i || !safeDiscs[j, k]) {
V_5 = 1; V_5 = true;
} }
} }
j--; j--;
@ -285,29 +285,29 @@ namespace Reversi
k = col + 1; k = col + 1;
for (; j < 8 && k < 8 && !V_4; k++) { for (; j < 8 && k < 8 && !V_4; k++) {
if (squares[j, k] == Empty) { if (squares[j, k] == Empty) {
V_4 = 1; V_4 = true;
} else { } else {
if (squares[j, k] != i || !safeDiscs[j, k]) { if (squares[j, k] != i || !safeDiscs[j, k]) {
V_6 = 1; V_6 = true;
} }
} }
j++; j++;
} }
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 true;
} }
V_3 = 0; V_3 = false;
V_4 = 0; V_4 = false;
V_5 = 0; V_5 = false;
V_6 = 0; V_6 = false;
j = row - 1; j = row - 1;
k = col + 1; k = col + 1;
for (; j >= 0 && k < 8 && !V_3; k++) { for (; j >= 0 && k < 8 && !V_3; k++) {
if (squares[j, k] == Empty) { if (squares[j, k] == Empty) {
V_3 = 1; V_3 = true;
} else { } else {
if (squares[j, k] != i || !safeDiscs[j, k]) { if (squares[j, k] != i || !safeDiscs[j, k]) {
V_5 = 1; V_5 = true;
} }
} }
j--; j--;
@ -316,18 +316,18 @@ namespace Reversi
k = col - 1; k = col - 1;
for (; j < 8 && k >= 0 && !V_4; k--) { for (; j < 8 && k >= 0 && !V_4; k--) {
if (squares[j, k] == Empty) { if (squares[j, k] == Empty) {
V_4 = 1; V_4 = true;
} else { } else {
if (squares[j, k] != i || !safeDiscs[j, k]) { if (squares[j, k] != i || !safeDiscs[j, k]) {
V_6 = 1; V_6 = true;
} }
} }
j++; j++;
} }
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 true;
} }
return 0; return false;
} }
} }
} }

3
lib/NRefactory/Project/Src/Ast/AbstractNode.cs

@ -20,7 +20,7 @@ namespace ICSharpCode.NRefactory.Ast
public INode Parent { get; set; } public INode Parent { get; set; }
public Location StartLocation { get; set; } public Location StartLocation { get; set; }
public Location EndLocation { get; set; } public Location EndLocation { get; set; }
public object UserData { get; set; } public Dictionary<string, object> UserData { get; set; }
IList<INode> INode.Children { IList<INode> INode.Children {
get { get {
@ -42,6 +42,7 @@ namespace ICSharpCode.NRefactory.Ast
{ {
children = new NodeCollection(); children = new NodeCollection();
children.Added += delegate(object sender, NodeEventArgs e) { e.Node.Parent = this; }; children.Added += delegate(object sender, NodeEventArgs e) { e.Node.Parent = this; };
this.UserData = new Dictionary<string, object>();
} }
public virtual void AddChild(INode childNode) public virtual void AddChild(INode childNode)

2
lib/NRefactory/Project/Src/Ast/INode.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.NRefactory.Ast
set; set;
} }
object UserData { Dictionary<string, object> UserData {
get; get;
set; set;
} }

2
lib/NRefactory/Project/Src/SnippetParser.cs

@ -117,7 +117,7 @@ namespace ICSharpCode.NRefactory
set { throw new NotSupportedException(); } set { throw new NotSupportedException(); }
} }
public object UserData { get; set; } public Dictionary<string, object> UserData { get; set; }
public object AcceptChildren(IAstVisitor visitor, object data) public object AcceptChildren(IAstVisitor visitor, object data)
{ {

37
src/AstMetodBodyBuilder.cs

@ -279,10 +279,11 @@ namespace Decompiler
static object TransformByteCode(MethodDefinition methodDef, ByteCode byteCode, List<Ast.Expression> args) static object TransformByteCode(MethodDefinition methodDef, ByteCode byteCode, List<Ast.Expression> args)
{ {
try { try {
object ret = TransformByteCode_Internal(methodDef, byteCode, args); Ast.INode ret = TransformByteCode_Internal(methodDef, byteCode, args);
if (ret is Ast.Expression) { if (ret is Ast.Expression) {
ret = new ParenthesizedExpression((Ast.Expression)ret); ret = new ParenthesizedExpression((Ast.Expression)ret);
} }
ret.UserData["Type"] = byteCode.Type;
return ret; return ret;
} catch (NotImplementedException) { } catch (NotImplementedException) {
// Output the operand of the unknown IL code as well // Output the operand of the unknown IL code as well
@ -293,7 +294,7 @@ namespace Decompiler
} }
} }
static object TransformByteCode_Internal(MethodDefinition methodDef, ByteCode byteCode, List<Ast.Expression> args) static Ast.INode TransformByteCode_Internal(MethodDefinition methodDef, ByteCode byteCode, List<Ast.Expression> args)
{ {
OpCode opCode = byteCode.OpCode; OpCode opCode = byteCode.OpCode;
object operand = byteCode.Operand; object operand = byteCode.Operand;
@ -579,12 +580,21 @@ namespace Decompiler
case Code.Readonly: throw new NotImplementedException(); case Code.Readonly: throw new NotImplementedException();
case Code.Refanytype: throw new NotImplementedException(); case Code.Refanytype: throw new NotImplementedException();
case Code.Refanyval: throw new NotImplementedException(); case Code.Refanyval: throw new NotImplementedException();
case Code.Ret: return new Ast.ReturnStatement(methodDef.ReturnType.ReturnType.FullName != Cecil.Constants.Void ? arg1 : null); case Code.Ret: {
if (methodDef.ReturnType.ReturnType.FullName != Cecil.Constants.Void) {
arg1 = Convert(arg1, methodDef.ReturnType.ReturnType);
return new Ast.ReturnStatement(arg1);
} else {
return new Ast.ReturnStatement(null);
}
}
case Code.Rethrow: throw new NotImplementedException(); case Code.Rethrow: throw new NotImplementedException();
case Code.Sizeof: throw new NotImplementedException(); case Code.Sizeof: throw new NotImplementedException();
case Code.Starg: throw new NotImplementedException(); case Code.Starg: throw new NotImplementedException();
case Code.Stloc: case Code.Stloc: {
string name = ((VariableDefinition)operand).Name; VariableDefinition locVar = (VariableDefinition)operand;
string name = locVar.Name;
arg1 = Convert(arg1, locVar.VariableType);
if (localVarDefined[name]) { if (localVarDefined[name]) {
return new Ast.AssignmentExpression(new Ast.IdentifierExpression(name), AssignmentOperatorType.Assign, arg1); return new Ast.AssignmentExpression(new Ast.IdentifierExpression(name), AssignmentOperatorType.Assign, arg1);
} else { } else {
@ -593,6 +603,7 @@ namespace Decompiler
localVarDefined[name] = true; localVarDefined[name] = true;
return astLocalVar; return astLocalVar;
} }
}
case Code.Stobj: throw new NotImplementedException(); case Code.Stobj: throw new NotImplementedException();
case Code.Switch: throw new NotImplementedException(); case Code.Switch: throw new NotImplementedException();
case Code.Tail: throw new NotImplementedException(); case Code.Tail: throw new NotImplementedException();
@ -605,6 +616,22 @@ namespace Decompiler
} }
} }
static Ast.Expression Convert(Ast.Expression expr, Cecil.TypeReference reqType)
{
if (expr.UserData.ContainsKey("Type")) {
Cecil.TypeReference exprType = (Cecil.TypeReference)expr.UserData["Type"];
if (exprType == ByteCode.TypeZero &&
reqType.FullName == ByteCode.TypeBool.FullName) {
return new PrimitiveExpression(false, "false");
}
if (exprType == ByteCode.TypeOne &&
reqType.FullName == ByteCode.TypeBool.FullName) {
return new PrimitiveExpression(true, "true");
}
}
return expr;
}
static Ast.Expression ConvertIntToBool(Ast.Expression astInt) static Ast.Expression ConvertIntToBool(Ast.Expression astInt)
{ {
return new Ast.ParenthesizedExpression(new Ast.BinaryOperatorExpression(astInt, BinaryOperatorType.InEquality, new Ast.PrimitiveExpression(0, "0"))); return new Ast.ParenthesizedExpression(new Ast.BinaryOperatorExpression(astInt, BinaryOperatorType.InEquality, new Ast.PrimitiveExpression(0, "0")));

15
src/ByteCode.Type.cs

@ -17,6 +17,8 @@ namespace Decompiler
static public Cecil.TypeReference TypeBool = GetCecilType(typeof(bool)); static public Cecil.TypeReference TypeBool = GetCecilType(typeof(bool));
static public Cecil.TypeReference TypeInt32 = GetCecilType(typeof(Int32)); static public Cecil.TypeReference TypeInt32 = GetCecilType(typeof(Int32));
static public Cecil.TypeReference TypeString = GetCecilType(typeof(string)); static public Cecil.TypeReference TypeString = GetCecilType(typeof(string));
static public Cecil.TypeReference TypeZero = GetCecilType(typeof(Int32));
static public Cecil.TypeReference TypeOne = GetCecilType(typeof(Int32));
static public Cecil.TypeReference GetCecilType(Type type) static public Cecil.TypeReference GetCecilType(Type type)
{ {
@ -198,7 +200,7 @@ namespace Decompiler
case Code.Break: throw new NotImplementedException(); case Code.Break: throw new NotImplementedException();
case Code.Call: return ((MethodReference)operand).ReturnType.ReturnType; case Code.Call: return ((MethodReference)operand).ReturnType.ReturnType;
case Code.Calli: throw new NotImplementedException(); case Code.Calli: throw new NotImplementedException();
case Code.Callvirt: throw new NotImplementedException(); case Code.Callvirt: return ((MethodReference)operand).ReturnType.ReturnType;
case Code.Castclass: throw new NotImplementedException(); case Code.Castclass: throw new NotImplementedException();
case Code.Ckfinite: throw new NotImplementedException(); case Code.Ckfinite: throw new NotImplementedException();
case Code.Constrained: throw new NotImplementedException(); case Code.Constrained: throw new NotImplementedException();
@ -216,11 +218,18 @@ namespace Decompiler
// 'this' returns null; TODO: Return proper type of this // 'this' returns null; TODO: Return proper type of this
return typeRef ?? TypeObject; return typeRef ?? TypeObject;
case Code.Ldarga: throw new NotImplementedException(); case Code.Ldarga: throw new NotImplementedException();
case Code.Ldc_I4: return TypeInt32; case Code.Ldc_I4:
if ((int)operand == 0) {
return TypeZero;
} else if ((int)operand == 1) {
return TypeOne;
} else {
return TypeInt32;
}
case Code.Ldc_I8: throw new NotImplementedException(); case Code.Ldc_I8: throw new NotImplementedException();
case Code.Ldc_R4: throw new NotImplementedException(); case Code.Ldc_R4: throw new NotImplementedException();
case Code.Ldc_R8: throw new NotImplementedException(); case Code.Ldc_R8: throw new NotImplementedException();
case Code.Ldfld: throw new NotImplementedException(); case Code.Ldfld: return ((FieldDefinition)operand).FieldType;
case Code.Ldflda: throw new NotImplementedException(); case Code.Ldflda: throw new NotImplementedException();
case Code.Ldftn: throw new NotImplementedException(); case Code.Ldftn: throw new NotImplementedException();
case Code.Ldloc: return ((VariableDefinition)operand).VariableType; case Code.Ldloc: return ((VariableDefinition)operand).VariableType;

Loading…
Cancel
Save