Skip to content

Commit 851f878

Browse files
authored
Merge pull request #2152 from Shaikh-Ubaid/unsigned_bit_operators
Support unsigned bitshift operators
2 parents 32f7ec9 + 05ff79a commit 851f878

File tree

4 files changed

+52
-0
lines changed

4 files changed

+52
-0
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,7 @@ RUN(NAME test_unary_op_03 LABELS cpython llvm c wasm) # unary bitinvert
566566
RUN(NAME test_unary_op_04 LABELS cpython llvm c) # unary bitinvert
567567
RUN(NAME test_unary_op_05 LABELS cpython llvm c) # unsigned unary minus, plus
568568
RUN(NAME test_unary_op_06 LABELS cpython llvm c) # unsigned unary bitnot
569+
RUN(NAME test_unsigned_01 LABELS cpython llvm c) # unsigned bitshift left, right
569570
RUN(NAME test_bool_binop LABELS cpython llvm c)
570571
RUN(NAME test_issue_518 LABELS cpython llvm c NOFAST)
571572
RUN(NAME structs_01 LABELS cpython llvm c)

integration_tests/test_unsigned_01.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from lpython import u8, u16, u32, u64
2+
3+
def f():
4+
5+
h: u8
6+
h = u8(5)
7+
print(h << u8(4), h << u8(7), h >> u8(4), h >> u8(7))
8+
assert h << u8(4) == u8(80)
9+
assert h << u8(7) == u8(128)
10+
assert h >> u8(4) == u8(0)
11+
assert h >> u8(7) == u8(0)
12+
13+
i: u16
14+
i = u16(67)
15+
print(i << u16(4), i << u16(7), i >> u16(4), i >> u16(7))
16+
assert i << u16(4) == u16(1072)
17+
assert i << u16(7) == u16(8576)
18+
assert i >> u16(4) == u16(4)
19+
assert i >> u16(7) == u16(0)
20+
21+
j: u32
22+
j = u32(25)
23+
print(j << u32(4), j << u32(7), j >> u32(4), j >> u32(7))
24+
assert j << u32(4) == u32(400)
25+
assert j << u32(7) == u32(3200)
26+
assert j >> u32(4) == u32(1)
27+
assert j >> u32(7) == u32(0)
28+
29+
k: u64
30+
k = u64(100000000000123)
31+
print(k << u64(4), k << u64(7), k >> u64(4), k >> u64(7))
32+
assert k << u64(4) == u64(1600000000001968)
33+
assert k << u64(7) == u64(12800000000015744)
34+
assert k >> u64(4) == u64(6250000000007)
35+
assert k >> u64(7) == u64(781250000000)
36+
37+
f()

src/libasr/codegen/asr_to_c_cpp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2190,6 +2190,8 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
21902190

21912191
void visit_UnsignedIntegerBinOp(const ASR::UnsignedIntegerBinOp_t &x) {
21922192
handle_BinOp(x);
2193+
int kind = ASRUtils::extract_kind_from_ttype_t(x.m_type);
2194+
src = "(uint" + std::to_string(kind * 8) + "_t)(" + src + ")";
21932195
}
21942196

21952197
void visit_RealBinOp(const ASR::RealBinOp_t &x) {

src/runtime/lpython/lpython.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,18 @@ def __ge__(self, other):
139139
else:
140140
raise TypeError("Unsupported operand type")
141141

142+
def __lshift__(self, other):
143+
if isinstance(other, self.__class__):
144+
return UnsignedInteger(self.bit_width, self.value << other.value)
145+
else:
146+
raise TypeError("Unsupported operand type")
147+
148+
def __rshift__(self, other):
149+
if isinstance(other, self.__class__):
150+
return UnsignedInteger(self.bit_width, self.value >> other.value)
151+
else:
152+
raise TypeError("Unsupported operand type")
153+
142154
# conversion to integer
143155
def __int__(self):
144156
return self.value

0 commit comments

Comments
 (0)