@@ -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" ) {
0 commit comments