diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index d05382962f..c9e12e97a6 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -445,6 +445,7 @@ RUN(NAME expr_17 LABELS cpython llvm c) RUN(NAME expr_18 FAIL LABELS cpython llvm c) RUN(NAME expr_19 LABELS cpython llvm c) RUN(NAME expr_20 LABELS cpython llvm c) +RUN(NAME expr_21 LABELS cpython llvm c) RUN(NAME expr_01u LABELS cpython llvm c NOFAST) RUN(NAME expr_02u LABELS cpython llvm c NOFAST) diff --git a/integration_tests/expr_21.py b/integration_tests/expr_21.py new file mode 100644 index 0000000000..e07693c580 --- /dev/null +++ b/integration_tests/expr_21.py @@ -0,0 +1,21 @@ +from lpython import i8, i16, i32, i64 + +def main0(): + x: i8 + y: i16 + z: i32 + w: i64 + + x = i8(97) + y = i16(47) + z = 56 + w = i64(67) + + print(chr(x), chr(y), chr(z), chr(w)) + + assert chr(x) == 'a' + assert chr(y) == '/' + assert chr(z) == '8' + assert chr(w) == 'C' + +main0() diff --git a/src/libasr/runtime/lfortran_intrinsics.c b/src/libasr/runtime/lfortran_intrinsics.c index d7a4f8f7b5..bad119b03e 100644 --- a/src/libasr/runtime/lfortran_intrinsics.c +++ b/src/libasr/runtime/lfortran_intrinsics.c @@ -1340,7 +1340,8 @@ LFORTRAN_API int _lfortran_str_ord_c(char* s) LFORTRAN_API char* _lfortran_str_chr(int val) { char* dest_char = (char*)malloc(2); - dest_char[0] = val; + uint8_t extended_ascii = (uint8_t)val; + dest_char[0] = extended_ascii; dest_char[1] = '\0'; return dest_char; } diff --git a/src/lpython/semantics/python_intrinsic_eval.h b/src/lpython/semantics/python_intrinsic_eval.h index 5b7b771ffb..2a069dd19e 100644 --- a/src/lpython/semantics/python_intrinsic_eval.h +++ b/src/lpython/semantics/python_intrinsic_eval.h @@ -448,15 +448,20 @@ struct IntrinsicNodeHandler { if (ASRUtils::is_integer(*type)) { if (ASRUtils::expr_value(arg) != nullptr) { int64_t c = ASR::down_cast(arg)->m_n; - if (! (c >= 0 && c <= 127) ) { - throw SemanticError("The argument 'x' in chr(x) must be in the range 0 <= x <= 127.", loc); + c = (uint8_t) c; + if (! (c >= 0 && c <= 255) ) { + throw SemanticError("The argument 'x' in chr(x) must be in the range 0 <= x <= 255.", loc); } - char cc = c; std::string svalue; - svalue += cc; + svalue += char(c); value = ASR::down_cast( ASR::make_StringConstant_t(al, loc, s2c(al, svalue), str_type)); } + int kind = ASRUtils::extract_kind_from_ttype_t(type); + if (kind != 4) { + ASR::ttype_t* dest_type = ASRUtils::TYPE(ASR::make_Integer_t(al,loc, 4)); + arg = ASRUtils::EXPR(ASR::make_Cast_t(al, loc, arg, ASR::cast_kindType::IntegerToInteger, dest_type, nullptr)); + } return ASR::make_StringChr_t(al, loc, arg, str_type, value); } else { throw SemanticError("'" + ASRUtils::type_to_str_python(type) + "' object cannot be interpreted as an integer",