-
Notifications
You must be signed in to change notification settings - Fork 158
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix ASR Slice frontend #1051
base: main
Are you sure you want to change the base?
Fix ASR Slice frontend #1051
Conversation
The current PR works fine with this: def main0():
arr: i32[4]
arr[0] = 1
arr[1] = 0
arr[2] = -4
print(arr[:2])
print(arr[1])
print(arr[2])
main0() Output:
The only issue is that the Array Section backend considers the right limit as inclusive whereas other Section backends (List/string) consider the right limit as exclusive. So we need to define some strict way of defining indexes, limits that is followed uniformly in all the backends. |
Well. Array is a shared feature between Fortran and Python. Fortran includes end index while slicing an array. However Python excludes end index. I think the backend should always treat the end index inclusive. Its the AST->ASR transition's job to format the indices of an array slices correctly. For example, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a test for your fix.
print(arr[:2]) | ||
print(arr[1]) | ||
print(arr[2]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use assert
for verifying that the outputs are actually correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if we can assign Array Section at present (I think only string is supported).
p: i32[4]
arr[0] = 1
arr[1] = 0
arr[2] = -4
p = arr[:2]
Throws this:
LFORTRAN_ASSERT(ASR::is_a<ASR::Character_t>(*ASRUtils::expr_type(x.m_v)) &&
AssertFailed: ASR::is_a<ASR::Character_t>(*ASRUtils::expr_type(x.m_v)) && n_dims == 0
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++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am surprised why tests didn't fail after this change. Can you try applying this specific change to LFortran to make sure this works there as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just because the frontend subtracts one and in backend (internally) we add one again. So, logic remains the same. And it's expected to pass all the tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you try applying this specific change to LFortran to make sure this works there as well.
Yep, tried. All tests passed for me. On the latest main branch of LFortran:
diff --git a/src/libasr/runtime/lfortran_intrinsics.c b/src/libasr/runtime/lfortran_intrinsics.c
index 17399c784..b71bfdd95 100644
--- a/src/libasr/runtime/lfortran_intrinsics.c
+++ b/src/libasr/runtime/lfortran_intrinsics.c
@@ -784,6 +784,7 @@ LFORTRAN_API char* _lfortran_str_copy(char* s, int32_t idx1, int32_t idx2) {
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) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just make a PR there (in LFortran) as well with a similar test. We will merge both together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will shepherd this later.
@czgdp1807 Should we merge this? Can we add assertion tests as the follow-up PR to keep this clean? |
@czgdp1807 let me know what needs to get done here. |
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++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just make a PR there (in LFortran) as well with a similar test. We will merge both together.
This is ready @czgdp1807 |
print(arr[:2]) | ||
print(arr[1]) | ||
print(arr[2]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usage of assert
possible here to check if the outputs are actually correct?
print(arr[:2]) | |
print(arr[1]) | |
print(arr[2]) | |
print(arr[:2]) | |
print(arr[1]) | |
print(arr[2]) | |
arr_2: i32[2] = arr[:2] | |
assert arr_2[0] == 1 | |
assert arr_2[1] == 0 | |
assert arr[1] == 0 | |
assert arr[2] == -4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet:
File "/Users/thebigbool/repos/lpython/src/libasr/codegen/asr_to_llvm.cpp", line 1658
LFORTRAN_ASSERT(ASR::is_a<ASR::Character_t>(*ASRUtils::expr_type(x.m_v)) &&
AssertFailed: ASR::is_a<ASR::Character_t>(*ASRUtils::expr_type(x.m_v)) && n_dims == 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. Can you try fixing the bug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the LLVM backend currently only supports string-slicing assignments and not arrays because they can be n-dimensional. Is that intentional?
Please fix #1051 (comment) and resolve the conflicts. Will merge it then. |
Fixes #332