Skip to content

Commit 248725b

Browse files
committed
Frontend: Add support for unsigned integers
1 parent 1bd2f93 commit 248725b

File tree

2 files changed

+123
-6
lines changed

2 files changed

+123
-6
lines changed

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 119 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ namespace CastingUtil {
5858
{std::make_pair(ASR::ttypeType::Integer, ASR::ttypeType::Complex), ASR::cast_kindType::IntegerToComplex},
5959
{std::make_pair(ASR::ttypeType::Integer, ASR::ttypeType::Real), ASR::cast_kindType::IntegerToReal},
6060
{std::make_pair(ASR::ttypeType::Integer, ASR::ttypeType::Logical), ASR::cast_kindType::IntegerToLogical},
61+
{std::make_pair(ASR::ttypeType::Integer, ASR::ttypeType::UnsignedInteger), ASR::cast_kindType::IntegerToUnsignedInteger},
6162
{std::make_pair(ASR::ttypeType::Logical, ASR::ttypeType::Real), ASR::cast_kindType::LogicalToReal},
6263
{std::make_pair(ASR::ttypeType::Logical, ASR::ttypeType::Integer), ASR::cast_kindType::LogicalToInteger},
64+
{std::make_pair(ASR::ttypeType::UnsignedInteger, ASR::ttypeType::Integer), ASR::cast_kindType::UnsignedIntegerToInteger},
6365
};
6466

