-
Notifications
You must be signed in to change notification settings - Fork 37
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
closureiters: use case
-based dispatcher
#607
closureiters: use case
-based dispatcher
#607
Conversation
5fc978a
to
e04de01
Compare
case
-based dispatcher
@@ -185,7 +185,7 @@ type | |||
unrollFinallySym: PSym # Indicates that we're unrolling finally states (either exception happened or premature return) | |||
curExcSym: PSym # Current exception | |||
|
|||
states: seq[PNode] # The resulting states. Every state is an nkState node. | |||
states: seq[tuple[label: int, body: PNode]] # The resulting states |
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.
This type reads more nicely and the tuple fields make the access below easier to follow when skimming. 👍🏽
compiler/sem/closureiters.nim
Outdated
while i < ctx.states.len - 1: | ||
let fs = skipStmtList(ctx, ctx.states[i][1]) | ||
if fs.kind == nkGotoState and i != 0: | ||
if ctx.states[i].label == -1: # is it unused? |
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.
Very soft suggestion: make -1
a constant, such as unusedStateIdx
, might read a bit better. It'd also be applicable to the setting of the label values above.
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.
That's much better, thanks.
I definitely like how this collapses the language into itself. Even before this change, I can imagine using case to explain how iterators work to a newcomer, and now the simple explanation and implementation are that much closer. Makes bridging the gap from language user to contributor that much smaller. 🚀 |
e04de01
to
c5fc991
Compare
Summary ======= Use a case statement for the dispatcher generated by the `closureiters` transformation, removing the need for both dedicated code generator support and the `nkState` node kind. This is a significant step towards closure iterator support the JavaScript and VM backend. While neither officially supported nor documented, it was previously possible to emit `nkGotoState` and `nkState` nodes from a macro, which could be used for unsafe unstructured control-flow. With the removal of the `nkState` node kind and `nkGotoState` being disallowed in AST reaching semantic analysis, the aforementioned is no longer possible. Details ======= The AST generated by the `closureiters` transformation always looked as follows: ```nim while true: block :stateLoop: # the block's body is wrapped in a try-except, if # necessary goto env.:state # goto the label corresponding to the run-time value # of `:state` # declarations body ``` where `body` defines the code blocks associated with each state value, like so: ```nim state 0: ... env.:state = 1 break :stateLoop state 1: ... state 2: ... ... # more labels (if used) follow ``` The control-flow described by the `goto` (`nkGotoState`) followed by the labels (`nkState`) is equally representable by the use of a case statement, which is what is now done after this commit. To summarize the change: - don't support `nkGotoState` nodes in AST reaching sem - adjust `closureiters` to generate a case statement for the dispatcher and to not depend on `nkState` - remove C code-generator support for `nkGotoState` and `nkState` - remove the `nkState` node kind Nodes with the `nkGotoState` kind now only exists *during* the transformation, but never before or after.
bors r+ |
Build succeeded: |
Summary
Use a case statement for the dispatcher generated by the
closureiters
transformation, removing the need for both dedicated code generator support and thenkState
node kind. This is a significant step towards closure iterator support the JavaScript and VM backend.While neither officially supported nor documented, it was previously possible to emit
nkGotoState
andnkState
nodes from a macro, which could be used for unsafe unstructured control-flow. With the removal of thenkState
node kind andnkGotoState
being disallowed in AST reaching semantic analysis, the aforementioned is no longer possible.Details
The AST generated by the
closureiters
transformation always looked as follows:where
body
defines the code blocks associated with each state value, like so:The control-flow described by the
goto
(nkGotoState
) followed by the labels (nkState
) is equally representable by the use of a case statement, which is what is now done after this commit.To summarize the change:
nkGotoState
nodes in AST reaching semclosureiters
to generate a case statement for the dispatcher and to not depend onnkState
nkGotoState
andnkState
nkState
node kindNodes with the
nkGotoState
kind now only exists during the transformation, but never before or after.Notes for Reviewers
jsgen
andvmgen
don't implement themFinished
magic yet, meaning that.closure
iterators are still not supported by the respective backendsmFinished
support as a follow-up PR