diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index b3ab956052..d6db445b29 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -311,6 +311,7 @@ RUN(NAME const_03 LABELS cpython llvm c EXTRAFILES const_03b.c) RUN(NAME const_04 LABELS cpython llvm c) RUN(NAME expr_01 LABELS cpython llvm c wasm wasm_x64) +RUN(NAME expr_01u LABELS cpython llvm) RUN(NAME expr_02 LABELS cpython llvm c wasm wasm_x64) RUN(NAME expr_03 LABELS cpython llvm c wasm wasm_x64) RUN(NAME expr_04 LABELS cpython llvm c wasm) diff --git a/integration_tests/expr_01u.py b/integration_tests/expr_01u.py new file mode 100644 index 0000000000..169f684d60 --- /dev/null +++ b/integration_tests/expr_01u.py @@ -0,0 +1,28 @@ +from lpython import inline, u32 + +@inline +def uadd(x: u32, y: u32) -> u32: + return x + y + +@inline +def uand_op(x: u32, y: u32) -> u32: + return x & y + +def main1(): + x: u32 + y: u32 + z: u32 + x = (u32(2)+u32(3))*u32(5) + y = uadd(x, u32(2))*u32(2) + assert x == u32(25) + assert y == u32(54) + + z = uand_op(x, y) + assert z == u32(16) + + +main1() + +# Not implemented yet in LPython: +#if __name__ == "__main__": +# main() diff --git a/src/libasr/ASR.asdl b/src/libasr/ASR.asdl index 12ada08a10..c763448193 100644 --- a/src/libasr/ASR.asdl +++ b/src/libasr/ASR.asdl @@ -237,6 +237,10 @@ expr | IntegerUnaryMinus(expr arg, ttype type, expr? value) | IntegerCompare(expr left, cmpop op, expr right, ttype type, expr? value) | IntegerBinOp(expr left, binop op, expr right, ttype type, expr? value) + | UnsignedIntegerConstant(int n, ttype type) + | UnsignedIntegerUnaryMinus(expr arg, ttype type, expr? value) + | UnsignedIntegerCompare(expr left, cmpop op, expr right, ttype type, expr? value) + | UnsignedIntegerBinOp(expr left, binop op, expr right, ttype type, expr? value) | RealConstant(float r, ttype type) | RealUnaryMinus(expr arg, ttype type, expr? value) | RealCompare(expr left, cmpop op, expr right, ttype type, expr? value) @@ -346,6 +350,7 @@ expr ttype = Integer(int kind, dimension* dims) + | UnsignedInteger(int kind, dimension* dims) | Real(int kind, dimension* dims) | Complex(int kind, dimension* dims) | Character(int kind, int len, expr? len_expr, dimension* dims) @@ -402,6 +407,8 @@ cast_kind | RealToCharacter | IntegerToCharacter | LogicalToCharacter + | UnsignedIntegerToInteger + | IntegerToUnsignedInteger dimension = (expr? start, expr? length) diff --git a/src/libasr/asr_utils.cpp b/src/libasr/asr_utils.cpp index 96b9b34ebb..cd77523da5 100644 --- a/src/libasr/asr_utils.cpp +++ b/src/libasr/asr_utils.cpp @@ -974,6 +974,10 @@ ASR::asr_t* make_Cast_t_value(Allocator &al, const Location &a_loc, int64_t int_value = ASR::down_cast( ASRUtils::expr_value(a_arg))->m_n; value = ASR::down_cast(ASR::make_IntegerConstant_t(al, a_loc, int_value, a_type)); + } else if (a_kind == ASR::cast_kindType::IntegerToUnsignedInteger) { + int64_t int_value = ASR::down_cast( + ASRUtils::expr_value(a_arg))->m_n; + value = ASR::down_cast(ASR::make_UnsignedIntegerConstant_t(al, a_loc, int_value, a_type)); } else if (a_kind == ASR::cast_kindType::IntegerToLogical) { // TODO: implement } else if (a_kind == ASR::cast_kindType::ComplexToComplex) { diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index f04f918fc5..93eaebb6c3 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -842,6 +842,11 @@ static inline bool extract_value(ASR::expr_t* value_expr, T& value) { value = (T) const_int->m_n; break; } + case ASR::exprType::UnsignedIntegerConstant: { + ASR::UnsignedIntegerConstant_t* const_int = ASR::down_cast(value_expr); + value = (T) const_int->m_n; + break; + } case ASR::exprType::RealConstant: { ASR::RealConstant_t* const_real = ASR::down_cast(value_expr); value = (T) const_real->m_r; @@ -924,6 +929,16 @@ static inline std::string get_type_code(const ASR::ttype_t *t, bool use_undersco is_dimensional = integer->n_dims > 0; break; } + case ASR::ttypeType::UnsignedInteger: { + ASR::UnsignedInteger_t *integer = ASR::down_cast(t); + res = "u" + std::to_string(integer->m_kind * 8); + if( encode_dimensions_ ) { + encode_dimensions(integer->n_dims, res, use_underscore_sep); + return res; + } + is_dimensional = integer->n_dims > 0; + break; + } case ASR::ttypeType::Real: { ASR::Real_t *real = ASR::down_cast(t); res = "r" + std::to_string(real->m_kind * 8); @@ -1090,7 +1105,7 @@ static inline std::string type_to_str_python(const ASR::ttype_t *t, { switch (t->type) { case ASR::ttypeType::Integer: { - ASR::Integer_t *i = (ASR::Integer_t*)t; + ASR::Integer_t *i = ASR::down_cast(t); std::string res = ""; switch (i->m_kind) { case 1: { res = "i8"; break; } @@ -1104,6 +1119,21 @@ static inline std::string type_to_str_python(const ASR::ttype_t *t, } return res; } + case ASR::ttypeType::UnsignedInteger: { + ASR::UnsignedInteger_t *i = ASR::down_cast(t); + std::string res = ""; + switch (i->m_kind) { + case 1: { res = "u8"; break; } + case 2: { res = "u16"; break; } + case 4: { res = "u32"; break; } + case 8: { res = "u64"; break; } + default: { throw LCompilersException("UnsignedInteger kind not supported"); } + } + if (i->n_dims == 1 && for_error_message) { + res = type_python_1dim_helper(res, i->m_dims); + } + return res; + } case ASR::ttypeType::Real: { ASR::Real_t *r = (ASR::Real_t*)t; std::string res = ""; @@ -1374,6 +1404,9 @@ static inline int extract_kind_from_ttype_t(const ASR::ttype_t* type) { case ASR::ttypeType::Integer : { return ASR::down_cast(type)->m_kind; } + case ASR::ttypeType::UnsignedInteger : { + return ASR::down_cast(type)->m_kind; + } case ASR::ttypeType::Real : { return ASR::down_cast(type)->m_kind; } @@ -1406,6 +1439,10 @@ static inline bool is_integer(ASR::ttype_t &x) { return ASR::is_a(*type_get_past_pointer(&x)); } +static inline bool is_unsigned_integer(ASR::ttype_t &x) { + return ASR::is_a(*type_get_past_pointer(&x)); +} + static inline bool is_real(ASR::ttype_t &x) { return ASR::is_a(*type_get_past_pointer(&x)); } @@ -1485,6 +1522,12 @@ inline int extract_dimensions_from_ttype(ASR::ttype_t *x, m_dims = Integer_type->m_dims; break; } + case ASR::ttypeType::UnsignedInteger: { + ASR::UnsignedInteger_t* Integer_type = ASR::down_cast(x); + n_dims = Integer_type->n_dims; + m_dims = Integer_type->m_dims; + break; + } case ASR::ttypeType::Real: { ASR::Real_t* Real_type = ASR::down_cast(x); n_dims = Real_type->n_dims; @@ -2122,6 +2165,22 @@ inline bool types_equal(ASR::ttype_t *a, ASR::ttype_t *b, } break; } + case (ASR::ttypeType::UnsignedInteger) : { + ASR::UnsignedInteger_t *a2 = ASR::down_cast(a); + ASR::UnsignedInteger_t *b2 = ASR::down_cast(b); + if (a2->m_kind == b2->m_kind) { + if( check_for_dimensions ) { + return ASRUtils::dimensions_equal( + a2->m_dims, a2->n_dims, + b2->m_dims, b2->n_dims); + } else { + return true; + } + } else { + return false; + } + break; + } case ASR::ttypeType::CPtr: { return true; } diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 6adb70dbc5..ae7d1d4c2d 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -2867,6 +2867,36 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } break; } + case (ASR::ttypeType::UnsignedInteger) : { + ASR::UnsignedInteger_t* v_type = down_cast(asr_type); + m_dims = v_type->m_dims; + n_dims = v_type->n_dims; + a_kind = v_type->m_kind; + if( n_dims > 0 ) { + if( m_abi == ASR::abiType::BindC ) { + if( ASRUtils::is_fixed_size_array(v_type->m_dims, v_type->n_dims) ) { + llvm_type = llvm::ArrayType::get(get_el_type(asr_type), ASRUtils::get_fixed_size_of_array( + v_type->m_dims, v_type->n_dims)); + } else { + llvm_type = get_el_type(asr_type)->getPointerTo(); + } + } else { + is_array_type = true; + llvm::Type* el_type = get_el_type(asr_type); + if( m_storage == ASR::storage_typeType::Allocatable ) { + is_malloc_array_type = true; + llvm_type = arr_descr->get_malloc_array_type(asr_type, el_type); + } else { + llvm_type = arr_descr->get_array_type(asr_type, el_type); + } + } + } else { + // LLVM does not distinguish signed and unsigned integer types + // Only integer operations can be signed/unsigned + llvm_type = getIntType(a_kind); + } + break; + } case (ASR::ttypeType::Real) : { ASR::Real_t* v_type = down_cast(asr_type); m_dims = v_type->m_dims; @@ -3459,6 +3489,34 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } break; } + case (ASR::ttypeType::UnsignedInteger) : { + ASR::UnsignedInteger_t* v_type = down_cast(asr_type); + n_dims = v_type->n_dims; + a_kind = v_type->m_kind; + if( n_dims > 0 ) { + if (m_abi == ASR::abiType::BindC || + (!ASRUtils::is_dimension_empty(v_type->m_dims, v_type->n_dims))) { + // Bind(C) arrays are represened as a pointer + type = getIntType(a_kind, true); + } else { + is_array_type = true; + llvm::Type* el_type = get_el_type(asr_type); + if( m_storage == ASR::storage_typeType::Allocatable ) { + type = arr_descr->get_malloc_array_type(asr_type, el_type, get_pointer); + } else { + type = arr_descr->get_array_type(asr_type, el_type, get_pointer); + } + } + } else { + if (arg_m_abi == ASR::abiType::BindC + && arg_m_value_attr) { + type = getIntType(a_kind, false); + } else { + type = getIntType(a_kind, true); + } + } + break; + } case (ASR::ttypeType::Pointer) : { ASR::ttype_t *t2 = ASRUtils::type_get_past_pointer(asr_type); bool is_pointer_ = ASR::is_a(*t2); @@ -3904,6 +3962,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor return_type = getIntType(a_kind); break; } + case (ASR::ttypeType::UnsignedInteger) : { + int a_kind = down_cast(return_var_type0)->m_kind; + return_type = getIntType(a_kind); + break; + } case (ASR::ttypeType::Real) : { int a_kind = down_cast(return_var_type0)->m_kind; return_type = getFPType(a_kind); @@ -5019,6 +5082,47 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } } + void visit_UnsignedIntegerCompare(const ASR::UnsignedIntegerCompare_t &x) { + if (x.m_value) { + this->visit_expr_wrapper(x.m_value, true); + return; + } + this->visit_expr_wrapper(x.m_left, true); + llvm::Value *left = tmp; + this->visit_expr_wrapper(x.m_right, true); + llvm::Value *right = tmp; + switch (x.m_op) { + case (ASR::cmpopType::Eq) : { + tmp = builder->CreateICmpEQ(left, right); + break; + } + case (ASR::cmpopType::Gt) : { + tmp = builder->CreateICmpUGT(left, right); + break; + } + case (ASR::cmpopType::GtE) : { + tmp = builder->CreateICmpUGE(left, right); + break; + } + case (ASR::cmpopType::Lt) : { + tmp = builder->CreateICmpULT(left, right); + break; + } + case (ASR::cmpopType::LtE) : { + tmp = builder->CreateICmpULE(left, right); + break; + } + case (ASR::cmpopType::NotEq) : { + tmp = builder->CreateICmpNE(left, right); + break; + } + default : { + throw CodeGenError("Comparison operator not implemented", + x.base.base.loc); + } + } + } + void visit_RealCompare(const ASR::RealCompare_t &x) { if (x.m_value) { this->visit_expr_wrapper(x.m_value, true); @@ -5498,7 +5602,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor tmp = lfortran_str_slice(str, left, right, step, left_present, right_present); } - void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { + template + void handle_SU_IntegerBinOp(const T &x) { if (x.m_value) { this->visit_expr_wrapper(x.m_value, true); return; @@ -5507,7 +5612,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::Value *left_val = tmp; this->visit_expr_wrapper(x.m_right, true); llvm::Value *right_val = tmp; - LCOMPILERS_ASSERT(ASRUtils::is_integer(*x.m_type)) + LCOMPILERS_ASSERT(ASRUtils::is_integer(*x.m_type) || + ASRUtils::is_unsigned_integer(*x.m_type)) switch (x.m_op) { case ASR::binopType::Add: { tmp = builder->CreateAdd(left_val, right_val); @@ -5571,6 +5677,14 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } } + void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { + handle_SU_IntegerBinOp(x); + } + + void visit_UnsignedIntegerBinOp(const ASR::UnsignedIntegerBinOp_t &x) { + handle_SU_IntegerBinOp(x); + } + void visit_RealBinOp(const ASR::RealBinOp_t &x) { if (x.m_value) { this->visit_expr_wrapper(x.m_value, true); @@ -5776,11 +5890,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor tmp = lfortran_complex_bin_op(zero_c, c, f_name, type); } - void visit_IntegerConstant(const ASR::IntegerConstant_t &x) { + template + void handle_SU_IntegerConstant(const T &x) { int64_t val = x.m_n; int a_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); switch( a_kind ) { - case 1: { tmp = llvm::ConstantInt::get(context, llvm::APInt(8, val, true)); break ; @@ -5805,6 +5919,14 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } } + void visit_IntegerConstant(const ASR::IntegerConstant_t &x) { + handle_SU_IntegerConstant(x); + } + + void visit_UnsignedIntegerConstant(const ASR::UnsignedIntegerConstant_t &x) { + handle_SU_IntegerConstant(x); + } + void visit_RealConstant(const ASR::RealConstant_t &x) { double val = x.m_r; int a_kind = ((ASR::Real_t*)(&(x.m_type->base)))->m_kind; @@ -6385,6 +6507,24 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } break; } + case (ASR::cast_kindType::IntegerToUnsignedInteger) : { + int arg_kind = -1, dest_kind = -1; + extract_kinds(x, arg_kind, dest_kind); + if( arg_kind > 0 && dest_kind > 0 && + arg_kind != dest_kind ) + { + if (dest_kind > arg_kind) { + tmp = builder->CreateSExt(tmp, getIntType(dest_kind)); + } else { + tmp = builder->CreateTrunc(tmp, getIntType(dest_kind)); + } + } + break; + } + case (ASR::cast_kindType::UnsignedIntegerToInteger) : { + // tmp = tmp + break; + } case (ASR::cast_kindType::ComplexToComplex) : { llvm::Type *target_type; int arg_kind = -1, dest_kind = -1; @@ -6698,6 +6838,31 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } } args.push_back(tmp); + } else if (ASRUtils::is_unsigned_integer(*t)) { + switch( a_kind ) { + case 1 : { + fmt.push_back("%hhi"); + break; + } + case 2 : { + fmt.push_back("%hi"); + break; + } + case 4 : { + fmt.push_back("%d"); + break; + } + case 8 : { + fmt.push_back("%lld"); + break; + } + default: { + throw CodeGenError(R"""(Printing support is available only + for 8, 16, 32, and 64 bit unsigned integer kinds.)""", + x.base.base.loc); + } + } + args.push_back(tmp); } else if (ASRUtils::is_real(*t)) { llvm::Value *d; switch( a_kind ) { @@ -7093,6 +7258,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor target_type = getIntType(a_kind); break; } + case (ASR::ttypeType::UnsignedInteger) : { + int a_kind = down_cast(arg_type)->m_kind; + target_type = getIntType(a_kind); + break; + } case (ASR::ttypeType::Real) : { int a_kind = down_cast(arg_type)->m_kind; target_type = getFPType(a_kind); diff --git a/src/libasr/pass/inline_function_calls.cpp b/src/libasr/pass/inline_function_calls.cpp index a013f3894d..ef7d2f9ad4 100644 --- a/src/libasr/pass/inline_function_calls.cpp +++ b/src/libasr/pass/inline_function_calls.cpp @@ -425,6 +425,10 @@ class InlineFunctionCallVisitor : public PassUtils::PassVisitor { } else if (var_annotation == "i64") { type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 8, dims.p, dims.size())); + } else if (var_annotation == "u8") { + type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, loc, + 1, dims.p, dims.size())); + } else if (var_annotation == "u16") { + type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, loc, + 2, dims.p, dims.size())); + } else if (var_annotation == "u32") { + type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, loc, + 4, dims.p, dims.size())); + } else if (var_annotation == "u64") { + type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, loc, + 8, dims.p, dims.size())); } else if (var_annotation == "f32") { type = ASRUtils::TYPE(ASR::make_Real_t(al, loc, 4, dims.p, dims.size())); @@ -1916,6 +1930,12 @@ class CommonVisitor : public AST::BaseVisitor { if( ASR::is_a(*dest_type) ) { dest_type = ASRUtils::get_contained_type(dest_type); } + } else if(ASRUtils::is_unsigned_integer(*left_type) + && ASRUtils::is_unsigned_integer(*right_type)) { + dest_type = ASRUtils::expr_type(left); + if( ASR::is_a(*dest_type) ) { + dest_type = ASRUtils::get_contained_type(dest_type); + } } else if ((right_is_int || left_is_int) && op == ASR::binopType::Mul) { // string repeat int64_t left_int = 0, right_int = 0, dest_len = 0; @@ -2088,6 +2108,60 @@ class CommonVisitor : public AST::BaseVisitor { tmp = ASR::make_IntegerBinOp_t(al, loc, left, op, right, dest_type, value); + } else if (ASRUtils::is_unsigned_integer(*dest_type)) { + ASR::dimension_t *m_dims_left = nullptr, *m_dims_right = nullptr; + int n_dims_left = ASRUtils::extract_dimensions_from_ttype(left_type, m_dims_left); + int n_dims_right = ASRUtils::extract_dimensions_from_ttype(right_type, m_dims_right); + if( !(n_dims_left == 0 && n_dims_right == 0) ) { + if( n_dims_left != 0 && n_dims_right != 0 ) { + LCOMPILERS_ASSERT(n_dims_left == n_dims_right); + dest_type = left_type; + } else { + if( n_dims_left > 0 ) { + dest_type = left_type; + } else { + dest_type = right_type; + } + } + } + + if (ASRUtils::expr_value(left) != nullptr && ASRUtils::expr_value(right) != nullptr) { + int64_t left_value = ASR::down_cast( + ASRUtils::expr_value(left))->m_n; + int64_t right_value = ASR::down_cast( + ASRUtils::expr_value(right))->m_n; + int64_t result; + switch (op) { + case (ASR::binopType::Add): { result = left_value + right_value; break; } + case (ASR::binopType::Sub): { result = left_value - right_value; break; } + case (ASR::binopType::Mul): { result = left_value * right_value; break; } + case (ASR::binopType::Div): { result = left_value / right_value; break; } + case (ASR::binopType::Pow): { result = std::pow(left_value, right_value); break; } + case (ASR::binopType::BitAnd): { result = left_value & right_value; break; } + case (ASR::binopType::BitOr): { result = left_value | right_value; break; } + case (ASR::binopType::BitXor): { result = left_value ^ right_value; break; } + case (ASR::binopType::BitLShift): { + if (right_value < 0) { + throw SemanticError("Negative shift count not allowed.", loc); + } + result = left_value << right_value; + break; + } + case (ASR::binopType::BitRShift): { + if (right_value < 0) { + throw SemanticError("Negative shift count not allowed.", loc); + } + result = left_value >> right_value; + break; + } + default: { LCOMPILERS_ASSERT(false); } // should never happen + } + value = ASR::down_cast(ASR::make_UnsignedIntegerConstant_t( + al, loc, result, dest_type)); + } + + tmp = ASR::make_UnsignedIntegerBinOp_t(al, loc, left, op, right, dest_type, value); + } else if (ASRUtils::is_real(*dest_type)) { if (op == ASR::binopType::BitAnd || op == ASR::binopType::BitOr || op == ASR::binopType::BitXor || @@ -5464,7 +5538,6 @@ class BodyVisitor : public CommonVisitor { dest_type = ASRUtils::get_contained_type(dest_type); } if (ASRUtils::is_integer(*dest_type)) { - if (ASRUtils::expr_value(left) != nullptr && ASRUtils::expr_value(right) != nullptr) { int64_t left_value = -1; ASRUtils::extract_value(ASRUtils::expr_value(left), left_value); @@ -5486,9 +5559,30 @@ class BodyVisitor : public CommonVisitor { value = ASR::down_cast(ASR::make_LogicalConstant_t( al, x.base.base.loc, result, type)); } - tmp = ASR::make_IntegerCompare_t(al, x.base.base.loc, left, asr_op, right, type, value); - + } else if (ASRUtils::is_unsigned_integer(*dest_type)) { + if (ASRUtils::expr_value(left) != nullptr && ASRUtils::expr_value(right) != nullptr) { + int64_t left_value = -1; + ASRUtils::extract_value(ASRUtils::expr_value(left), left_value); + int64_t right_value = -1; + ASRUtils::extract_value(ASRUtils::expr_value(right), right_value); + bool result; + switch (asr_op) { + case (ASR::cmpopType::Eq): { result = left_value == right_value; break; } + case (ASR::cmpopType::Gt): { result = left_value > right_value; break; } + case (ASR::cmpopType::GtE): { result = left_value >= right_value; break; } + case (ASR::cmpopType::Lt): { result = left_value < right_value; break; } + case (ASR::cmpopType::LtE): { result = left_value <= right_value; break; } + case (ASR::cmpopType::NotEq): { result = left_value != right_value; break; } + default: { + throw SemanticError("Comparison operator not implemented", + x.base.base.loc); + } + } + value = ASR::down_cast(ASR::make_LogicalConstant_t( + al, x.base.base.loc, result, type)); + } + tmp = ASR::make_UnsignedIntegerCompare_t(al, x.base.base.loc, left, asr_op, right, type, value); } else if (ASRUtils::is_real(*dest_type)) { if (ASRUtils::expr_value(left) != nullptr && ASRUtils::expr_value(right) != nullptr) { @@ -6742,9 +6836,20 @@ class BodyVisitor : public CommonVisitor { tmp = ASR::make_SizeOfType_t(al, x.base.base.loc, arg_type, size_type, nullptr); return ; - } else if( call_name == "f64" || call_name == "f32" || - call_name == "i64" || call_name == "i32" || call_name == "c32" || - call_name == "c64" || call_name == "i8" || call_name == "i16" ) { + } else if( + call_name == "f64" || + call_name == "f32" || + call_name == "i64" || + call_name == "i32" || + call_name == "i16" || + call_name == "i8" || + call_name == "u64" || + call_name == "u32" || + call_name == "u16" || + call_name == "u8" || + call_name == "c32" || + call_name == "c64" + ) { parse_args() ASR::ttype_t* target_type = nullptr; if( call_name == "i8" ) { @@ -6755,6 +6860,14 @@ class BodyVisitor : public CommonVisitor { target_type = ASRUtils::TYPE(ASR::make_Integer_t(al, x.base.base.loc, 4, nullptr, 0)); } else if( call_name == "i64" ) { target_type = ASRUtils::TYPE(ASR::make_Integer_t(al, x.base.base.loc, 8, nullptr, 0)); + } else if( call_name == "u8" ) { + target_type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, x.base.base.loc, 1, nullptr, 0)); + } else if( call_name == "u16" ) { + target_type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, x.base.base.loc, 2, nullptr, 0)); + } else if( call_name == "u32" ) { + target_type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, x.base.base.loc, 4, nullptr, 0)); + } else if( call_name == "u64" ) { + target_type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, x.base.base.loc, 8, nullptr, 0)); } else if( call_name == "f32" ) { target_type = ASRUtils::TYPE(ASR::make_Real_t(al, x.base.base.loc, 4, nullptr, 0)); } else if( call_name == "f64" ) { diff --git a/src/runtime/lpython/lpython.py b/src/runtime/lpython/lpython.py index 1456b4b4b5..0b43d3c2c0 100644 --- a/src/runtime/lpython/lpython.py +++ b/src/runtime/lpython/lpython.py @@ -6,7 +6,7 @@ from goto import with_goto # TODO: this does not seem to restrict other imports -__slots__ = ["i8", "i16", "i32", "i64", "f32", "f64", "c32", "c64", "CPtr", +__slots__ = ["i8", "i16", "i32", "i64", "u8", "u16", "u32", "u64", "f32", "f64", "c32", "c64", "CPtr", "overload", "ccall", "TypeVar", "pointer", "c_p_pointer", "Pointer", "p_c_pointer", "vectorize", "inline", "Union", "static", "with_goto", "packed", "Const", "sizeof", "ccallable", "ccallback", "Callable"] @@ -18,6 +18,10 @@ "i16": int, "i32": int, "i64": int, + "u8": lambda x: x, + "u16": lambda x: x, + "u32": lambda x: x, + "u64": lambda x: x, "f32": float, "f64": float, "c32": complex, @@ -65,6 +69,10 @@ def __init__(self, type, dims): i16 = Type("i16") i32 = Type("i32") i64 = Type("i64") +u8 = Type("u8") +u16 = Type("u16") +u32 = Type("u32") +u64 = Type("u64") f32 = Type("f32") f64 = Type("f64") c32 = Type("c32")