But as one can see c might end within the try catch which goes against the initial semantic of the program.
A solution that seems to work
Then I read again your solution for the while Fengyun and it inspired me :)
We assume the catch doesnt contain any yieldval for now. And I omitted the finally block too, but since I assume it doesnt contain yieldval for the moment it can just be added after the catch with no problems.
[[try {
Z1*
} catch {
e2
}]] c
would become
'{
val co = coroutine(Z1*)
def f() = {
var tryRet = None
try {
tryRet = co.continue()
} catch {
e2
}
if (tryRet.isDefined) {
[[yieldval(tryRet.get)]] {() => '{ f() } } //this could be simplified to the actual code returned by the transformation of yieldval to avoid one more call.
} else ${ c() }
}
f()
}
If the execution lands in if (tryRet.isDefined):
This means the try actually yielded something. In this case we can yield the value yielded by the try. After the yield we can come back to f to execute what is left of the coroutine containing the try body.
There are two possibility for landing in the else: 1) the subcoroutine actually is done 2) an exception was thrown by the body of the try and caught. In both cases we continue by calling c()
I think the drawback from my solution is that I end up creating a new coroutine which could be a bit heavy to do within a function. So it might be nice to lift the created coroutine in the containing Coroutine class.
It seems I found some sort of solution. The main challenge for the try catch was for me to keep the c out of the try catch.
My first iterations on the problem (which didnt work):
At first I thought I could do something like this:
which would become
But as one can see
c
might end within the try catch which goes against the initial semantic of the program.A solution that seems to work
Then I read again your solution for the
while
Fengyun and it inspired me :) We assume the catch doesnt contain any yieldval for now. And I omitted the finally block too, but since I assume it doesnt contain yieldval for the moment it can just be added after the catch with no problems.would become
If the execution lands in if (tryRet.isDefined): This means the try actually yielded something. In this case we can yield the value yielded by the try. After the yield we can come back to f to execute what is left of the coroutine containing the try body.
There are two possibility for landing in the else: 1) the subcoroutine actually is done 2) an exception was thrown by the body of the try and caught. In both cases we continue by calling c()
I think the drawback from my solution is that I end up creating a new coroutine which could be a bit heavy to do within a function. So it might be nice to lift the created coroutine in the containing Coroutine class.