diff --git a/integration_tests/test_str_03.py b/integration_tests/test_str_03.py index d9b140d9e2..ac142011dc 100644 --- a/integration_tests/test_str_03.py +++ b/integration_tests/test_str_03.py @@ -10,5 +10,16 @@ def test_int(): l: i64 = 4 print("abc:", i, j, k, l) + +def test_issue_1124(): + a: str + a = "012345" + assert a[-1] == "5" + assert a[-1] == a[5] + assert a[-2] == a[4] + assert a[-4] == "2" + + test_new_line() test_int() +test_issue_1124() diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 89bee35123..b4abf020bb 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -2586,6 +2586,19 @@ class CommonVisitor : public AST::BaseVisitor { } ai.m_right = index; if (ASRUtils::is_character(*type)) { + ASR::expr_t* val = ASRUtils::expr_value(index); + if (val && ASR::is_a(*val)) { + if (ASR::down_cast(val)->m_n < 0) { + // Replace `x[-1]` to `x[len(x)+(-1)]` + ASR::ttype_t *int_type = ASRUtils::TYPE(ASR::make_Integer_t( + al, loc, 4, nullptr, 0)); + ASR::expr_t *list_len = ASRUtils::EXPR(ASR::make_StringLen_t( + al, loc, value, int_type, nullptr)); + ASR::expr_t *neg_idx = ASRUtils::expr_value(index); + index = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, + list_len, ASR::binopType::Add, neg_idx, int_type, nullptr)); + } + } index = index_add_one(loc, index); ai.m_right = index; tmp = ASR::make_StringItem_t(al, loc, value, index, type, nullptr);