On Feb 3, 2011, at 12:57, Edward Jaffe wrote:
> On 2/3/2011 10:41 AM, Johanson, Adam wrote:
>> Then, I told myself that the whole point of the exercise was to make
>> the code more readable, so a branch to a return-to-caller label every now
>> and then didn't really defeat the purpose and actually _did_ help things.
>> IMHO, rather than seeing a big nested IF statement and chasing down the end
>> point just to figure out that you're gonna return to the caller is a bit
>> more involved than realizing, "Oh, I'm just getting out of Dodge."
>
> Yup. You can find analogs in other languages. For example SIGNAL and EXIT in
> REXX. Programs can become unnecessarily complex if you require every condition
> to be surfaced back up through a deeply-nested logic hierarchy.
>
Rexx SIGNAL sucks. One one hand, it trashes the DO...END structure; OTOH
it leaves the subroutine return stack hanging (a naive colleague once
authored a Rexx program that used SIGNAL to "get out of Dodge". He tested
it, apparently successfully. It crashed on a large input data set when
the stack overflowed. PITA to refactor.) Absence of a construct to
exit a nest of procedures impels Rexx programmers to eschew subroutines
in contexts where they'd otherwise be preferable.
I'd cherish an extension to support "LEAVE control-variable" where
control-variable belongs to a loop in an outer procedure exposed in
the inner procedure containing the LEAVE.
But Rexx does support LEAVE and ITERATE for outer DOs. I habitually
code:
do OuterLoop = 1 for 1
...
do
...
do
...
leave OuterLoop
...
end
...
end
...
end OuterLoop
> Depending on your program design, an "signal/exit jump from anywhere" can be
> problematic when using a stack for (at least) saving/restoring registers. If
> you
> "signal/exit" with the stack pushed several levels deep, your current
> registers
> might not be appropriate for the "signal/exit" routine and, if the stack is
> needed for any processing after that, you'll need a way to unwind the stack to
> the appropriate level or else things might go horribly wrong--for example when
> the "signal/exit" routine itself tries to return to the original caller.
>
> The easiest way to avoid this is to never branch to a "signal/exit" label from
> an inner routine. Or put another way, each stack level has its own
> "signal/exit"
> routine.
>
> Another way we've handled the "signal/exit jump from anywhere" is to save the
> appropriate stack control and registers in some easily addressable non-stack
> storage from which they are loaded/copied as one of the very first things the
> "signal/exit" routine does.
>
> FWIW, when writing code from scratch it is often possible to avoid
> "signal/exit"
> branches entirely by enclosing the logic within two nested simple DOs as
> shown.
> We have used this technique quite effectively in some very large and complex
> programs. (This is only an example. Many other variants of this approach are
> possible.)
>
> | DO LABEL=MainLine Do for MainLine routine
> |
> | ************************************
> | * Process MainLine Logic Here *
> | ************************************
> | DO LABEL=MainLineLogic Do for MainLine logic
> | .
> | .(some deeply nested code here discovers an error)
> | LHI R15,ErrorCode1 Load error code
> | LEAVE MainLineLogic Go perform error processing
> | .
> | .(another error is discovered)
> | LHI R15,ErrorCode2 Load error code
> | LEAVE MainLineLogic Go perform error processing
> | .
> | .(this can be a very large and complex routine)
> | .
> | XR R15,R15 Set return code = 0
> | LEAVE MainLine Exit the routine
> | ENDDO , MainLineLogic EndDo for MainLine error trap
> |
> | ************************************
> | * Process MainLine Errors Here *
> | ************************************
> | SELECT CHI,R15,EQ Select error code
> | WHEN ErrorCode1 ErrorCode1
> | (whatever) Issue msg, set retcode/rsn, etc.
> | WHEN ErrorCode2 ErrorCode2
> | (whatever) Issue msg, set retcode/rsn, etc.
> | OTHRWISE , Unknown Error Code
> | J *+2 Logic error. Force abend here.
> | ENDSEL , EndSel error code
> | ENDDO , MainLine EndDo for MainLine routine
>
>
>> And you've probably come across it in the SHARE presentations that
>> you've seen, but if you're going to do this, download Ed Jaffe's FLOWASM
>> exit. It makes life easier.
>
> I'm glad you found it useful. 8-)
>
> --
> Edward E Jaffe
> Phoenix Software International, Inc
> 831 Parkview Drive North
> El Segundo, CA 90245
> 310-338-0400 x318
> [email protected]
> http://www.phoenixsoftware.com/