Skip to content

Implement goto in LPython #1163

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

Merged
merged 8 commits into from
Sep 30, 2022
Merged

Implement goto in LPython #1163

merged 8 commits into from
Sep 30, 2022

Conversation

ronnuriel
Copy link
Collaborator

No description provided.

@ronnuriel ronnuriel requested a review from czgdp1807 September 28, 2022 13:25
@ronnuriel ronnuriel self-assigned this Sep 28, 2022
@ronnuriel ronnuriel requested a review from certik September 28, 2022 14:03
@ronnuriel ronnuriel added c Label for C language related changes asr ASR related changes labels Sep 28, 2022
@czgdp1807 czgdp1807 marked this pull request as draft September 29, 2022 02:56
@czgdp1807 czgdp1807 marked this pull request as ready for review September 29, 2022 08:19


def _make_code(code, codestring):
return code.replace(co_code=codestring)
Copy link
Collaborator

@czgdp1807 czgdp1807 Sep 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of manually calling types.Code(*args) as in the original source code I am using .replace method and passing the updated code. This makes it work with Python > 3.8 robustly since we don't depend on the internal order of arguments to PyCode_New.

@czgdp1807
Copy link
Collaborator

czgdp1807 commented Sep 29, 2022

@certik This is ready and works for CPython, LLVM and C backend. The file src/runtime/ltypes/goto.py is taken from snoack/python-goto. I have the following questions,

  1. How should I give credit to python-goto developers? They use UNLICENSE which doesn't impose any legal restrictions on us. Should I add the commit we are using in a comment at the top of src/runtime/ltypes/goto.py (our goto.py file)?
  2. I figured out a fix (see Implement goto in LPython #1163 (comment)). My question is should I send a PR to the original project or is it not necessary because we are not facing the burden of supporting very old Python versions.

Please let me know. Other than the above questions goto feature is fully ready from my side.

@rebcabin
Copy link
Contributor

rebcabin commented Sep 29, 2022

Is "UNLICENSE" equivalent to "PUBLIC DOMAIN?" If we have any other "derivative works" in our sources, how are we giving credit to the authors of the originals?

@czgdp1807
Copy link
Collaborator

Is "UNLICENSE" equivalent to "PUBLIC DOMAIN?"

Correct as far as I can tell.

If we have any other "derivative works" in our sources, how are we giving credit to the authors of the originals?

I don't think we have any AFAICT. @certik Can you please confirm.

@rebcabin
Copy link
Contributor

  1. I figured out a fix (see Goto #1163 (comment)). My question is should I send a PR to the original project or is it not necessary because we are not facing the burden of supporting very old Python versions.

I would say we do not need the original project to pull any of our changes because we will never support earlier versions of Python. Is there any residual benefit to them? What's our version floor? 3.7, 3.9, ... ?

@rebcabin
Copy link
Contributor

3. I figured out a fix (see Goto #1163 (comment)). My question is should I send a PR to the original project or is it not necessary because we are not facing the burden of supporting very old Python versions.

I would say we do not need the original project to pull any of our changes because we will never support earlier versions of Python. Is there any residual benefit to them? What's our version floor? 3.7, 3.9, ... ?

Looks like we're 3.9 and greater for LPython.

@czgdp1807 czgdp1807 changed the title Goto Implement goto in LPython Sep 29, 2022
@@ -173,10 +173,10 @@ stmt
-- GoTo points to a GoToTarget with the corresponding target_id within
-- the same procedure. We currently use `int` IDs to link GoTo with
-- GoToTarget to avoid issues with serialization.
| GoTo(int target_id)
| GoTo(int target_id, identifier name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think GoTo should just reference using an ID. The name should go into GoToTarget.

Suggested change
| GoTo(int target_id, identifier name)
| GoTo(int target_id)

Or am I missing something?

Copy link
Collaborator

@czgdp1807 czgdp1807 Sep 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well in C backend we need the name to produce, label name_of_the_label or goto name_of_the_label. So we need the name to be stored in both GoTo and GoToTarget.

if( !ASR::is_a<ASR::stmt_t>(*tmp) ) {
ASRUtils::EXPR(tmp);
tmp = nullptr;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of these lines, both the original and the new ones?

Are we checking that the result is an expression? If so, you can use an assert for ASR::is_a (or perhaps down_cast, since is_a might require a particular class).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the scene is that goto.end is represented as [(Expr (Attribute (Name goto Load) end Load))] at AST level. So, now when we will complete visiting Attribute, tmp will either point to a ASR expression or a ASR statement (because GoTo in ASR is a statement). So in case we get something like, goto.label then tmp will point to a statement in which case we should exit the function naturally and the transform_stmts before this node will include that GoTo statement. However if tmp is not pointing to a statement then I replaced ASRUtils::EXPR(tmp) with an LFORTRAN_ASSERT.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If so, you can use an assert for ASR::is_a (or perhaps down_cast, since is_a might require a particular class).

Assert with ASR::is_a works fine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please document this as a comment? Next person to see that code will have the same question, including me tomorrow.

Copy link
Contributor

@certik certik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is good enough to merge as is. But there are issues to resolve. One is the ASR relationship of GoTo and GoToTarget. It looks like what is needed is a direct link (in C++) from goto to the target, so that one can read off the name if needed easily.

It seems the ASR.asdl structure does not easily allow a way to do it. Storing both the number and a string is redundant.

@certik
Copy link
Contributor

certik commented Sep 29, 2022

Regarding where to maintain the CPython implementation, yes, we should maintain it ourselves and ensure it actually works in all modern Python versions.

@czgdp1807 czgdp1807 enabled auto-merge September 30, 2022 02:57
@czgdp1807
Copy link
Collaborator

It looks like what is needed is a direct link (in C++) from goto to the target, so that one can read off the name if needed easily.

It seems the ASR.asdl structure does not easily allow a way to do it. Storing both the number and a string is redundant.

There are two ways in my mind to deal with this,

  1. Store only the name and generate IDs in the backend. This goes against the principle that we backend shouldn't need to track anything.
  2. Change GoTo(int target_id, identifier name) to GoTo(stmt_t goto_target). Then one can do ASR::down_cast<ASR::GoToTarget>(goto_object->goto_target)->m_name. One extra indirection but it should removes the redundancy.

@czgdp1807 czgdp1807 merged commit 5a99a6a into lcompilers:main Sep 30, 2022
@czgdp1807 czgdp1807 deleted the goto branch September 30, 2022 03:20
@certik
Copy link
Contributor

certik commented Sep 30, 2022

Change GoTo(int target_id, identifier name) to GoTo(stmt_t goto_target). Then one can do ASR::down_cast<ASR::GoToTarget>(goto_object->goto_target)->m_name. One extra indirection but it should removes the redundancy.

I like this idea, so I opened up a dedicated issue for this: #1167

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
asr ASR related changes c Label for C language related changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants