Browse Source

Unary operators rewritten to match C# semantics. Added unit tests.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5172 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 16 years ago
parent
commit
b4e733b738
  1. 534
      src/AddIns/Misc/Debugger/Debugger.Core/NRefactory/Visitors/ExpressionEvaluator.cs
  2. 78
      src/AddIns/Misc/Debugger/Debugger.Tests/Tests/ExpressionEvaluator_Tests.cs

534
src/AddIns/Misc/Debugger/Debugger.Core/NRefactory/Visitors/ExpressionEvaluator.cs

@ -593,59 +593,135 @@ namespace ICSharpCode.NRefactory.Visitors
if (!value.Type.IsPrimitive) if (!value.Type.IsPrimitive)
throw new GetValueException("Primitive value expected"); throw new GetValueException("Primitive value expected");
object val = value.PrimitiveValue; if (op == UnaryOperatorType.Decrement || op == UnaryOperatorType.PostDecrement ||
op == UnaryOperatorType.Increment || op == UnaryOperatorType.PostIncrement)
object result = null; {
TypedValue oldValue = value;
// Bool operation TypedValue newValue = null;
if (val is bool) { try {
bool a = Convert.ToBoolean(val); if (op == UnaryOperatorType.Decrement || op == UnaryOperatorType.PostDecrement)
switch (op) { newValue = (TypedValue)VisitAssignmentExpression(new AssignmentExpression(unaryOperatorExpression.Expression, AssignmentOperatorType.Subtract, new PrimitiveExpression(1)), null);
case UnaryOperatorType.Not: result = !a; break; if (op == UnaryOperatorType.Increment || op == UnaryOperatorType.PostIncrement)
newValue = (TypedValue)VisitAssignmentExpression(new AssignmentExpression(unaryOperatorExpression.Expression, AssignmentOperatorType.Add, new PrimitiveExpression(1)), null);
} catch (EvaluateException e) {
throw new EvaluateException(unaryOperatorExpression, e.Message);
}
if (op == UnaryOperatorType.PostDecrement || op == UnaryOperatorType.PostIncrement) {
return oldValue;
} else {
// Note: the old unaryOparatorExpression is still cached and still has the old value
return newValue;
} }
} }
// Float operation if (op == UnaryOperatorType.Minus) {
if (val is double || val is float) { object val = value.PrimitiveValue;
double a = Convert.ToDouble(val); // Special case - it would promote the value to long otherwise
switch (op) { if (val is uint && (uint)val == (uint)1 << 31)
case UnaryOperatorType.Minus: result = -a; break; return CreateValue(int.MinValue);
case UnaryOperatorType.Plus: result = +a; break;
// Special case - it would overflow otherwise
if (val is ulong && (ulong)val == (ulong)1 << 63)
return CreateValue(long.MinValue);
}
if (op == UnaryOperatorType.Plus || op == UnaryOperatorType.Minus ||
op == UnaryOperatorType.BitNot || op == UnaryOperatorType.Not)
{
Type[] overloads;
if (op == UnaryOperatorType.Not) {
overloads = new Type[] { typeof(bool) };
} else if (op == UnaryOperatorType.Minus) {
overloads = new Type[] { typeof(int), typeof(long), typeof(ulong), typeof(float), typeof(double) };
} else {
overloads = new Type[] { typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double) };
}
foreach(Type argType in overloads) {
if (value.Type.CanPromoteTo(argType)) {
object a = Convert.ChangeType(value.PrimitiveValue, argType);
object res;
try {
res = PerformUnaryOperation(a, op, argType);
} catch (ArithmeticException e) {
// Can happen for smaller int or long
throw new EvaluateException(unaryOperatorExpression, e.Message);
}
if (res != null)
return CreateValue(res);
break; // Match only one overload
}
} }
} }
throw new EvaluateException(unaryOperatorExpression, "Can not use the unary operator {0} on type {1}", op.ToString(), value.Type.FullName);
}
// Integer operation /// <summary>
if (val is byte || val is sbyte || val is int || val is uint || val is long || val is ulong) { /// Perform given arithmetic operation.
long a = Convert.ToInt64(val); /// The arguments must be already converted to the correct types.
switch (op) { /// </summary>
case UnaryOperatorType.Decrement: result = a - 1; break; object PerformUnaryOperation(object val, UnaryOperatorType op, Type argType)
case UnaryOperatorType.Increment: result = a + 1; break; {
case UnaryOperatorType.PostDecrement: result = a; break; checked {
case UnaryOperatorType.PostIncrement: result = a; break; if (argType == typeof(bool)) {
case UnaryOperatorType.Minus: result = -a; break; bool a = (bool)val;
case UnaryOperatorType.Plus: result = a; break; switch (op) {
case UnaryOperatorType.BitNot: result = ~a; break; case UnaryOperatorType.Not: return !a;
}
} }
switch (op) {
case UnaryOperatorType.Decrement: if (argType == typeof(float)) {
case UnaryOperatorType.PostDecrement: float a = (float)val;
VisitAssignmentExpression(new AssignmentExpression(unaryOperatorExpression.Expression, AssignmentOperatorType.Subtract, new PrimitiveExpression(1)), null); switch (op) {
break; case UnaryOperatorType.Minus: return -a;
case UnaryOperatorType.Increment: case UnaryOperatorType.Plus: return +a;
case UnaryOperatorType.PostIncrement: }
VisitAssignmentExpression(new AssignmentExpression(unaryOperatorExpression.Expression, AssignmentOperatorType.Add, new PrimitiveExpression(1)), null); }
break;
if (argType == typeof(double)) {
double a = (double)val;
switch (op) {
case UnaryOperatorType.Minus: return -a;
case UnaryOperatorType.Plus: return +a;
}
} }
}
long? l = result as long?;
if (l != null && int.MinValue <= l && l <= int.MaxValue)
result = (int)l;
if (result == null) if (argType == typeof(int)) {
throw new GetValueException("Unsuppored unary expression " + op); int a = (int)val;
switch (op) {
case UnaryOperatorType.Minus: return -a;
case UnaryOperatorType.Plus: return +a;
case UnaryOperatorType.BitNot: return ~a;
}
}
if (argType == typeof(uint)) {
uint a = (uint)val;
switch (op) {
case UnaryOperatorType.Plus: return +a;
case UnaryOperatorType.BitNot: return ~a;
}
}
if (argType == typeof(long)) {
long a = (long)val;
switch (op) {
case UnaryOperatorType.Minus: return -a;
case UnaryOperatorType.Plus: return +a;
case UnaryOperatorType.BitNot: return ~a;
}
}
if (argType == typeof(ulong)) {
ulong a = (ulong)val;
switch (op) {
case UnaryOperatorType.Plus: return +a;
case UnaryOperatorType.BitNot: return ~a;
}
}
}
return CreateValue(result); return null;
} }
public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data) public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
@ -706,8 +782,8 @@ namespace ICSharpCode.NRefactory.Visitors
Type[] overloads = { typeof(int), typeof(uint), typeof(long), typeof(ulong)}; Type[] overloads = { typeof(int), typeof(uint), typeof(long), typeof(ulong)};
foreach(Type argType in overloads) { foreach(Type argType in overloads) {
if (left.Type.CanPromoteTo(argType) && right.Type.CanPromoteTo(typeof(int))) { if (left.Type.CanPromoteTo(argType) && right.Type.CanPromoteTo(typeof(int))) {
object a = Convert.ChangeType(left.Value.PrimitiveValue, argType); object a = Convert.ChangeType(left.PrimitiveValue, argType);
object b = Convert.ChangeType(right.Value.PrimitiveValue, typeof(int)); object b = Convert.ChangeType(right.PrimitiveValue, typeof(int));
// Shift operations never cause overflows // Shift operations never cause overflows
object res = PerformBinaryOperation(a, b, op, argType); object res = PerformBinaryOperation(a, b, op, argType);
return CreateValue(res); return CreateValue(res);
@ -722,6 +798,8 @@ namespace ICSharpCode.NRefactory.Visitors
// uint operator +(uint x, uint y); // uint operator +(uint x, uint y);
// long operator +(long x, long y); // long operator +(long x, long y);
// ulong operator +(ulong x, ulong y); // ulong operator +(ulong x, ulong y);
// void operator +(long x, ulong y);
// void operator +(ulong x, long y);
// float operator +(float x, float y); // float operator +(float x, float y);
// double operator +(double x, double y); // double operator +(double x, double y);
// //
@ -733,8 +811,15 @@ namespace ICSharpCode.NRefactory.Visitors
Type[] overloads = { typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(bool) }; Type[] overloads = { typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(bool) };
foreach(Type argType in overloads) { foreach(Type argType in overloads) {
if (left.Type.CanPromoteTo(argType) && right.Type.CanPromoteTo(argType)) { if (left.Type.CanPromoteTo(argType) && right.Type.CanPromoteTo(argType)) {
object a = Convert.ChangeType(left.Value.PrimitiveValue, argType); if (argType == typeof(float) || argType == typeof(double)) {
object b = Convert.ChangeType(right.Value.PrimitiveValue, argType); // Invalid overloads
if (left.Type.CanPromoteTo(typeof(long)) && right.Type.CanPromoteTo(typeof(ulong)))
break;
if (left.Type.CanPromoteTo(typeof(ulong)) && right.Type.CanPromoteTo(typeof(long)))
break;
}
object a = Convert.ChangeType(left.PrimitiveValue, argType);
object b = Convert.ChangeType(right.PrimitiveValue, argType);
object res; object res;
try { try {
res = PerformBinaryOperation(a, b, op, argType); res = PerformBinaryOperation(a, b, op, argType);
@ -743,11 +828,12 @@ namespace ICSharpCode.NRefactory.Visitors
} }
if (res != null) if (res != null)
return CreateValue(res); return CreateValue(res);
break; // Match only one overload
} }
} }
} }
throw new EvaluateException(binaryOperatorExpression, "Can not use the binary operator {0} for types {1} and {2}", op.ToString(), left.Type.FullName, right.Type.FullName); throw new EvaluateException(binaryOperatorExpression, "Can not use the binary operator {0} on types {1} and {2}", op.ToString(), left.Type.FullName, right.Type.FullName);
} }
/// <summary> /// <summary>
@ -756,183 +842,185 @@ namespace ICSharpCode.NRefactory.Visitors
/// </summary> /// </summary>
object PerformBinaryOperation(object left, object right, BinaryOperatorType op, Type argTypes) object PerformBinaryOperation(object left, object right, BinaryOperatorType op, Type argTypes)
{ {
if (argTypes == typeof(string)) { checked {
string a = (string)left; if (argTypes == typeof(string)) {
string b = (string)right; string a = (string)left;
switch (op) { string b = (string)right;
case BinaryOperatorType.Equality: return a == b; switch (op) {
case BinaryOperatorType.InEquality: return a != b; case BinaryOperatorType.Equality: return a == b;
case BinaryOperatorType.Add: return a + b; case BinaryOperatorType.InEquality: return a != b;
} case BinaryOperatorType.Add: return a + b;
} }
}
if (argTypes == typeof(bool)) {
bool a = (bool)left; if (argTypes == typeof(bool)) {
bool b = (bool)right; bool a = (bool)left;
switch (op) { bool b = (bool)right;
case BinaryOperatorType.Equality: return a == b; switch (op) {
case BinaryOperatorType.InEquality: return a != b; case BinaryOperatorType.Equality: return a == b;
case BinaryOperatorType.ExclusiveOr: return a ^ b; case BinaryOperatorType.InEquality: return a != b;
case BinaryOperatorType.BitwiseAnd: return a & b; case BinaryOperatorType.ExclusiveOr: return a ^ b;
case BinaryOperatorType.BitwiseOr: return a | b; case BinaryOperatorType.BitwiseAnd: return a & b;
case BinaryOperatorType.LogicalAnd: return a && b; case BinaryOperatorType.BitwiseOr: return a | b;
case BinaryOperatorType.LogicalOr: return a || b; case BinaryOperatorType.LogicalAnd: return a && b;
} case BinaryOperatorType.LogicalOr: return a || b;
} }
}
if (argTypes == typeof(float)) {
float a = (float)left; if (argTypes == typeof(float)) {
float b = (float)right; float a = (float)left;
switch (op) { float b = (float)right;
case BinaryOperatorType.GreaterThan: return a > b; switch (op) {
case BinaryOperatorType.GreaterThanOrEqual: return a >= b; case BinaryOperatorType.GreaterThan: return a > b;
case BinaryOperatorType.Equality: return a == b; case BinaryOperatorType.GreaterThanOrEqual: return a >= b;
case BinaryOperatorType.InEquality: return a != b; case BinaryOperatorType.Equality: return a == b;
case BinaryOperatorType.LessThan: return a < b; case BinaryOperatorType.InEquality: return a != b;
case BinaryOperatorType.LessThanOrEqual: return a <= b; case BinaryOperatorType.LessThan: return a < b;
case BinaryOperatorType.LessThanOrEqual: return a <= b;
case BinaryOperatorType.Add: return a + b;
case BinaryOperatorType.Subtract: return a - b; case BinaryOperatorType.Add: return a + b;
case BinaryOperatorType.Multiply: return a * b; case BinaryOperatorType.Subtract: return a - b;
case BinaryOperatorType.Divide: return a / b; case BinaryOperatorType.Multiply: return a * b;
case BinaryOperatorType.Modulus: return a % b; case BinaryOperatorType.Divide: return a / b;
case BinaryOperatorType.Concat: return a + b; case BinaryOperatorType.Modulus: return a % b;
} case BinaryOperatorType.Concat: return a + b;
} }
}
if (argTypes == typeof(double)) {
double a = (double)left; if (argTypes == typeof(double)) {
double b = (double)right; double a = (double)left;
switch (op) { double b = (double)right;
case BinaryOperatorType.GreaterThan: return a > b; switch (op) {
case BinaryOperatorType.GreaterThanOrEqual: return a >= b; case BinaryOperatorType.GreaterThan: return a > b;
case BinaryOperatorType.Equality: return a == b; case BinaryOperatorType.GreaterThanOrEqual: return a >= b;
case BinaryOperatorType.InEquality: return a != b; case BinaryOperatorType.Equality: return a == b;
case BinaryOperatorType.LessThan: return a < b; case BinaryOperatorType.InEquality: return a != b;
case BinaryOperatorType.LessThanOrEqual: return a <= b; case BinaryOperatorType.LessThan: return a < b;
case BinaryOperatorType.LessThanOrEqual: return a <= b;
case BinaryOperatorType.Add: return a + b;
case BinaryOperatorType.Subtract: return a - b; case BinaryOperatorType.Add: return a + b;
case BinaryOperatorType.Multiply: return a * b; case BinaryOperatorType.Subtract: return a - b;
case BinaryOperatorType.Divide: return a / b; case BinaryOperatorType.Multiply: return a * b;
case BinaryOperatorType.Modulus: return a % b; case BinaryOperatorType.Divide: return a / b;
case BinaryOperatorType.Concat: return a + b; case BinaryOperatorType.Modulus: return a % b;
} case BinaryOperatorType.Concat: return a + b;
} }
}
if (argTypes == typeof(int)) {
switch (op) { if (argTypes == typeof(int)) {
case BinaryOperatorType.ShiftLeft: return (int)left << (int)right; switch (op) {
case BinaryOperatorType.ShiftRight: return (int)left >> (int)right; case BinaryOperatorType.ShiftLeft: return (int)left << (int)right;
} case BinaryOperatorType.ShiftRight: return (int)left >> (int)right;
int a = (int)left; }
int b = (int)right; int a = (int)left;
switch (op) { int b = (int)right;
case BinaryOperatorType.BitwiseAnd: return a & b; switch (op) {
case BinaryOperatorType.BitwiseOr: return a | b; case BinaryOperatorType.BitwiseAnd: return a & b;
case BinaryOperatorType.ExclusiveOr: return a ^ b; case BinaryOperatorType.BitwiseOr: return a | b;
case BinaryOperatorType.ExclusiveOr: return a ^ b;
case BinaryOperatorType.GreaterThan: return a > b;
case BinaryOperatorType.GreaterThanOrEqual: return a >= b; case BinaryOperatorType.GreaterThan: return a > b;
case BinaryOperatorType.Equality: return a == b; case BinaryOperatorType.GreaterThanOrEqual: return a >= b;
case BinaryOperatorType.InEquality: return a != b; case BinaryOperatorType.Equality: return a == b;
case BinaryOperatorType.LessThan: return a < b; case BinaryOperatorType.InEquality: return a != b;
case BinaryOperatorType.LessThanOrEqual: return a <= b; case BinaryOperatorType.LessThan: return a < b;
case BinaryOperatorType.LessThanOrEqual: return a <= b;
case BinaryOperatorType.Add: return a + b;
case BinaryOperatorType.Subtract: return a - b; case BinaryOperatorType.Add: return a + b;
case BinaryOperatorType.Multiply: return a * b; case BinaryOperatorType.Subtract: return a - b;
case BinaryOperatorType.Divide: return a / b; case BinaryOperatorType.Multiply: return a * b;
case BinaryOperatorType.Modulus: return a % b; case BinaryOperatorType.Divide: return a / b;
case BinaryOperatorType.Concat: return a + b; case BinaryOperatorType.Modulus: return a % b;
} case BinaryOperatorType.Concat: return a + b;
} }
}
if (argTypes == typeof(uint)) {
switch (op) { if (argTypes == typeof(uint)) {
case BinaryOperatorType.ShiftLeft: return (uint)left << (int)right; switch (op) {
case BinaryOperatorType.ShiftRight: return (uint)left >> (int)right; case BinaryOperatorType.ShiftLeft: return (uint)left << (int)right;
} case BinaryOperatorType.ShiftRight: return (uint)left >> (int)right;
uint a = (uint)left; }
uint b = (uint)right; uint a = (uint)left;
switch (op) { uint b = (uint)right;
case BinaryOperatorType.BitwiseAnd: return a & b; switch (op) {
case BinaryOperatorType.BitwiseOr: return a | b; case BinaryOperatorType.BitwiseAnd: return a & b;
case BinaryOperatorType.ExclusiveOr: return a ^ b; case BinaryOperatorType.BitwiseOr: return a | b;
case BinaryOperatorType.ExclusiveOr: return a ^ b;
case BinaryOperatorType.GreaterThan: return a > b;
case BinaryOperatorType.GreaterThanOrEqual: return a >= b; case BinaryOperatorType.GreaterThan: return a > b;
case BinaryOperatorType.Equality: return a == b; case BinaryOperatorType.GreaterThanOrEqual: return a >= b;
case BinaryOperatorType.InEquality: return a != b; case BinaryOperatorType.Equality: return a == b;
case BinaryOperatorType.LessThan: return a < b; case BinaryOperatorType.InEquality: return a != b;
case BinaryOperatorType.LessThanOrEqual: return a <= b; case BinaryOperatorType.LessThan: return a < b;
case BinaryOperatorType.LessThanOrEqual: return a <= b;
case BinaryOperatorType.Add: return a + b;
case BinaryOperatorType.Subtract: return a - b; case BinaryOperatorType.Add: return a + b;
case BinaryOperatorType.Multiply: return a * b; case BinaryOperatorType.Subtract: return a - b;
case BinaryOperatorType.Divide: return a / b; case BinaryOperatorType.Multiply: return a * b;
case BinaryOperatorType.Modulus: return a % b; case BinaryOperatorType.Divide: return a / b;
case BinaryOperatorType.Concat: return a + b; case BinaryOperatorType.Modulus: return a % b;
} case BinaryOperatorType.Concat: return a + b;
} }
}
if (argTypes == typeof(long)) {
switch (op) { if (argTypes == typeof(long)) {
case BinaryOperatorType.ShiftLeft: return (long)left << (int)right; switch (op) {
case BinaryOperatorType.ShiftRight: return (long)left >> (int)right; case BinaryOperatorType.ShiftLeft: return (long)left << (int)right;
} case BinaryOperatorType.ShiftRight: return (long)left >> (int)right;
long a = (long)left; }
long b = (long)right; long a = (long)left;
switch (op) { long b = (long)right;
case BinaryOperatorType.BitwiseAnd: return a & b; switch (op) {
case BinaryOperatorType.BitwiseOr: return a | b; case BinaryOperatorType.BitwiseAnd: return a & b;
case BinaryOperatorType.ExclusiveOr: return a ^ b; case BinaryOperatorType.BitwiseOr: return a | b;
case BinaryOperatorType.ExclusiveOr: return a ^ b;
case BinaryOperatorType.GreaterThan: return a > b;
case BinaryOperatorType.GreaterThanOrEqual: return a >= b; case BinaryOperatorType.GreaterThan: return a > b;
case BinaryOperatorType.Equality: return a == b; case BinaryOperatorType.GreaterThanOrEqual: return a >= b;
case BinaryOperatorType.InEquality: return a != b; case BinaryOperatorType.Equality: return a == b;
case BinaryOperatorType.LessThan: return a < b; case BinaryOperatorType.InEquality: return a != b;
case BinaryOperatorType.LessThanOrEqual: return a <= b; case BinaryOperatorType.LessThan: return a < b;
case BinaryOperatorType.LessThanOrEqual: return a <= b;
case BinaryOperatorType.Add: return a + b;
case BinaryOperatorType.Subtract: return a - b; case BinaryOperatorType.Add: return a + b;
case BinaryOperatorType.Multiply: return a * b; case BinaryOperatorType.Subtract: return a - b;
case BinaryOperatorType.Divide: return a / b; case BinaryOperatorType.Multiply: return a * b;
case BinaryOperatorType.Modulus: return a % b; case BinaryOperatorType.Divide: return a / b;
case BinaryOperatorType.Concat: return a + b; case BinaryOperatorType.Modulus: return a % b;
} case BinaryOperatorType.Concat: return a + b;
} }
}
if (argTypes == typeof(ulong)) {
switch (op) { if (argTypes == typeof(ulong)) {
case BinaryOperatorType.ShiftLeft: return (ulong)left << (int)right; switch (op) {
case BinaryOperatorType.ShiftRight: return (ulong)left >> (int)right; case BinaryOperatorType.ShiftLeft: return (ulong)left << (int)right;
} case BinaryOperatorType.ShiftRight: return (ulong)left >> (int)right;
ulong a = (ulong)left; }
ulong b = (ulong)right; ulong a = (ulong)left;
switch (op) { ulong b = (ulong)right;
case BinaryOperatorType.BitwiseAnd: return a & b; switch (op) {
case BinaryOperatorType.BitwiseOr: return a | b; case BinaryOperatorType.BitwiseAnd: return a & b;
case BinaryOperatorType.ExclusiveOr: return a ^ b; case BinaryOperatorType.BitwiseOr: return a | b;
case BinaryOperatorType.ExclusiveOr: return a ^ b;
case BinaryOperatorType.GreaterThan: return a > b;
case BinaryOperatorType.GreaterThanOrEqual: return a >= b; case BinaryOperatorType.GreaterThan: return a > b;
case BinaryOperatorType.Equality: return a == b; case BinaryOperatorType.GreaterThanOrEqual: return a >= b;
case BinaryOperatorType.InEquality: return a != b; case BinaryOperatorType.Equality: return a == b;
case BinaryOperatorType.LessThan: return a < b; case BinaryOperatorType.InEquality: return a != b;
case BinaryOperatorType.LessThanOrEqual: return a <= b; case BinaryOperatorType.LessThan: return a < b;
case BinaryOperatorType.LessThanOrEqual: return a <= b;
case BinaryOperatorType.Add: return a + b;
case BinaryOperatorType.Subtract: return a - b; case BinaryOperatorType.Add: return a + b;
case BinaryOperatorType.Multiply: return a * b; case BinaryOperatorType.Subtract: return a - b;
case BinaryOperatorType.Divide: return a / b; case BinaryOperatorType.Multiply: return a * b;
case BinaryOperatorType.Modulus: return a % b; case BinaryOperatorType.Divide: return a / b;
case BinaryOperatorType.Concat: return a + b; case BinaryOperatorType.Modulus: return a % b;
case BinaryOperatorType.Concat: return a + b;
}
} }
}
return null; return null;
}
} }
#endregion #endregion

78
src/AddIns/Misc/Debugger/Debugger.Tests/Tests/ExpressionEvaluator_Tests.cs

@ -154,18 +154,24 @@ namespace Debugger.Tests {
{ {
string expressionsInput = @" string expressionsInput = @"
b; i; *i; *iPtr; pi b; i; *i; *iPtr; pi
pi - 3; pi + b; i + b; (uint)2 - 3; ((uint)2 - 3).GetType() ; (ulong)2 - 3 ; ((ulong)2 - 3).GetType(); (b + b).GetType() pi - 3; pi + b; i + b; (uint)2 - 3; ((uint)2 - 3).GetType() ; (ulong)2 - 3 ; (b + b).GetType()
1 << 4; 7 << -1; 1 << (uint)2; 1.0 & 2.0; System.Int32.MaxValue + 1; (uint)2 - (uint)3; 1 / 0 1 << 4; 7 << -1; 1 << (uint)2; 1.0 & 2.0; System.Int32.MaxValue + 1; (uint)2 - (uint)3; 1 / 0
hi + hi; hi + ''#''; hi + pi; hi + null hi + hi; hi + ''#''; hi + pi; hi + null
hi + ''#'' == ''hi#''; hi == (string)null; hi == null; hi == 1; null == null hi + ''#'' == ''hi#''; hi + ''#'' == (object) ''hi#''; hi == (string)null; hi == null; hi == 1; null == null
arg; instanceField; staticField
(5 + 6) % (1 + 2); 3 % 2 == 1 (5 + 6) % (1 + 2); 3 % 2 == 1
15 & 255; 15 && 255 15 & 255; 15 && 255; (ulong)1 + (long)1 /* invalid */
b + 3 == i; b + 4 == i b + 3 == i; b + 4 == i
true == true; true == false true == true; true == false
i = 10; -i; ++i; i++; +i; i += 1; ~i; i = 4
-(byte)1; (-(byte)1).GetType(); -(uint)1; (-(uint)1).GetType(); -(ulong)1 /* invalid */
-2147483648 /* int.MinValue */; (-2147483648).GetType(); -(-2147483648)
-9223372036854775808 /* long.MinValue */; (-9223372036854775808).GetType(); -(-9223372036854775808)
-1.0; ~1.0; !1; flag; !flag
arg; instanceField; staticField
array; arrays; array[1]; array[i]; array[i - 1] array; arrays; array[1]; array[i]; array[i - 1]
new char[3] new char[3]
new char[b] {'a'} new char[b] {'a'}
@ -180,8 +186,6 @@ namespace Debugger.Tests {
list.Add((char)42); list.Add((char)52); list list.Add((char)42); list.Add((char)52); list
list = new System.Collections.Generic.List<char>(array2); list list = new System.Collections.Generic.List<char>(array2); list
i = 10; -i; ++i; i++; i; i += 1; i; ~i
flag; !flag
"; ";
[NUnit.Framework.Test] [NUnit.Framework.Test]
@ -299,39 +303,65 @@ namespace Debugger.Tests {
<Eval> i + b = 5 </Eval> <Eval> i + b = 5 </Eval>
<Eval> (uint)2 - 3 = -1 </Eval> <Eval> (uint)2 - 3 = -1 </Eval>
<Eval> ((uint)2 - 3).GetType() = System.Int64 </Eval> <Eval> ((uint)2 - 3).GetType() = System.Int64 </Eval>
<Eval> (ulong)2 - 3 = -1 </Eval> <Eval> (ulong)2 - 3 = Can not use the binary operator Subtract on types System.UInt64 and System.Int32 </Eval>
<Eval> ((ulong)2 - 3).GetType() = System.Single </Eval>
<Eval> (b + b).GetType() = System.Int32 </Eval> <Eval> (b + b).GetType() = System.Int32 </Eval>
<Eval> 1 &lt;&lt; 4 = 16 </Eval> <Eval> 1 &lt;&lt; 4 = 16 </Eval>
<Eval> 7 &lt;&lt; -1 = -2147483648 </Eval> <Eval> 7 &lt;&lt; -1 = -2147483648 </Eval>
<Eval> 1 &lt;&lt; (uint)2 = Can not use the binary operator ShiftLeft for types System.Int32 and System.UInt32 </Eval> <Eval> 1 &lt;&lt; (uint)2 = Can not use the binary operator ShiftLeft on types System.Int32 and System.UInt32 </Eval>
<Eval> 1.0 &amp; 2.0 = Can not use the binary operator BitwiseAnd for types System.Double and System.Double </Eval> <Eval> 1.0 &amp; 2.0 = Can not use the binary operator BitwiseAnd on types System.Double and System.Double </Eval>
<Eval> System.Int32.MaxValue + 1 = -2147483648 </Eval> <Eval> System.Int32.MaxValue + 1 = Arithmetic operation resulted in an overflow. </Eval>
<Eval> (uint)2 - (uint)3 = 4294967295 </Eval> <Eval> (uint)2 - (uint)3 = Arithmetic operation resulted in an overflow. </Eval>
<Eval> 1 / 0 = Attempted to divide by zero. </Eval> <Eval> 1 / 0 = Attempted to divide by zero. </Eval>
<Eval> hi + hi = "hihi" </Eval> <Eval> hi + hi = "hihi" </Eval>
<Eval> hi + "#" = "hi#" </Eval> <Eval> hi + "#" = "hi#" </Eval>
<Eval> hi + pi = "hi3.14" </Eval> <Eval> hi + pi = "hi3.14" </Eval>
<Eval> hi + null = "hi" </Eval> <Eval> hi + null = "hi" </Eval>
<Eval> hi + "#" == "hi#" = True </Eval> <Eval> hi + "#" == "hi#" = True </Eval>
<Eval> hi + "#" == (object) "hi#" = False </Eval>
<Eval> hi == (string)null = False </Eval> <Eval> hi == (string)null = False </Eval>
<Eval> hi == null = False </Eval> <Eval> hi == null = False </Eval>
<Eval> hi == 1 = Can not use the binary operator Equality for types System.String and System.Int32 </Eval> <Eval> hi == 1 = Can not use the binary operator Equality on types System.String and System.Int32 </Eval>
<Eval> null == null = True </Eval> <Eval> null == null = True </Eval>
<Eval> </Eval> <Eval> </Eval>
<Eval> arg = "function argument" </Eval>
<Eval> instanceField = "instance field value" </Eval>
<Eval> staticField = "static field value" </Eval>
<Eval> </Eval>
<Eval> (5 + 6) % (1 + 2) = 2 </Eval> <Eval> (5 + 6) % (1 + 2) = 2 </Eval>
<Eval> 3 % 2 == 1 = True </Eval> <Eval> 3 % 2 == 1 = True </Eval>
<Eval> 15 &amp; 255 = 15 </Eval> <Eval> 15 &amp; 255 = 15 </Eval>
<Eval> 15 &amp;&amp; 255 = Can not use the binary operator LogicalAnd for types System.Int32 and System.Int32 </Eval> <Eval> 15 &amp;&amp; 255 = Can not use the binary operator LogicalAnd on types System.Int32 and System.Int32 </Eval>
<Eval> (ulong)1 + (long)1 /* invalid */ = Can not use the binary operator Add on types System.UInt64 and System.Int64 </Eval>
<Eval> b + 3 == i = True </Eval> <Eval> b + 3 == i = True </Eval>
<Eval> b + 4 == i = False </Eval> <Eval> b + 4 == i = False </Eval>
<Eval> true == true = True </Eval> <Eval> true == true = True </Eval>
<Eval> true == false = False </Eval> <Eval> true == false = False </Eval>
<Eval> </Eval> <Eval> </Eval>
<Eval> i = 10 = 10 </Eval>
<Eval> -i = -10 </Eval>
<Eval> ++i = 11 </Eval>
<Eval> i++ = 11 </Eval>
<Eval> +i = 12 </Eval>
<Eval> i += 1 = 13 </Eval>
<Eval> ~i = -14 </Eval>
<Eval> i = 4 = 4 </Eval>
<Eval> -(byte)1 = -1 </Eval>
<Eval> (-(byte)1).GetType() = System.Int32 </Eval>
<Eval> -(uint)1 = -1 </Eval>
<Eval> (-(uint)1).GetType() = System.Int64 </Eval>
<Eval> -(ulong)1 /* invalid */ = Can not use the unary operator Minus on type System.UInt64 </Eval>
<Eval> -2147483648 /* int.MinValue */ = -2147483648 </Eval>
<Eval> (-2147483648).GetType() = System.Int32 </Eval>
<Eval> -(-2147483648) = Arithmetic operation resulted in an overflow. </Eval>
<Eval> -9223372036854775808 /* long.MinValue */ = -9223372036854775808 </Eval>
<Eval> (-9223372036854775808).GetType() = System.Int64 </Eval>
<Eval> -(-9223372036854775808) = Arithmetic operation resulted in an overflow. </Eval>
<Eval> -1.0 = -1 </Eval>
<Eval> ~1.0 = Can not use the unary operator BitNot on type System.Double </Eval>
<Eval> !1 = Can not use the unary operator Not on type System.Int32 </Eval>
<Eval> flag = True </Eval>
<Eval> !flag = False </Eval>
<Eval> </Eval>
<Eval> arg = "function argument" </Eval>
<Eval> instanceField = "instance field value" </Eval>
<Eval> staticField = "static field value" </Eval>
<Eval> </Eval>
<Eval> array = Char[] {'H', 'e', 'l', 'l', 'o'} </Eval> <Eval> array = Char[] {'H', 'e', 'l', 'l', 'o'} </Eval>
<Eval> arrays = Char[][] {Char[] {'H', 'e', 'l', 'l', 'o'}, Char[] {'w', 'o', 'r', 'l', 'd'}} </Eval> <Eval> arrays = Char[][] {Char[] {'H', 'e', 'l', 'l', 'o'}, Char[] {'w', 'o', 'r', 'l', 'd'}} </Eval>
<Eval> array[1] = 'e' </Eval> <Eval> array[1] = 'e' </Eval>
@ -357,16 +387,6 @@ namespace Debugger.Tests {
<Eval> list = new System.Collections.Generic.List&lt;char&gt;(array2) = List`1 {'w', 'o', 'r', 'l', 'd'} </Eval> <Eval> list = new System.Collections.Generic.List&lt;char&gt;(array2) = List`1 {'w', 'o', 'r', 'l', 'd'} </Eval>
<Eval> list = List`1 {'w', 'o', 'r', 'l', 'd'} </Eval> <Eval> list = List`1 {'w', 'o', 'r', 'l', 'd'} </Eval>
<Eval> </Eval> <Eval> </Eval>
<Eval> i = 10 = 10 </Eval>
<Eval> -i = -10 </Eval>
<Eval> ++i = 11 </Eval>
<Eval> i++ = 11 </Eval>
<Eval> i = 12 </Eval>
<Eval> i += 1 = 13 </Eval>
<Eval> i = 13 </Eval>
<Eval> ~i = -14 </Eval>
<Eval> flag = True </Eval>
<Eval> !flag = False </Eval>
<Eval> </Eval> <Eval> </Eval>
<Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.ConstInt = 42 </Eval> <Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.ConstInt = 42 </Eval>
<Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.ConstString = "const string" </Eval> <Eval> Debugger.Tests.ExpressionEvaluator_Tests.DerivedClass.ConstString = "const string" </Eval>

Loading…
Cancel
Save