-
Notifications
You must be signed in to change notification settings - Fork 172
Add list.index #1703
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
Add list.index #1703
Conversation
d489a65
to
b890fbf
Compare
It won't be efficient because slicing a list will create a copy which is not needed at all. I will start the loop from For long term, How to use IntrinsicFunction for implementing methods like,
Point 2 is for the far future. In fact if I think more you don't need to add lpython/src/libasr/pass/intrinsic_function.cpp Lines 63 to 71 in ae6c547
Also, you can ignore implementing lpython/src/libasr/pass/intrinsic_function_registry.h Lines 456 to 466 in ae6c547
Also modify the following by returning a lpython/src/libasr/pass/intrinsic_function_registry.h Lines 489 to 491 in ae6c547
By following the above approach you won't be required to add new ASR nodes for each intrinsic feature of Python language like, cc: @certik What do you say? |
If @certik agrees and if you want, I can try the above approach here in your PR and we will see if its doable or not. If it is then we can remove a large number of unnecessary nodes from ASR and just register everything in https://github.com/lcompilers/lpython/blob/main/src/libasr/pass/intrinsic_function.cpp. |
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.
Yes, @czgdp1807's plan is the way to go I think. However, this PR is small and clean, so I think it's ok to merge it and then do the refactoring in a new PR.
@czgdp1807 I'll leave the decision up to you. If it's easy to do the redesign here, then let's do it, otherwise in a new PR.
I am doing it here. Let's see how it goes. |
@virendrakabra14 I have pushed the changes (which I described above). Please update your branch locally. @certik Please let me know if they look good to you. I will apply them to LFortran as well. Initially keeping IntrinsicFunction in sync between LPython/LFortran will help in avoiding problems. I will not apply list.index changes, just the API changes in |
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 this looks pretty good, thanks!
4, nullptr, 0)); | ||
return ASR::make_IntrinsicFunction_t(al, loc, | ||
static_cast<int64_t>(ASRUtils::IntrinsicFunctions::ListIndex), | ||
args.p, args.size(), 0, to_type, compile_time_value); |
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.
Is the idea that create_ListIndex
is to be used when we need to check the argument types and compute compile time value (if available), but if we already have everything ready (such as in some transformation passes), we just use make_IntrinsicFunction_t directly?
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.
Yes. All the error checking related to an intrinsic function resides in one place. Also there is no restriction on using make_IntrinsicFunction_t
directly (its a public API and if you few feel you can avoid calling, create_ListIndex
or any other create function then feel free to do so).
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.
Later we might need to add some checks to verify() to ensure all arguments to IntrinsicFunctions are correct. For now this is good.
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.
We can easily do this by registering verify_args
function in IntrinsicFunctionRegistry
. We can define, LogGamma::verify_args
, Abs::verify_args
, etc. Then, in asr_verify.cpp we can call these methods in the same way as we call instantiate_function
in intrinsic_function.cpp
.
std::string org = ASRUtils::type_to_str_python(list_type); | ||
err( | ||
"Type mismatch in 'index', the types must be compatible " | ||
"(found: '" + fnd + "', expected: '" + org + "')", loc); |
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 a bit worried that we have a frontend dependency here (ASRUtils::type_to_str_python
).
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.
Ah! Yes. I would do get_type_code
here.
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.
We now use get_type_code
since its just an error message so our frontend agnostic type codes should convey the error with same clarity.
I think this is ok to merge. I have some design questions, but I think we can iterate on this after it is merged. |
I will make some updates here before merging. |
This reuses
LLVMList::find_item_position
inllvm_utils.cpp
. Part of #941.Issues
list.remove
#1701 is common to bothlist.remove
andlist.index
.tests/errors/test_list_index.py
doesn't appear to give an error, but putting the same snippet at the end ofintegration_tests/test_list_index.py
correctly outputsValueError: The list does not contain the element: 0
. (Is this related to the above point?)CPython allows specifying a range for finding the first occurrence as
list.index(x[, start[, end]])
. This would be easier to implement using the existing implementations of list-slicing andindex
. Could someone please point to where we implement such overloads for data-structure methods?