6567
// Data structure which contains casting rules for equal intrinsic
@@ -907,6 +909,18 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
907909
} else if (var_annotation == "i64") {
908910
type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc,
909911
8, dims.p, dims.size()));
912+
} else if (var_annotation == "u8") {
913+
type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, loc,
914+
1, dims.p, dims.size()));
915+
} else if (var_annotation == "u16") {
916+
type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, loc,
917+
2, dims.p, dims.size()));
918+
} else if (var_annotation == "u32") {
919+
type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, loc,
920+
4, dims.p, dims.size()));
921+
} else if (var_annotation == "u64") {
922+
type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, loc,
923+
8, dims.p, dims.size()));
910924
} else if (var_annotation == "f32") {
911925
type = ASRUtils::TYPE(ASR::make_Real_t(al, loc,
912926
4, dims.p, dims.size()));
@@ -1916,6 +1930,12 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
19161930
if( ASR::is_a<ASR::Const_t>(*dest_type) ) {
19171931
dest_type = ASRUtils::get_contained_type(dest_type);
19181932
}
1933+
} else if(ASRUtils::is_unsigned_integer(*left_type)
1934+
&& ASRUtils::is_unsigned_integer(*right_type)) {
1935+
dest_type = ASRUtils::expr_type(left);
1936+
if( ASR::is_a<ASR::Const_t>(*dest_type) ) {
1937+
dest_type = ASRUtils::get_contained_type(dest_type);
1938+
}
19191939
} else if ((right_is_int || left_is_int) && op == ASR::binopType::Mul) {
19201940
// string repeat
19211941
int64_t left_int = 0, right_int = 0, dest_len = 0;
@@ -2088,6 +2108,60 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
20882108

20892109
tmp = ASR::make_IntegerBinOp_t(al, loc, left, op, right, dest_type, value);
20902110

2111+
} else if (ASRUtils::is_unsigned_integer(*dest_type)) {
2112+
ASR::dimension_t *m_dims_left = nullptr, *m_dims_right = nullptr;
2113+
int n_dims_left = ASRUtils::extract_dimensions_from_ttype(left_type, m_dims_left);
2114+
int n_dims_right = ASRUtils::extract_dimensions_from_ttype(right_type, m_dims_right);
2115+
if( !(n_dims_left == 0 && n_dims_right == 0) ) {
2116+
if( n_dims_left != 0 && n_dims_right != 0 ) {
2117+
LCOMPILERS_ASSERT(n_dims_left == n_dims_right);
2118+
dest_type = left_type;
2119+
} else {
2120+
if( n_dims_left > 0 ) {
2121+
dest_type = left_type;
2122+
} else {
2123+
dest_type = right_type;
2124+
}
2125+
}
2126+
}
2127+
2128+
if (ASRUtils::expr_value(left) != nullptr && ASRUtils::expr_value(right) != nullptr) {
2129+
int64_t left_value = ASR::down_cast<ASR::UnsignedIntegerConstant_t>(
2130+
ASRUtils::expr_value(left))->m_n;
2131+
int64_t right_value = ASR::down_cast<ASR::UnsignedIntegerConstant_t>(
2132+
ASRUtils::expr_value(right))->m_n;
2133+
int64_t result;
2134+
switch (op) {
2135+
case (ASR::binopType::Add): { result = left_value + right_value; break; }
2136+
case (ASR::binopType::Sub): { result = left_value - right_value; break; }
2137+
case (ASR::binopType::Mul): { result = left_value * right_value; break; }
2138+
case (ASR::binopType::Div): { result = left_value / right_value; break; }
2139+
case (ASR::binopType::Pow): { result = std::pow(left_value, right_value); break; }
2140+
case (ASR::binopType::BitAnd): { result = left_value & right_value; break; }
2141+
case (ASR::binopType::BitOr): { result = left_value | right_value; break; }
2142+
case (ASR::binopType::BitXor): { result = left_value ^ right_value; break; }
2143+
case (ASR::binopType::BitLShift): {
2144+
if (right_value < 0) {
2145+
throw SemanticError("Negative shift count not allowed.", loc);
2146+
}
2147+
result = left_value << right_value;
2148+
break;
2149+
}
2150+
case (ASR::binopType::BitRShift): {
2151+
if (right_value < 0) {
2152+
throw SemanticError("Negative shift count not allowed.", loc);
2153+
}
2154+
result = left_value >> right_value;
2155+
break;
2156+
}
2157+
default: { LCOMPILERS_ASSERT(false); } // should never happen
2158+
}
2159+
value = ASR::down_cast<ASR::expr_t>(ASR::make_UnsignedIntegerConstant_t(
2160+
al, loc, result, dest_type));
2161+
}
2162+
2163+
tmp = ASR::make_UnsignedIntegerBinOp_t(al, loc, left, op, right, dest_type, value);
2164+
20912165
} else if (ASRUtils::is_real(*dest_type)) {
20922166

20932167
if (op == ASR::binopType::BitAnd || op == ASR::binopType::BitOr || op == ASR::binopType::BitXor ||
@@ -5464,7 +5538,6 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
54645538
dest_type = ASRUtils::get_contained_type(dest_type);
54655539
}
54665540
if (ASRUtils::is_integer(*dest_type)) {
5467-
54685541
if (ASRUtils::expr_value(left) != nullptr && ASRUtils::expr_value(right) != nullptr) {
54695542
int64_t left_value = -1;
54705543
ASRUtils::extract_value(ASRUtils::expr_value(left), left_value);
@@ -5486,9 +5559,30 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
54865559
value = ASR::down_cast<ASR::expr_t>(ASR::make_LogicalConstant_t(
54875560
al, x.base.base.loc, result, type));
54885561
}
5489-
54905562
tmp = ASR::make_IntegerCompare_t(al, x.base.base.loc, left, asr_op, right, type, value);
5491-
5563+
} else if (ASRUtils::is_unsigned_integer(*dest_type)) {
5564+
if (ASRUtils::expr_value(left) != nullptr && ASRUtils::expr_value(right) != nullptr) {
5565+
int64_t left_value = -1;
5566+
ASRUtils::extract_value(ASRUtils::expr_value(left), left_value);
5567+
int64_t right_value = -1;
5568+
ASRUtils::extract_value(ASRUtils::expr_value(right), right_value);
5569+
bool result;
5570+
switch (asr_op) {
5571+
case (ASR::cmpopType::Eq): { result = left_value == right_value; break; }
5572+
case (ASR::cmpopType::Gt): { result = left_value > right_value; break; }
5573+
case (ASR::cmpopType::GtE): { result = left_value >= right_value; break; }
5574+
case (ASR::cmpopType::Lt): { result = left_value < right_value; break; }
5575+
case (ASR::cmpopType::LtE): { result = left_value <= right_value; break; }
5576+
case (ASR::cmpopType::NotEq): { result = left_value != right_value; break; }
5577+
default: {
5578+
throw SemanticError("Comparison operator not implemented",
5579+
x.base.base.loc);
5580+
}
5581+
}
5582+
value = ASR::down_cast<ASR::expr_t>(ASR::make_LogicalConstant_t(
5583+
al, x.base.base.loc, result, type));
5584+
}
5585+
tmp = ASR::make_UnsignedIntegerCompare_t(al, x.base.base.loc, left, asr_op, right, type, value);
54925586
} else if (ASRUtils::is_real(*dest_type)) {
54935587

54945588
if (ASRUtils::expr_value(left) != nullptr && ASRUtils::expr_value(right) != nullptr) {
@@ -6742,9 +6836,20 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
67426836
tmp = ASR::make_SizeOfType_t(al, x.base.base.loc,
67436837
arg_type, size_type, nullptr);
67446838
return ;
6745-
} else if( call_name == "f64" || call_name == "f32" ||
6746-
call_name == "i64" || call_name == "i32" || call_name == "c32" ||
6747-
call_name == "c64" || call_name == "i8" || call_name == "i16" ) {
6839+
} else if(
6840+
call_name == "f64" ||
6841+
call_name == "f32" ||
6842+
call_name == "i64" ||
6843+
call_name == "i32" ||
6844+
call_name == "i16" ||
6845+
call_name == "i8" ||
6846+
call_name == "u64" ||
6847+
call_name == "u32" ||
6848+
call_name == "u16" ||
6849+
call_name == "u8" ||
6850+
call_name == "c32" ||
6851+
call_name == "c64"
6852+
) {
67486853
parse_args()
67496854
ASR::ttype_t* target_type = nullptr;
67506855
if( call_name == "i8" ) {
@@ -6755,6 +6860,14 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
67556860
target_type = ASRUtils::TYPE(ASR::make_Integer_t(al, x.base.base.loc, 4, nullptr, 0));
67566861
} else if( call_name == "i64" ) {
67576862
target_type = ASRUtils::TYPE(ASR::make_Integer_t(al, x.base.base.loc, 8, nullptr, 0));
6863+
} else if( call_name == "u8" ) {
6864+
target_type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, x.base.base.loc, 1, nullptr, 0));
6865+
} else if( call_name == "u16" ) {
6866+
target_type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, x.base.base.loc, 2, nullptr, 0));
6867+
} else if( call_name == "u32" ) {
6868+
target_type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, x.base.base.loc, 4, nullptr, 0));
6869+
} else if( call_name == "u64" ) {
6870+
target_type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, x.base.base.loc, 8, nullptr, 0));
67586871
} else if( call_name == "f32" ) {
67596872
target_type = ASRUtils::TYPE(ASR::make_Real_t(al, x.base.base.loc, 4, nullptr, 0));
67606873
} else if( call_name == "f64" ) {

src/runtime/lpython/lpython.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ def __init__(self, type, dims):
6969
i16 = Type("i16")
7070
i32 = Type("i32")
7171
i64 = Type("i64")
72+
u8 = Type("u8")
73+
u16 = Type("u16")
74+
u32 = Type("u32")
75+
u64 = Type("u64")
7276
f32 = Type("f32")
7377
f64 = Type("f64")
7478
c32 = Type("c32")

0 commit comments

Comments
 (0)