-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
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
GH-123391: Code generators: Track stack and locals in if
statements.
#123397
Conversation
…ntax error, just a tool limitation.
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.
Some nitpicks.
f"Locals not defined in stack order. " | ||
f"Expected '{out.name}' is defined before '{undefined}'" |
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.
f"Locals not defined in stack order. " | |
f"Expected '{out.name}' is defined before '{undefined}'" | |
f"Locals not defined in stack order. " | |
f"Expected {out.name!r} to be defined before {undefined!r}" |
break | ||
undefined = "" | ||
for out in self.outputs: | ||
if out.defined: |
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.
If the first out.defined
holds, then we don't really have anything "before" (unless this case is not possible?)
self.emit(next(tkn_iter)) | ||
lparen = next(tkn_iter) | ||
self.emit(lparen) | ||
assert(lparen.kind == "LPAREN") |
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.
assert(lparen.kind == "LPAREN") | |
assert lparen.kind == "LPAREN" |
self.emit(next(tkn_iter)) | ||
lparen = next(tkn_iter) | ||
self.emit(lparen) | ||
assert(lparen.kind == "LPAREN") |
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.
assert(lparen.kind == "LPAREN") | |
assert lparen.kind == "LPAREN" |
self.out.emit(next(tkn_iter)) | ||
lparen = next(tkn_iter) | ||
self.emit(lparen) | ||
assert(lparen.kind == "LPAREN") |
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.
assert(lparen.kind == "LPAREN") | |
assert lparen.kind == "LPAREN" |
raise analysis_error( | ||
f"Locals not defined in stack order. " | ||
f"Expected '{out.name}' is defined before '{undefined}'", | ||
tkn | ||
) |
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.
raise analysis_error( | |
f"Locals not defined in stack order. " | |
f"Expected '{out.name}' is defined before '{undefined}'", | |
tkn | |
) | |
raise analysis_error( | |
f"Locals not defined in stack order. " | |
f"Expected {out.name!r} to be defined before {undefined!r}", | |
tkn | |
) |
other.top_offset = self.top_offset.copy() | ||
other.base_offset = self.base_offset.copy() | ||
other.variables = [var.copy() for var in self.variables] | ||
other.defined = set(self.defined) |
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.
other.defined = set(self.defined) | |
other.defined = self.defined.copy() |
self.out.emit(next(tkn_iter)) | ||
lparen = next(tkn_iter) | ||
self.emit(lparen) | ||
assert(lparen.kind == "LPAREN") |
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.
assert(lparen.kind == "LPAREN") | |
assert lparen.kind == "LPAREN" |
self.run_cases_test(input, output) | ||
|
||
|
||
def test_pep7_condition(self): |
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.
Maybe test the else branch as well?
This PR adds little functionality, but it will enable us to do much more effective stack spilling in the future.
I've deliberately left the spilling functionality for a later PR to make this PR easier to review.
This PR:
Storage
class which combines the state of the stack and the local variables within a micro-op.if
statements.The resulting generated code is basically the same as we have now.
To simplify parsing, the code generator also enforces PEP 7 rules for braces.
Most of the changes in bytecodes.c are a result of this change.