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

Basic for parsing/interpreting #32

Merged
merged 5 commits into from
Dec 3, 2023

Conversation

Jacco
Copy link
Contributor

@Jacco Jacco commented Nov 29, 2023

Resolved #31

Also implements iter on Dict and List
added main handling on interpreter
Added enumerate global function
Added items function on Dict
tests also check real python

Jacco and others added 2 commits November 29, 2023 11:05
Also implements __iter__ on Dict and List
added main handling on interpreter
Added enumerate global function
Added items function on Dict
tests also check real python
@tusharsadhwani
Copy link
Owner

Thanks a lot! Most of the work seems good, especially in the Interpreter class.

The parser will probably require some changes, as I think we should reuse parse_expression() for the parsing of the targets here.

Consider this example from Python's AST:

$ python -m ast <<<'for i in x in y in z: ...'
Module(
   body=[
      For(
         target=Name(id='i', ctx=Store()),
         iter=Compare(
            left=Name(id='x', ctx=Load()),
            ops=[
               In(),
               In()],
            comparators=[
               Name(id='y', ctx=Load()),
               Name(id='z', ctx=Load())]),
         body=[
            Expr(
               value=Constant(value=Ellipsis))],
         orelse=[])],
   type_ignores=[])

This seems to show that we can stop at the first in statement for the target, right?

Well, unfortunately that's not the case, for example, if there are commas after that sub-expression:

$ python -m ast <<<'for i in x, j in y in z: ...'
Module(
   body=[
      For(
         target=Name(id='i', ctx=Store()),
         iter=Tuple(
            elts=[
               Name(id='x', ctx=Load()),
               Compare(
                  left=Name(id='j', ctx=Load()),
                  ops=[
                     In(),
                     In()],
                  comparators=[
                     Name(id='y', ctx=Load()),
                     Name(id='z', ctx=Load())])],
            ctx=Load()),
         body=[
            Expr(
               value=Constant(value=Ellipsis))],
         orelse=[])],
   type_ignores=[])

Here, i in x, j became the target and y, z became the iterable.

Doing this correctly will require some more looking into how Python's actual grammar works.

@Jacco
Copy link
Contributor Author

Jacco commented Nov 29, 2023

I did experiment with multiple expressions separated by comma after the in. I think that already works.

The extra ins are comparisson operators or am I missing something :-)

In both case the target is target=Name(id='i', ctx=Store()),

Or do you mean the output of my code :-)

@tusharsadhwani
Copy link
Owner

You're right, I confused myself.

Making some small changes to the code...

@Jacco
Copy link
Contributor Author

Jacco commented Nov 29, 2023

I think I also forgot to add the 'range' function

@tusharsadhwani
Copy link
Owner

I made some adjustments:

  • Since we don't have a Generator type yet, Items and Enumerate will return a List instead. Unfortunate but it is how it is for now.
  • The parser was mostly good! I just made sure that iterable and target were always a Node, instead of a list of Nodes
  • Added a parser test to ensure we parse for loops properly.

@tusharsadhwani
Copy link
Owner

Please feel free to add a range class as well.

@Jacco
Copy link
Contributor Author

Jacco commented Nov 29, 2023

  • The parser was mostly good! I just made sure that iterable and target were always a Node, instead of a list of Nodes

I think they can have multiple. There are examples in the tests:

This one has two targets

for k,w in dct.item():
    print(k,w)

@tusharsadhwani
Copy link
Owner

This one has two targets

for k,w in dct.item():
    print(k,w)

@Jacco In this case target will be a Tuple, check parser_test.py changes.

@Jacco
Copy link
Contributor Author

Jacco commented Dec 1, 2023

Ah ok, I missed the inner workings self.assign :-)

@tusharsadhwani
Copy link
Owner

I'll merge this PR soon, you can add a range function in a separate one.

@tusharsadhwani tusharsadhwani merged commit 12429a0 into tusharsadhwani:main Dec 3, 2023
5 of 6 checks passed
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

Successfully merging this pull request may close these issues.

Implement visit_For
2 participants