We use a similar approach as Vulcan:What I'm interested in: how the code recover block in the begin/end sequence block is translated by the compiler.
Code: Select all
BEGIN SEQUENCE ... RECOVER [USING varname]... END SEQUENCE
The outer block is a
Code: Select all
try .. catch
inside the catch we check to see if the exception ex was a 'WrappedException' which happens when you call BREAK in your code with a value.
If it is a normal Exception (from the framework) then we create a new WrappedException.
We then extract the value from this WrappedException and assign it to the variable in the RECOVER statement
the try block in this try catch contains the inner try statement
The inner try statement is a Try .. FInally where we call
Code: Select all
CompilerServices.EnterBeginSequence()
Code: Select all
CompilerServices.ExitBeginSequence()
The rest of this try block is the original code inside the BEGIN SEQUENCE
These 2 helper methods are called so the runtime function _CanBreak() knows that we are in a BEGIN SEQUENCE.. END. Inside the compilerServices class we keep track of the "BreakLevel" for the current thread.
The BREAK <value> statement is translated to a call to
Code: Select all
throw WrappedException{<value>}
Robert