diff --git a/integration_tests/test_str_01.py b/integration_tests/test_str_01.py index 7da6cd83bc..eafe27eae2 100644 --- a/integration_tests/test_str_01.py +++ b/integration_tests/test_str_01.py @@ -27,9 +27,16 @@ def test_str_index(): assert a[-1] == "5" assert a[-6] == "0" +def test_str_slice(): + a: str + a = "012345" + assert a[2:4] == "23" + assert a[2:3] == a[2] + def check(): f() test_str_concat() test_str_index() + test_str_slice() check() diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 180c3073e8..8396ce0914 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -1075,7 +1075,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor //throw CodeGenError("Only string(a:b) for a,b variables for now.", x.base.base.loc); // Use the "right" index for now this->visit_expr_wrapper(x.m_args[0].m_right, true); - llvm::Value *idx = tmp; + llvm::Value *idx2 = tmp; + this->visit_expr_wrapper(x.m_args[0].m_left, true); + llvm::Value *idx1 = tmp; // idx = builder->CreateSub(idx, llvm::ConstantInt::get(context, llvm::APInt(32, 1))); //std::vector idx_vec = {llvm::ConstantInt::get(context, llvm::APInt(32, 0)), idx}; // std::vector idx_vec = {idx}; @@ -1083,7 +1085,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor // llvm::Value *p = CreateGEP(str, idx_vec); // TODO: Currently the string starts at the right location, but goes to the end of the original string. // We have to allocate a new string, copy it and add null termination. - llvm::Value *p = lfortran_str_copy(str, idx, idx); + llvm::Value *p = lfortran_str_copy(str, idx1, idx2); tmp = builder->CreateAlloca(character_type, nullptr); builder->CreateStore(p, tmp); diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index eac5ea628a..72f86a79ec 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -1233,7 +1233,7 @@ 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 = index_add_one(x.base.base.loc, ASRUtils::EXPR(tmp)); + ai.m_right = ASRUtils::EXPR(tmp); } if (s->m_step != nullptr) { this->visit_expr(*s->m_step); diff --git a/tests/reference/asr-subscript1-1acfc19.json b/tests/reference/asr-subscript1-1acfc19.json index 8b73e7d124..afd511acd1 100644 --- a/tests/reference/asr-subscript1-1acfc19.json +++ b/tests/reference/asr-subscript1-1acfc19.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-subscript1-1acfc19.stdout", - "stdout_hash": "ce3de13d575b58ea45610106701fea385509a39f0a88cd9a96b1f3a9", + "stdout_hash": "567ee666c2e63003152d97effb4b33f7866639a4a3285f564b9a7689", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-subscript1-1acfc19.stdout b/tests/reference/asr-subscript1-1acfc19.stdout index a94bea3e91..23ba2c3377 100644 --- a/tests/reference/asr-subscript1-1acfc19.stdout +++ b/tests/reference/asr-subscript1-1acfc19.stdout @@ -1 +1 @@ -(TranslationUnit (SymbolTable 1 {main_program: (Program (SymbolTable 3 {}) main_program [] []), test_subscript: (Subroutine (SymbolTable 2 {A: (Variable 2 A Local () () Default (Integer 4 [((IntegerConstant 1 (Integer 4 [])) (IntegerConstant 5 (Integer 4 [])))]) Source Public Required .false.), B: (Variable 2 B Local () () Default (Integer 4 [((IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 [])))]) Source Public Required .false.), i: (Variable 2 i Local () () Default (Integer 4 []) Source Public Required .false.), s: (Variable 2 s Local () () Default (Character 1 -2 () []) Source Public Required .false.)}) test_subscript [] [(= (Var 2 s) (StringConstant "abc" (Character 1 3 () [])) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (IntegerConstant 0 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (IntegerConstant 0 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) ())] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (IntegerConstant 1 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (IntegerConstant 2 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) ())] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [(() () ())] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [(() () (BinOp (UnaryOp USub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 []))) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [(() () (BinOp (IntegerConstant 2 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (IntegerConstant 1 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (IntegerConstant 88 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (IntegerConstant 1 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (IntegerConstant 1 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (IntegerConstant 1 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (UnaryOp USub (IntegerConstant 4 (Integer 4 [])) (Integer 4 []) (IntegerConstant -4 (Integer 4 []))) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (UnaryOp USub (IntegerConstant 89 (Integer 4 [])) (Integer 4 []) (IntegerConstant -89 (Integer 4 []))) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) () (BinOp (IntegerConstant 4 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (UnaryOp USub (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) (IntegerConstant -3 (Integer 4 []))) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (UnaryOp USub (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) (IntegerConstant -3 (Integer 4 []))) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (UnaryOp USub (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) (IntegerConstant -3 (Integer 4 []))) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (IntegerConstant 2 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (IntegerConstant 3 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) ())] (Character 1 -2 () []) ()) ()) (= (Var 2 i) (ArrayRef 2 A [(() (BinOp (IntegerConstant 0 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) ())] (Integer 4 [((IntegerConstant 1 (Integer 4 [])) (IntegerConstant 5 (Integer 4 [])))]) ()) ()) (= (Var 2 B) (ArrayRef 2 A [((BinOp (IntegerConstant 1 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (IntegerConstant 3 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) ())] (Integer 4 [((IntegerConstant 1 (Integer 4 [])) (IntegerConstant 5 (Integer 4 [])))]) ()) ()) (= (Var 2 B) (ArrayRef 2 A [((BinOp (IntegerConstant 1 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (IntegerConstant 2 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (IntegerConstant 3 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Integer 4 [((IntegerConstant 1 (Integer 4 [])) (IntegerConstant 5 (Integer 4 [])))]) ()) ())] Source Public Implementation () .false. .false.)}) []) +(TranslationUnit (SymbolTable 1 {main_program: (Program (SymbolTable 3 {}) main_program [] []), test_subscript: (Subroutine (SymbolTable 2 {A: (Variable 2 A Local () () Default (Integer 4 [((IntegerConstant 1 (Integer 4 [])) (IntegerConstant 5 (Integer 4 [])))]) Source Public Required .false.), B: (Variable 2 B Local () () Default (Integer 4 [((IntegerConstant 1 (Integer 4 [])) (IntegerConstant 2 (Integer 4 [])))]) Source Public Required .false.), i: (Variable 2 i Local () () Default (Integer 4 []) Source Public Required .false.), s: (Variable 2 s Local () () Default (Character 1 -2 () []) Source Public Required .false.)}) test_subscript [] [(= (Var 2 s) (StringConstant "abc" (Character 1 3 () [])) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (IntegerConstant 0 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (BinOp (IntegerConstant 0 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) ())] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (IntegerConstant 1 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (IntegerConstant 2 (Integer 4 [])) ())] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [(() () ())] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [(() () (BinOp (UnaryOp USub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) (IntegerConstant -1 (Integer 4 []))) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [(() () (BinOp (IntegerConstant 2 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (IntegerConstant 1 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (IntegerConstant 88 (Integer 4 [])) (BinOp (IntegerConstant 1 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [((IntegerConstant 1 (Integer 4 [])) (IntegerConstant 1 (Integer 4 [])) (BinOp (UnaryOp USub (IntegerConstant 4 (Integer 4 [])) (Integer 4 []) (IntegerConstant -4 (Integer 4 []))) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (UnaryOp USub (IntegerConstant 89 (Integer 4 [])) (Integer 4 []) (IntegerConstant -89 (Integer 4 []))) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) () (BinOp (IntegerConstant 4 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (UnaryOp USub (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) (IntegerConstant -3 (Integer 4 []))) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (UnaryOp USub (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) (IntegerConstant -3 (Integer 4 []))) (BinOp (UnaryOp USub (IntegerConstant 3 (Integer 4 [])) (Integer 4 []) (IntegerConstant -3 (Integer 4 []))) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Character 1 -2 () []) ()) ()) (= (Var 2 s) (ArrayRef 2 s [((BinOp (IntegerConstant 2 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (IntegerConstant 3 (Integer 4 [])) ())] (Character 1 -2 () []) ()) ()) (= (Var 2 i) (ArrayRef 2 A [(() (BinOp (IntegerConstant 0 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) ())] (Integer 4 [((IntegerConstant 1 (Integer 4 [])) (IntegerConstant 5 (Integer 4 [])))]) ()) ()) (= (Var 2 B) (ArrayRef 2 A [((BinOp (IntegerConstant 1 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (IntegerConstant 3 (Integer 4 [])) ())] (Integer 4 [((IntegerConstant 1 (Integer 4 [])) (IntegerConstant 5 (Integer 4 [])))]) ()) ()) (= (Var 2 B) (ArrayRef 2 A [((BinOp (IntegerConstant 1 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (IntegerConstant 2 (Integer 4 [])) (BinOp (IntegerConstant 3 (Integer 4 [])) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()))] (Integer 4 [((IntegerConstant 1 (Integer 4 [])) (IntegerConstant 5 (Integer 4 [])))]) ()) ())] Source Public Implementation () .false. .false.)}) [])