Skip to content

Commit 44892ff

Browse files
authored
Merge pull request #2081 from Shaikh-Ubaid/support_unsigned_int_unary_operators
Support unsigned int unary operators
2 parents dee5200 + 6bf590f commit 44892ff

19 files changed

+132
-16
lines changed

integration_tests/CMakeLists.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -552,12 +552,14 @@ RUN(NAME test_ConstantEllipsis LABLES cpython llvm c)
552552
RUN(NAME test_max_min LABELS cpython llvm c)
553553
RUN(NAME test_global LABELS cpython llvm c)
554554
RUN(NAME test_global_decl LABELS cpython llvm c)
555-
RUN(NAME test_integer_bitnot LABELS cpython llvm c wasm)
556-
RUN(NAME test_unsign_int_bitnot LABELS cpython llvm c)
557555
RUN(NAME test_ifexp_01 LABELS cpython llvm c)
558556
RUN(NAME test_ifexp_02 LABELS cpython llvm c)
559-
RUN(NAME test_unary_minus LABELS cpython llvm c)
560-
RUN(NAME test_unary_plus LABELS cpython llvm c)
557+
RUN(NAME test_unary_op_01 LABELS cpython llvm c) # unary minus
558+
RUN(NAME test_unary_op_02 LABELS cpython llvm c) # unary plus
559+
RUN(NAME test_unary_op_03 LABELS cpython llvm c wasm) # unary bitinvert
560+
RUN(NAME test_unary_op_04 LABELS cpython llvm c) # unary bitinvert
561+
RUN(NAME test_unary_op_05 LABELS cpython llvm c) # unsigned unary minus, plus
562+
RUN(NAME test_unary_op_06 LABELS cpython llvm c) # unsigned unary bitnot
561563
RUN(NAME test_bool_binop LABELS cpython llvm c)
562564
RUN(NAME test_issue_518 LABELS cpython llvm c NOFAST)
563565
RUN(NAME structs_01 LABELS cpython llvm c)
File renamed without changes.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from lpython import u16, u32, u64
2+
3+
def f():
4+
5+
i: u16
6+
i = u16(67)
7+
print(-i, +i, -(-i))
8+
assert -i == u16(65469)
9+
assert +i == u16(67)
10+
assert -(-i) == u16(67)
11+
12+
j: u32
13+
j = u32(25)
14+
print(-j, +j, -(-j))
15+
assert -j == u32(4294967271)
16+
assert +j == u32(25)
17+
assert -(-j) == u32(25)
18+
19+
k: u64
20+
k = u64(100000000000123)
21+
print(-k, +k, -(-k))
22+
# TODO: We are unable to store the following u64 in AST/R
23+
# assert -k == u64(18446644073709551493)
24+
assert +k == u64(100000000000123)
25+
assert -(-k) == u64(100000000000123)
26+
27+
f()
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from lpython import i32, i64, u16, u64, f32, f64
2+
3+
def f():
4+
5+
i: i32
6+
j: i64
7+
i = -67
8+
j = i64(0)
9+
10+
print(i, j)
11+
print(not i, not j)
12+
assert (not i) == False
13+
assert (not j) == True
14+
15+
k: u16
16+
l: u64
17+
k = u16(0)
18+
l = u64(55)
19+
20+
print(k, l)
21+
print(not k, not l)
22+
assert (not k) == True
23+
assert (not l) == False
24+
25+
m: f32
26+
n: f64
27+
m = f32(0.0)
28+
n = -3.14
29+
30+
print(m, n)
31+
print(not m, not n)
32+
assert (not m) == True
33+
assert (not n) == False
34+
35+
f()

src/libasr/ASR.asdl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ cast_kind
430430
| LogicalToCharacter
431431
| UnsignedIntegerToInteger
432432
| UnsignedIntegerToReal
433+
| UnsignedIntegerToLogical
433434
| IntegerToUnsignedInteger
434435
| RealToUnsignedInteger
435436
| CPtrToUnsignedInteger

src/libasr/codegen/asr_to_c_cpp.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1830,7 +1830,8 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
18301830
last_expr_precedence = 2;
18311831
break;
18321832
}
1833-
case (ASR::cast_kindType::IntegerToLogical) : {
1833+
case (ASR::cast_kindType::IntegerToLogical) :
1834+
case (ASR::cast_kindType::UnsignedIntegerToLogical) : {
18341835
src = "(bool)(" + src + ")";
18351836
last_expr_precedence = 2;
18361837
break;
@@ -2061,6 +2062,12 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
20612062
handle_UnaryMinus(x);
20622063
}
20632064

2065+
void visit_UnsignedIntegerUnaryMinus(const ASR::UnsignedIntegerUnaryMinus_t &x) {
2066+
handle_UnaryMinus(x);
2067+
int kind = ASRUtils::extract_kind_from_ttype_t(ASRUtils::expr_type(x.m_arg));
2068+
src = "(uint" + std::to_string(kind * 8) + "_t)" + src;
2069+
}
2070+
20642071
void visit_RealUnaryMinus(const ASR::RealUnaryMinus_t &x) {
20652072
handle_UnaryMinus(x);
20662073
}

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6208,6 +6208,17 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
62086208
tmp = builder->CreateSub(zero, tmp);
62096209
}
62106210

6211+
void visit_UnsignedIntegerUnaryMinus(const ASR::UnsignedIntegerUnaryMinus_t &x) {
6212+
if (x.m_value) {
6213+
this->visit_expr_wrapper(x.m_value, true);
6214+
return;
6215+
}
6216+
this->visit_expr_wrapper(x.m_arg, true);
6217+
int kind = ASRUtils::extract_kind_from_ttype_t(ASRUtils::expr_type(x.m_arg));
6218+
llvm::Value *one = llvm::ConstantInt::get(context, llvm::APInt(kind * 8, 1, true));
6219+
tmp = builder->CreateAdd(builder->CreateNot(tmp), one); // compute 2's complement
6220+
}
6221+
62116222
void visit_RealUnaryMinus(const ASR::RealUnaryMinus_t &x) {
62126223
if (x.m_value) {
62136224
this->visit_expr_wrapper(x.m_value, true);
@@ -6777,7 +6788,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
67776788
tmp = complex_from_floats(tmp, zero, complex_type);
67786789
break;
67796790
}
6780-
case (ASR::cast_kindType::IntegerToLogical) : {
6791+
case (ASR::cast_kindType::IntegerToLogical) :
6792+
case (ASR::cast_kindType::UnsignedIntegerToLogical) : {
67816793
ASR::ttype_t* curr_type = extract_ttype_t_from_expr(x.m_arg);
67826794
LCOMPILERS_ASSERT(curr_type != nullptr)
67836795
int a_kind = ASRUtils::extract_kind_from_ttype_t(curr_type);

0 commit comments

Comments
 (0)