Skip to content

Commit

Permalink
(interpreter) Make int == double use value-type semantics (#413)
Browse files Browse the repository at this point in the history
This is an important preparation for
#409, where we will use the
same semantics. Doing the change already not for interpreted mode makes
things easier, since we can then use the same tests for both interpreted
and compiled mode.
  • Loading branch information
perlun authored Oct 22, 2023
1 parent 28f6dae commit 8f6e529
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 5 deletions.
2 changes: 2 additions & 0 deletions release-notes/v0.4.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
- Remove Moq dependency [[#380][380]]

### Fixed
- Make `int == double` use value-type semantics [[#413][413]]

### Tests
- Minor test improvements [[#410][410]]
Expand All @@ -39,3 +40,4 @@
[407]: https://github.com/perlang-org/perlang/pull/407
[410]: https://github.com/perlang-org/perlang/pull/410
[412]: https://github.com/perlang-org/perlang/pull/412
[413]: https://github.com/perlang-org/perlang/pull/413
16 changes: 15 additions & 1 deletion src/Perlang.Interpreter/PerlangInterpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Numerics;
using System.Reflection;
using System.Text;
using Microsoft.CSharp.RuntimeBinder;
using Perlang.Attributes;
using Perlang.Exceptions;
using Perlang.Internal.Extensions;
Expand Down Expand Up @@ -948,10 +949,23 @@ private static bool IsEqual(object? a, object? b)

if (a == null)
{
// null != non-null
return false;
}

return a.Equals(b);
// Note: must use dynamic here since `object == object` behaves differently than e.g. `int == double`,
// tragically enough. More details:
// https://learn.microsoft.com/en-us/dotnet/api/System.Object.Equals?view=net-7.0#notes-for-callers
try
{
return (dynamic)a == (dynamic?)b;
}
catch (RuntimeBinderException)
{
// This will happen when trying to compare e.g `double == BigInteger`. We fall back to Equals() in this
// case, hoping that it will make sense...
return a.Equals(b);
}
}

public object? VisitGroupingExpr(Expr.Grouping expr)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ public static class BinaryOperatorData
{
new object[] { "12", "34", "True" },
new object[] { "12", "12", "False" },
new object[] { "12", "12.0", "True" }, // Same value but different types. Note: this is truthy in C# AND Java.
new object[] { "12.0", "12", "True" }, // Same value but different types. Note: this is truthy in C# AND Java.
new object[] { "12", "12.0", "False" }, // Same value but different types. We follow the precedent of C#, Java and C++ and consider these to be equal.
new object[] { "12.0", "12", "False" }, // Likewise

new object[] { "2147483647", "4294967295", "True" },
new object[] { "2147483647", "9223372036854775807", "True" },
Expand Down Expand Up @@ -341,8 +341,8 @@ public static class BinaryOperatorData
{
new object[] { "12", "34", "False" },
new object[] { "12", "12", "True" },
new object[] { "12", "12.0", "False" }, // Same value but different types. Note: this is truthy in C# AND Java.
new object[] { "12.0", "12", "False" }, // Same value but different types. Note: this is truthy in C# AND Java.
new object[] { "12", "12.0", "True" }, // Same value but different types. We follow the precedent of C#, Java and C++ and consider these to be equal.
new object[] { "12.0", "12", "True" }, // Likewise
new object[] { "12.345", "12.345", "True" },
new object[] { "12.345", "67.890", "False" },

Expand Down

0 comments on commit 8f6e529

Please sign in to comment.