-
Notifications
You must be signed in to change notification settings - Fork 21
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
Add a RewriteControlFlow
phase (return
/continue
/break
)
#393
Comments
?
/return
/continue
/break
...)
PR #559 made some progress toward this issue, but we need to improve it to close this. |
So if I understand well, to complete this issue we need this Let's consider (a simplified version of) the example from the issue description:
And an example written with a
They should be rewritten respectively as:
The crucial rule to rewrite like this would be recognizing patterns like:
and rewrite it to:
In case there is no To avoid recursing twice, we would need to pass the following expression top-down in the recursive calls (in an argument) and propagate the information of whether there is a |
We also need another phase (or a second visitor inside drop_needless_returns) to rewrite
as
As they can be nested it needs its own visitor. |
I thought #907 is only partially implementing this? |
ok, @W95Psp please clean up and close what's done 🙏🏻 |
?
/return
/continue
/break
...)return
/continue
/break
)
return
/continue
/break
)RewriteControlFlow
phase (return
/continue
/break
)
I am designing the part about loops. First attempt:
For all this to work well, I suspect that we should treat the body of the loop after phase |
A few additions:
|
Here is an example of the rewriting:
After the transformation (here with a classic fold but we will define a specific fold that will do this internal pattern matching on the accumulator, and we will also use
|
@maximebuyse @W95Psp what's the state here? |
We wanted to work on that together in CC, but that will not happen this week (I thought I could do CC today, but after being awake for a bit, I think it's wiser to work slowly from home and recover). @maximebuyse correct me if I'm wrong, but I think the PR (#988) is mostly ready, only the F* parts are missing. Thus there is two things to do:
|
I am quite happy with the order of phases now. But for sure there will be some cleanup to do, and we might change a bit the code we emit while writing the f*. |
This introduced a regression https://github.com/inria-prosecco/circus-green/actions/runs/11510030233 |
We want a phase that eliminates explicit control flow (say a
return
or abreak
) by moving or duplicating code.We want to rewrite the control flow so that every
return
,break
orcontinue
always appears in a return position in our AST. Returns in return positions can be dropped: e.g.if ... then {return 3;} else {return 5;}
can be simplified inif ... then {3} else {5}
.return
s appearing outside of a loop (this was PR Add RewriteControlFlow phase. #907);return
,break
andcontinue
within a loop.See Details below for a lengthy explanation.
Details
Question marks (but also
return
and friends) used to be transformed in a monadic style.In this style, computations are promoted to a
Result
orOption
monad, andpure
andbind
nodes are inserted heavily.For instance, let's consider the following function:
This would be transformed to this monadic F* function, where
(let*)
is basically abind
node in the option monad:While this is a correct translation, lifting everything to a monad and running the monad is a bit heavy.
Instead, the control flow of the Rust function
test
can be rewritten into:Rewriting control flow is about pushing
?
s to return positions. When?
appears deep in aif
/match
node itself nested in a sequential expression (e.g. a sequence or a function call), then such rewriting can result in code duplication. Example:The text was updated successfully, but these errors were encountered: