diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index ccea9e3bf4..6a0f2c56d9 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -273,6 +273,7 @@ RUN(NAME vec_01 LABELS cpython llvm) RUN(NAME test_str_comparison LABELS cpython llvm c) RUN(NAME test_bit_length LABELS cpython llvm c) RUN(NAME str_to_list_cast LABELS cpython llvm) +RUN(NAME test_issue_332 LABELS llvm) RUN(NAME generics_01 LABELS cpython llvm) RUN(NAME generics_02 LABELS cpython llvm) diff --git a/integration_tests/test_issue_332.py b/integration_tests/test_issue_332.py new file mode 100644 index 0000000000..d49cc34c81 --- /dev/null +++ b/integration_tests/test_issue_332.py @@ -0,0 +1,13 @@ +from ltypes import i32 + +def test_issue_332(): + arr: i32[4] + arr[0] = 1 + arr[1] = 0 + arr[2] = -4 + print(arr[:2]) + print(arr[1]) + print(arr[2]) + + +test_issue_332() diff --git a/src/libasr/runtime/lfortran_intrinsics.c b/src/libasr/runtime/lfortran_intrinsics.c index 3abd0f6ffd..2f400249ab 100644 --- a/src/libasr/runtime/lfortran_intrinsics.c +++ b/src/libasr/runtime/lfortran_intrinsics.c @@ -801,9 +801,11 @@ LFORTRAN_API char* _lfortran_str_copy(char* s, int32_t idx1, int32_t idx2) { return dest_char; } +// This functions considers idx1 and idx2 both inclusive. LFORTRAN_API char* _lfortran_str_slice(char* s, int32_t idx1, int32_t idx2, int32_t step, bool idx1_present, bool idx2_present) { int s_len = strlen(s); + idx2++; if (step == 0) { printf("slice step cannot be zero\n"); exit(1); diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index e0c0a9e66f..f647e13626 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -2681,7 +2681,13 @@ class CommonVisitor : public AST::BaseVisitor { if (!ASRUtils::is_integer(*ASRUtils::expr_type(ASRUtils::EXPR(tmp)))) { throw SemanticError("slice indices must be integers or None", tmp->loc); } - ai.m_right = ASRUtils::EXPR(tmp); + // Subtract 1 from right since python has exclusive right limits. + ASR::ttype_t *a_type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, + 4, nullptr, 0)); + ASR::expr_t *constant_one = ASR::down_cast(ASR::make_IntegerConstant_t( + al, loc, 1, a_type)); + ai.m_right = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, ASRUtils::EXPR(tmp), + ASR::binopType::Sub, constant_one, a_type, nullptr)); } if (sl->m_step != nullptr) { this->visit_expr(*sl->m_step); @@ -2689,18 +2695,14 @@ class CommonVisitor : public AST::BaseVisitor { throw SemanticError("slice indices must be integers or None", tmp->loc); } ai.m_step = ASRUtils::EXPR(tmp); - } - if( ai.m_left != nullptr && - ASR::is_a(*ai.m_left) && - ASR::is_a(*ai.m_right) ) { - ASR::Variable_t* startv = ASRUtils::EXPR2VAR(ai.m_left); - ASR::Variable_t* endv = ASRUtils::EXPR2VAR(ai.m_right); - is_item = is_item && (startv == endv); } else { - is_item = is_item && (ai.m_left == nullptr && - ai.m_step == nullptr && - ai.m_right != nullptr); + ASR::ttype_t *a_type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, + 4, nullptr, 0)); + ASR::expr_t *constant_one = ASR::down_cast(ASR::make_IntegerConstant_t( + al, loc, 1, a_type)); + ai.m_step = constant_one; } + is_item = false; if (ASR::is_a(*type)) { tmp = ASR::make_ListSection_t(al, loc, value, ai, type, nullptr); return false; diff --git a/tests/reference/asr-list1-770ba33.json b/tests/reference/asr-list1-770ba33.json index d2abab03d5..e40eedda73 100644 --- a/tests/reference/asr-list1-770ba33.json +++ b/tests/reference/asr-list1-770ba33.json @@ -10,4 +10,4 @@ "stderr": null, "stderr_hash": null, "returncode": 0 -} \ No newline at end of file +}