Description
Currently we created our own class UnsignedInteger and we provide a CPython incompatible behavior of some operators such as ~. Rather, if we need a CPython incompatible behavior, we should introduce some special functions, such as from lpython import uneg
. The intrinsic operators should work just like in CPython.
Here is an example:
print(u16(0xff), 0xff)
print(~u16(0xff), ~0xff)
This currently prints:
255 255
65280 -256
So the ~
is behaving differently for u16 and Python ints. It should not. The design of u16 and i16 is that they are strict value restricted subset of Python ints and should behave exactly identical on this subset, and LPython should give compile time or runtime error messages if any operation is performed outside of this subset.
Since in CPython ~255 becomes -256, then the same behavior must happen on ~u16(255). In order to provide the other operation, we can make uneg(255)
be 65280. Then the operation can be correctly implemented in emulation mode, and all unsigned integers can be just integers, which will speedup operation and remove many bugs that we currently have, when we are passing UnsignedInteger somewhere where a regular integer is expected.
I think the current behavior was introduced by trying to emulate C, but Python is not C. We need to be compatible with Python, not C. If C behavior is desired, it must be done using functions like uneg
, not using intrinsic integer operators (which should rather behave like CPython does).