Skip to content
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

Blocks #25

Open
clozinski opened this issue Mar 15, 2017 · 2 comments
Open

Blocks #25

clozinski opened this issue Mar 15, 2017 · 2 comments

Comments

@clozinski
Copy link

The method manage_block_stack
https://github.com/nedbat/byterun/blob/master/byterun/pyvm2.py#L246-L307

mentions 4 different block types.

  • loop
  • finally
  • setup-except
  • with

and 5ldifferent whys

  • yield
  • continue
  • break
  • exception
  • return

Maybe after closures this is the second hardest piece of code to understand. Of course there is lots of documentation on the web.

Generally Blocks are pretty obvious. Every time I indent, I create a block. I have to add them to the block stack. Understanding what happens with an exception is a bit harder to grok.

But this code really tangles them all together. There is not even a Block class, just a named tuple.

Block = collections.namedtuple("Block", "type, handler, level")

From a conceptual point of view, I think it would be much easier to create 4 different Block classes. Maybe they would have a shared base class. It would certainly be much easier to document.

I can understand why cPython did it this way. But my goal here is to understand the concepts, before I try to understand the optimizations.

So may I write the documentation as 4 different block classes? If I eventually write those classes, would you accept a pull request?

Warm Regards
Chris

@clozinski
Copy link
Author

So I went ahead and restructured the code according to block type. I have not yet debugged it, but the end result is interesting. It is conceptually simpler. You just think about one block type at a time. Maybe a few more lines of code overall, but conceptually simpler. One can look at one block type, and figure out exactly what is going on. Debugging, should also be easier.

Maye on creating blocks, I will need a few more if statements.

I am slightly tempted to throw out the Py2/Py3 stuff. Just have one version. At least in the documentation. That would again reduce the conceptual burden.

@akaptur
Copy link
Contributor

akaptur commented Mar 16, 2017

Hey Chris!

Thanks for looking at this - you're right that Blocks are one of the most fiddly parts of the interpreter.

Every time I indent, I create a block. I have to add them to the block stack.

To be a bit pedantic, every indentation isn't a new Block. For example, creating a class or a method doesn't create a new block.

Understanding what happens with an exception is a bit harder to grok.

This is about what happens with an exception handler rather than an exception. See b47f377 for some details on this, and take a read of the linked email.

So you get blocks in the following cases (simplified):

for ...:
   loop block

while ... :
   loop block

try:
   setup-except
except:
   (not a block!)
finally:
   finally

with ...:
    with block

But my goal here is to understand the concepts, before I try to understand the optimizations.

This is definitely byterun's overall goal, so I'd be happy to look at your code.

I am slightly tempted to throw out the Py2/Py3 stuff. Just have one version. At least in the documentation.

http://www.aosabook.org/en/500L/a-python-interpreter-written-in-python.html is Py3 only for exactly this reason. Byterun itself is going to preserve 2 & 3 compatibility, but it's fine to have docs that are Py3 only (provided they say so).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants