Given a coroutine body
```
int f()
{
a;
co_yield r;
b;
co_return r2;
}
```
this transforms into
```
auto f(auto then)
{
a;
return then(r, [&]()
{
b;
return then(r2);
});
};
```
You can easily extend this to arbitrarily complex statements. The main thing is that obviously, you have to worry about the capture lifetime yourself (coroutines allocate a frame separate from the stack), and the syntax causes nesting for every statement (but you can avoid that using operator overloading, like C++26/29 does for executors)