/// <inheritdoc /> public override void VisitIntervalIntegerValue(IntegerIntervalValue value) { if (isIncrement) { if (value.End < int.MaxValue) { result = OutSet.CreateIntegerInterval(value.Start + 1, value.End + 1); } else { result = OutSet.CreateFloatInterval(TypeConversion.ToFloat(value.Start) + 1.0, TypeConversion.ToFloat(value.End) + 1.0); } } else { if (value.Start > int.MinValue) { result = OutSet.CreateIntegerInterval(value.Start - 1, value.End - 1); } else { result = OutSet.CreateFloatInterval(TypeConversion.ToFloat(value.Start) - 1.0, TypeConversion.ToFloat(value.End) - 1.0); } } }
/// <inheritdoc /> public override void VisitAnyBooleanValue(AnyBooleanValue value) { switch (operation) { case Operations.Plus: result = OutSet.CreateIntegerInterval(0, 1); break; case Operations.Minus: result = OutSet.CreateIntegerInterval(-1, 0); break; case Operations.LogicNegation: result = value; break; case Operations.BitNegation: // TODO: This must be fatal error SetWarning("Unsupported operand types: Bit negation of boolean value"); result = OutSet.AnyValue; break; default: base.VisitAnyBooleanValue(value); break; } }
/// <inheritdoc /> public override void VisitIntervalFloatValue(FloatIntervalValue value) { if (value.Start == value.End) { VisitFloatValue(OutSet.CreateDouble(value.Start)); return; } IntervalValue <int> integerInterval; switch (operation) { case Operations.Minus: result = OutSet.CreateFloatInterval(-value.End, -value.Start); break; case Operations.BitNegation: if (TypeConversion.TryConvertToIntegerInterval(OutSet, value, out integerInterval)) { result = OutSet.CreateIntegerInterval(~integerInterval.End, ~integerInterval.Start); } else { result = OutSet.AnyIntegerValue; } break; case Operations.Int32Cast: if (TypeConversion.TryConvertToIntegerInterval(OutSet, value, out integerInterval)) { result = integerInterval; } else { result = OutSet.AnyIntegerValue; } break; case Operations.FloatCast: case Operations.DoubleCast: result = value; break; default: base.VisitIntervalFloatValue(value); break; } }
/// <inheritdoc /> public override void VisitAnyBooleanValue(AnyBooleanValue value) { switch (operation) { case Operations.Equal: case Operations.NotEqual: case Operations.GreaterThanOrEqual: case Operations.LessThan: case Operations.Or: case Operations.Xor: result = value; break; case Operations.Add: case Operations.BitOr: case Operations.BitXor: result = TypeConversion.AnyBooleanToIntegerInterval(OutSet); break; case Operations.Sub: var booleanInterval = TypeConversion.AnyBooleanToIntegerInterval(OutSet); result = OutSet.CreateIntegerInterval(-booleanInterval.End, -booleanInterval.Start); break; case Operations.Mul: result = OutSet.CreateInt(0); break; case Operations.Div: SetWarning("Possible division by zero (converted from boolean false)", AnalysisWarningCause.DIVISION_BY_ZERO); // Division or modulo by false returns false boolean value result = OutSet.AnyValue; break; case Operations.Mod: result = ModuloOperation.ModuloByAnyBooleanValue(flow); break; default: base.VisitAnyBooleanValue(value); break; } }
/// <inheritdoc /> public override void VisitIntervalIntegerValue(IntegerIntervalValue value) { if (value.Start == value.End) { VisitIntegerValue(OutSet.CreateInt(value.Start)); return; } switch (operation) { case Operations.Minus: // Result of arithmetic negation can overflow if ((value.Start == 0) || ((-value.Start) != 0)) { result = OutSet.CreateIntegerInterval(-value.End, -value.Start); } else { // <seealso cref="UnaryOperationEvaluator.VisitIntegerValue" /> result = OutSet.CreateFloatInterval(-TypeConversion.ToFloat(value.End), -TypeConversion.ToFloat(value.Start)); } break; case Operations.BitNegation: result = OutSet.CreateIntegerInterval(~value.End, ~value.Start); break; case Operations.Int32Cast: result = value; break; case Operations.FloatCast: case Operations.DoubleCast: result = OutSet.CreateFloatInterval(TypeConversion.ToFloat(value.Start), TypeConversion.ToFloat(value.End)); break; default: base.VisitIntervalIntegerValue(value); break; } }