Skip to content

Commit a394303

Browse files
authored
Merge pull request #2203 from Shaikh-Ubaid/char_changes_from_lfortran
Support different integers in chr()
2 parents 31a6be1 + afe3769 commit a394303

File tree

4 files changed

+33
-5
lines changed

4 files changed

+33
-5
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ RUN(NAME expr_17 LABELS cpython llvm c)
445445
RUN(NAME expr_18 FAIL LABELS cpython llvm c)
446446
RUN(NAME expr_19 LABELS cpython llvm c)
447447
RUN(NAME expr_20 LABELS cpython llvm c)
448+
RUN(NAME expr_21 LABELS cpython llvm c)
448449

449450
RUN(NAME expr_01u LABELS cpython llvm c NOFAST)
450451
RUN(NAME expr_02u LABELS cpython llvm c NOFAST)

integration_tests/expr_21.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from lpython import i8, i16, i32, i64
2+
3+
def main0():
4+
x: i8
5+
y: i16
6+
z: i32
7+
w: i64
8+
9+
x = i8(97)
10+
y = i16(47)
11+
z = 56
12+
w = i64(67)
13+
14+
print(chr(x), chr(y), chr(z), chr(w))
15+
16+
assert chr(x) == 'a'
17+
assert chr(y) == '/'
18+
assert chr(z) == '8'
19+
assert chr(w) == 'C'
20+
21+
main0()

src/libasr/runtime/lfortran_intrinsics.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1340,7 +1340,8 @@ LFORTRAN_API int _lfortran_str_ord_c(char* s)
13401340
LFORTRAN_API char* _lfortran_str_chr(int val)
13411341
{
13421342
char* dest_char = (char*)malloc(2);
1343-
dest_char[0] = val;
1343+
uint8_t extended_ascii = (uint8_t)val;
1344+
dest_char[0] = extended_ascii;
13441345
dest_char[1] = '\0';
13451346
return dest_char;
13461347
}

src/lpython/semantics/python_intrinsic_eval.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -448,15 +448,20 @@ struct IntrinsicNodeHandler {
448448
if (ASRUtils::is_integer(*type)) {
449449
if (ASRUtils::expr_value(arg) != nullptr) {
450450
int64_t c = ASR::down_cast<ASR::IntegerConstant_t>(arg)->m_n;
451-
if (! (c >= 0 && c <= 127) ) {
452-
throw SemanticError("The argument 'x' in chr(x) must be in the range 0 <= x <= 127.", loc);
451+
c = (uint8_t) c;
452+
if (! (c >= 0 && c <= 255) ) {
453+
throw SemanticError("The argument 'x' in chr(x) must be in the range 0 <= x <= 255.", loc);
453454
}
454-
char cc = c;
455455
std::string svalue;
456-
svalue += cc;
456+
svalue += char(c);
457457
value = ASR::down_cast<ASR::expr_t>(
458458
ASR::make_StringConstant_t(al, loc, s2c(al, svalue), str_type));
459459
}
460+
int kind = ASRUtils::extract_kind_from_ttype_t(type);
461+
if (kind != 4) {
462+
ASR::ttype_t* dest_type = ASRUtils::TYPE(ASR::make_Integer_t(al,loc, 4));
463+
arg = ASRUtils::EXPR(ASR::make_Cast_t(al, loc, arg, ASR::cast_kindType::IntegerToInteger, dest_type, nullptr));
464+
}
460465
return ASR::make_StringChr_t(al, loc, arg, str_type, value);
461466
} else {
462467
throw SemanticError("'" + ASRUtils::type_to_str_python(type) + "' object cannot be interpreted as an integer",

0 commit comments

Comments
 (0)