Re: Best (or any) practices to rewrite spaghetti or METAL/C

2011-02-10 Thread Miklos Szigetvari

 Original Message 
Subject:Re: Best (or any) practices to rewrite spaghetti or METAL/C
Date:   Thu, 10 Feb 2011 08:58:28 +0100
From:   Miklos Szigetvari miklos.szigetv...@isis-papyrus.com
To: IBM Mainframe Discussion List ibm-m...@bama.ua.edu



Hi

If we can consider METAL/C as alternative to rewrite assembler code ?


Re: Best (or any) practices to rewrite spaghetti

2011-02-04 Thread Don Higgins
Miklos, all

Good question.  I'm not sure the following is a best practice, but I've
found it useful in developing z390 in Java and zcobol in z390 assembler.

I have used several callable routines to handle all error messages and
aborts.  One routine called log_error(error_number,error_msg) logs error
message and returns to caller which allows caller to continue on or handle
error.  The other routine named abort_error(error_number,error_message)
logs error and then issues abort.  This approach minimizes insertion of
GOTO's (one abort call), and allows user to maintain the shared routines
which handle error logs, console logs, maximum return codes, etc.

Don Higgins
d...@higgins.net

On Thu, 3 Feb 2011 18:16:57 +0100, Miklos Szigetvari
miklos.szigetv...@isis-papyrus.com wrote:

 Hi

 Asking here for the best practices to rewrite spaghetti assembler
code to use structured programming macros
I think I red a number of  SHARE presentations

My concern is currently the error handling
  Till now, if an error occurred, there  was a JUMP/BRANCH to an error
block, with all the possible error messages , and after a  JUMP/BRANCH
to the module RETURN.
Seems to me , instead of this,  some DOEXIT or ASMLEAVE would be more
complicated

Mikos, all


Re: Best (or any) practices to rewrite spaghetti

2011-02-04 Thread Paul Gilmartin
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=MainLineDo 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)
 | .
 | XRR15,R15Set return code = 0
 | LEAVE MainLine   Exit the routine
 |   ENDDO , MainLineLogicEndDo for MainLine error trap
 |
 |   
 |   * Process MainLine Errors Here *
 |   
 |   SELECT CHI,R15,EQSelect 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 *+2Logic 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
 edja...@phoenixsoftware.com
 http://www.phoenixsoftware.com/


Re: Best (or any) practices to rewrite spaghetti

2011-02-04 Thread Miklos Szigetvari

Hi

Thank you.
Try to consider this, i.e if I can make some common error routine set.
Currently every error label  does something special .


On 2/4/2011 3:31 PM, Don Higgins wrote:

Miklos, all

Good question.  I'm not sure the following is a best practice, but I've
found it useful in developing z390 in Java and zcobol in z390 assembler.

I have used several callable routines to handle all error messages and
aborts.  One routine called log_error(error_number,error_msg) logs error
message and returns to caller which allows caller to continue on or handle
error.  The other routine named abort_error(error_number,error_message)
logs error and then issues abort.  This approach minimizes insertion of
GOTO's (one abort call), and allows user to maintain the shared routines
which handle error logs, console logs, maximum return codes, etc.

Don Higgins
d...@higgins.net

On Thu, 3 Feb 2011 18:16:57 +0100, Miklos Szigetvari
miklos.szigetv...@isis-papyrus.com  wrote:


 Hi

 Asking here for the best practices to rewrite spaghetti assembler
code to use structured programming macros
I think I red a number of  SHARE presentations

My concern is currently the error handling
  Till now, if an error occurred, there  was a JUMP/BRANCH to an error
block, with all the possible error messages , and after a  JUMP/BRANCH
to the module RETURN.
Seems to me , instead of this,  some DOEXIT or ASMLEAVE would be more
complicated

Mikos, all




SV: Best (or any) practices to rewrite spaghetti

2011-02-04 Thread Thomas Berg
 -Ursprungligt meddelande-
 Från: IBM Mainframe Assembler List [mailto:ASSEMBLER-
 l...@listserv.uga.edu] För Paul Gilmartin
 Skickat: den 4 februari 2011 16:09
 Till: ASSEMBLER-LIST@LISTSERV.UGA.EDU
 Ämne: Re: Best (or any) practices to rewrite spaghetti

 On Feb 3, 2011, at 12:57, Edward Jaffe wrote:

snip
  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

I don't quite understand Your problems with SIGNAL.  AFAICS, You use SIGNAL
when the situation is such that You can't handle it within Your REXX routine
logic/context.  That's is, You must abort all processing and (normally) give
a comprehensive error message, maybe also log it.

You describe a situation where a large input file was handled.  If that were
the reason for the crash it means that too much data was stored in memory
(instead of reading smaller amounts at a time from the file or storing
temporary data in a disk dataset).

(BTW, I use in these kinds of error situations a CALL errorroutine where
I do necessary messaging etc, and then in that routine SIGNAL exitroutine.)



Regards,
Thomas Berg
_
Thomas Berg   Specialist   A M   SWEDBANK


Re: Best (or any) practices to rewrite spaghetti

2011-02-04 Thread Rob van der Heij
On Fri, Feb 4, 2011 at 4:40 PM, Thomas Berg thomas.b...@swedbank.se wrote:

 I don't quite understand Your problems with SIGNAL.  AFAICS, You use SIGNAL
 when the situation is such that You can't handle it within Your REXX routine
 logic/context.  That's is, You must abort all processing and (normally) give
 a comprehensive error message, maybe also log it.

The abort all processing is the magic. At best show some diagnostic
information to diagnose the problem. But not everyone can resist the
temptation...

I found some code where a bright soul had put a restart: somewhere
in the REXX program and then a signal restart in the error:
handler. Unfortunately the trapped error was in a procedure so once
the program went though that path, it continued with part of the REXX
variables hidden outside the scope (but filling up memory).

| Rob


Re: SV: Best (or any) practices to rewrite spaghetti

2011-02-04 Thread Paul Gilmartin
On Feb 4, 2011, at 08:40, Thomas Berg wrote:

 I don't quite understand Your problems with SIGNAL.  AFAICS, You use SIGNAL
 when the situation is such that You can't handle it within Your REXX routine
 logic/context.  That's is, You must abort all processing and (normally) give
 a comprehensive error message, maybe also log it.

For that, CALL and EXIT suffice; no need for SIGNAL.

 You describe a situation where a large input file was handled.  If that were
 the reason for the crash it means that too much data was stored in memory

It does not mean that.

 (instead of reading smaller amounts at a time from the file or storing
 temporary data in a disk dataset).

I was not the author.  It became my problem only when I was called on
to analyze it.  Something such as:

/* Rexx */ signal on novalue;  /*
  Doc: signal considered harmful.
*/
I = 0
A:  I = I + 1
   call P
   say I 'was processed by P'
   signal A

P:
   if right( I, 1 ) == 0 then do
   say Ignoring I
   signal A;  end
   /* whatever  */
   return

Much surrounding spaghetti redacted.  When I succeeded, after
several tries, in explaining the problem to the author, I
believe he replaced the CALL and the RETURN with two more
SIGNALs.

I never have a problem with SIGNAL because I have _never_
(except in demonstrations such as above) coded a SIGNAL to
a label.  I always code SIGNAL ON NOVALUE.

There is one larger EXEC of which I was not the author, but
have become the maintainer, which is permeated with SIGNAL
spaghetti.  It reads commands from the terminal with a
hierarchy of recognized subcommands.  But many of the subcommand
processors recognize top-level commands and SIGNAL directly
to their processors.  Necessarily, all the loops are implemented
by SIGNAL, not DO, and all the subcommand processors are
invoked by SIGNAL, not CALL.  I hate it.  But, following the
spaghetti metaphor, once it's cooked it can't be untangled;
it merely breaks.  Someday I'll try setting a switch variable
and RETURN to a SELECT within a DO.  Or adding a unified
lexical analyzer.

-- gil


SV: SV: Best (or any) practices to rewrite spaghetti

2011-02-04 Thread Thomas Berg
 -Ursprungligt meddelande-
 Från: IBM Mainframe Assembler List [mailto:ASSEMBLER-
 l...@listserv.uga.edu] För Paul Gilmartin
 Skickat: den 4 februari 2011 17:54
 Till: ASSEMBLER-LIST@LISTSERV.UGA.EDU
 Ämne: Re: SV: Best (or any) practices to rewrite spaghetti

 On Feb 4, 2011, at 08:40, Thomas Berg wrote:
 
  I don't quite understand Your problems with SIGNAL.  AFAICS, You use
 SIGNAL
  when the situation is such that You can't handle it within Your REXX
 routine
  logic/context.  That's is, You must abort all processing and (normally)
 give
  a comprehensive error message, maybe also log it.
 
 For that, CALL and EXIT suffice; no need for SIGNAL.

I had some cases where CALL didn't work as expected but SIGNAL did.
Maybe the problem was when the exit was a RETURN (external function).


  You describe a situation where a large input file was handled.  If that
 were
  the reason for the crash it means that too much data was stored in
 memory

 It does not mean that.

  (instead of reading smaller amounts at a time from the file or storing
  temporary data in a disk dataset).
 
 I was not the author.  It became my problem only when I was called on
 to analyze it.  Something such as:

 /* Rexx */ signal on novalue;  /*
   Doc: signal considered harmful.
 */
 I = 0
 A:  I = I + 1
call P
say I 'was processed by P'
signal A

 P:
if right( I, 1 ) == 0 then do
say Ignoring I
signal A;  end
/* whatever  */
return


OMG, I didn't foresee such a usage of SIGNAL... 8-o
That is calling (or maybe rather signaling) for problems.

 Much surrounding spaghetti redacted.  When I succeeded, after
 several tries, in explaining the problem to the author, I
 believe he replaced the CALL and the RETURN with two more
 SIGNALs.

 I never have a problem with SIGNAL because I have _never_
 (except in demonstrations such as above) coded a SIGNAL to
 a label.  I always code SIGNAL ON NOVALUE.

 There is one larger EXEC of which I was not the author, but
 have become the maintainer, which is permeated with SIGNAL
 spaghetti.  It reads commands from the terminal with a
 hierarchy of recognized subcommands.  But many of the subcommand
 processors recognize top-level commands and SIGNAL directly
 to their processors.  Necessarily, all the loops are implemented
 by SIGNAL, not DO, and all the subcommand processors are
 invoked by SIGNAL, not CALL.  I hate it.  But, following the
 spaghetti metaphor, once it's cooked it can't be untangled;
 it merely breaks.  Someday I'll try setting a switch variable
 and RETURN to a SELECT within a DO.  Or adding a unified
 lexical analyzer.

 -- gil


Regards,
Thomas Berg
_
Thomas Berg   Specialist   A M   SWEDBANK


Re: Best (or any) practices to rewrite spaghetti

2011-02-04 Thread Bodoh John Robert
Sorry, REXX SIGNAL does not suck; you just don't know how to use it.  It
only trashes the current DO...END structure.  It works just fine if you
code something like:

DO Outerloop = 1 to n
  Call processes_item
End

Process_item:
Signal ...
Return

Any errors encountered in 'Process_item' will not stop Outerloop.

John


-Original Message-
From: IBM Mainframe Assembler List
[mailto:ASSEMBLER-LIST@LISTSERV.UGA.EDU] On Behalf Of Paul Gilmartin
Sent: Friday, February 04, 2011 10:09 AM
To: ASSEMBLER-LIST@LISTSERV.UGA.EDU
Subject: Re: Best (or any) practices to rewrite spaghetti

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=MainLineDo 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)
 | .
 | XRR15,R15Set return code = 0
 | LEAVE MainLine   Exit the routine
 |   ENDDO , MainLineLogicEndDo for MainLine error trap
 |
 |   
 |   * Process MainLine Errors Here *
 |   
 |   SELECT CHI,R15,EQSelect 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 *+2Logic error. Force abend here.
 |   ENDSEL

SV: Best (or any) practices to rewrite spaghetti

2011-02-04 Thread Thomas Berg
 -Ursprungligt meddelande-
 Från: IBM Mainframe Assembler List [mailto:ASSEMBLER-
 l...@listserv.uga.edu] För Rob van der Heij
 Skickat: den 4 februari 2011 17:56
 Till: ASSEMBLER-LIST@LISTSERV.UGA.EDU
 Ämne: Re: Best (or any) practices to rewrite spaghetti

 On Fri, Feb 4, 2011 at 4:40 PM, Thomas Berg thomas.b...@swedbank.se
 wrote:

  I don't quite understand Your problems with SIGNAL.  AFAICS, You use
 SIGNAL
  when the situation is such that You can't handle it within Your REXX
 routine
  logic/context.  That's is, You must abort all processing and (normally)
 give
  a comprehensive error message, maybe also log it.

 The abort all processing is the magic. At best show some diagnostic
 information to diagnose the problem. But not everyone can resist the
 temptation...

 I found some code where a bright soul had put a restart: somewhere
 in the REXX program and then a signal restart in the error:
 handler. Unfortunately the trapped error was in a procedure so once
 the program went though that path, it continued with part of the REXX
 variables hidden outside the scope (but filling up memory).


I don't understand how anyone can have any decent confidence in a routine
that continue processing after a SIGNAL.  It's more or less like continue
driving after taking LSD.  :)



Regards,
Thomas Berg
_
Thomas Berg   Specialist   A M   SWEDBANK


REXX SIGNAL (Was: Best (or any) practices to rewrite spaghetti)

2011-02-04 Thread Edward Jaffe

On 2/4/2011 7:08 AM, Paul Gilmartin wrote:

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 didn't know that about REXX SIGNAL. The issues you describe are similar to
those I described in my post to this thread. At least an HLASM programmer can
design his/her program to deal with these issues. Apparently, a REXX programmer
is just screwed. :-(

--
Edward E Jaffe
Phoenix Software International, Inc
831 Parkview Drive North
El Segundo, CA 90245
310-338-0400 x318
edja...@phoenixsoftware.com
http://www.phoenixsoftware.com/


Re: Best (or any) practices to rewrite spaghetti

2011-02-03 Thread Tony Thigpen
Personally, I consider a 'branch to abnormal exit' much better than
trying to unwind all the 'perform' levels, be it COBOL or Assembler.

I have seen programs where they attempted to unwind everything during an
error and ended up processing code unintentionally.

Tony Thigpen

-Original Message -
 From: Miklos Szigetvari
 Sent: 02/03/2011 12:16 PM
 Hi

 Asking here for the best practices to rewrite spaghetti assembler
 code to use structured programming macros
 I think I red a number of  SHARE presentations

 My concern is currently the error handling
  Till now, if an error occurred, there  was a JUMP/BRANCH to an error
 block, with all the possible error messages , and after a  JUMP/BRANCH
 to the module RETURN.
 Seems to me , instead of this,  some DOEXIT or ASMLEAVE would be more
 complicated




Re: Best (or any) practices to rewrite spaghetti

2011-02-03 Thread John Ehrman
There's no reason your SP macro code can't include a jump to an error
handler when an error occurs.

Donald Knuth once wrote a scholarly article called Structured Programming
with GOTO Statements where he showed that attempts to be purely
structured were often more obscure than using a GOTO when it was simplest.

Miklos Szigetvari asked:

 Asking here for the best practices to rewrite spaghetti assembler
 code to use structured programming macros
 I think I red a number of  SHARE presentations

 My concern is currently the error handling
 Till now, if an error occurred, there  was a JUMP/BRANCH to an error
 block, with all the possible error messages , and after a  JUMP/BRANCH
 to the module RETURN.
 Seems to me, instead of this,  some DOEXIT or ASMLEAVE would be more
 complicated


Re: Best (or any) practices to rewrite spaghetti

2011-02-03 Thread Rob Scott
One of the ways I avoid too many nested IF statements is to use straddling 
DO/ENDDO around code that may require several let's get outta here now 
moments. For example :

DO,
  Some code
  DOEXIT (TM,flag,bit,NO)
  ...
  Some more code
  DOEXIT (CLC,field,NE,value)
  ...
  Call some subroutine
  DOEXIT (LTR,R15,R15,NZ)
  ...etc
ENDDO

You could also label the DO (eg MAIN) and then use something like ASMLEAVE 
MAIN from anywhere later in the logic.



Rob Scott
Lead Developer
Rocket Software
275 Grove Street * Newton, MA 02466-2272 * USA
Tel: +1.617.614.2305
Email: rsc...@rs.com
Web: www.rocketsoftware.com


-Original Message-
From: IBM Mainframe Assembler List [mailto:ASSEMBLER-LIST@LISTSERV.UGA.EDU] On 
Behalf Of Johanson, Adam
Sent: 03 February 2011 18:42
To: ASSEMBLER-LIST@LISTSERV.UGA.EDU
Subject: Re: Best (or any) practices to rewrite spaghetti

John Ehrman wrote:

 There's no reason your SP macro code can't include a jump to an error handler 
 when an error occurs.

 Donald Knuth once wrote a scholarly article called Structured Programming 
 with GOTO Statements where he showed that
 attempts to be purely structured were often more obscure than using a GOTO 
 when it was simplest.

Yeah, what they said.

I recently changed a couple of multi-thousand-line programs to use SPMs 
and my first thought was that I was going to eliminate all of the branches in 
them. But as I got going, it became pretty apparent that to do so would require 
things that made the code a little bit less readable, like lengthening 
IF-blocks and adding a couple of more indentation spacings to blocks that 
already had a fair amount of indentation to them.

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.

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.

Adam Johanson
IMS Systems Programming
USAA


Re: Best (or any) practices to rewrite spaghetti

2011-02-03 Thread Edward Jaffe

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.

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=MainLineDo 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)
| .
| XRR15,R15Set return code = 0
| LEAVE MainLine   Exit the routine
|   ENDDO , MainLineLogicEndDo for MainLine error trap
|
|   
|   * Process MainLine Errors Here *
|   
|   SELECT CHI,R15,EQSelect 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 *+2Logic 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
edja...@phoenixsoftware.com
http://www.phoenixsoftware.com/


Re: Best (or any) practices to rewrite spaghetti

2011-02-03 Thread Roger Bolan
I'm sure others will tell you about coding techniques and structured macros
etc.  My advice when improving old spaghetti assembler code is this:
Make sure you have a regression test library ready to insure that the
behavior of the new code matches the old code.  Spaghetti code can hide a
lot of little subtleties and you need to make sure that the more structured,
more readable code doesn't change or miss anything.   You also need to
compare performance.  On more than one occasion we found the performance of
the old spaghetti code module hard to beat or match.
--Roger

On Thu, Feb 3, 2011 at 10:16 AM, Miklos Szigetvari 
miklos.szigetv...@isis-papyrus.com wrote:

Hi

Asking here for the best practices to rewrite spaghetti assembler
 code to use structured programming macros
 I think I red a number of  SHARE presentations

 My concern is currently the error handling
  Till now, if an error occurred, there  was a JUMP/BRANCH to an error
 block, with all the possible error messages , and after a  JUMP/BRANCH
 to the module RETURN.
 Seems to me , instead of this,  some DOEXIT or ASMLEAVE would be more
 complicated



Re: Best (or any) practices to rewrite spaghetti

2011-02-03 Thread Rob van der Heij
On Thu, Feb 3, 2011 at 6:29 PM, Tony Thigpen t...@vse2pdf.com wrote:

 Personally, I consider a 'branch to abnormal exit' much better than
 trying to unwind all the 'perform' levels, be it COBOL or Assembler.

 I have seen programs where they attempted to unwind everything during an
 error and ended up processing code unintentionally.

My father used to say that 'anything with too in it is bad'  and I
had to think of that when I was recently trying to untange some
ancient code. I allow myself premature exit to the end of the routine
as well, but it's a glippery slope. At least I find that when you
don't give it enough thought, it's easy to end up with a lot of them
and make following the flow much harder.

My dialect of Structured Assembler does a combined call with
automatic exit on nonzero return code  Though this is the same as
coding that extra branch, the simplification to me is that it's always
the same NZ that does the exit. If necessary, I will put a number of
those diverse tests in a subroutine and let that conclude Z or NZ.
That avoids things like this:
  CLC   DEVADDR,RANGELO
  BL EXIT
  CLC   DEVADDR,RANGEHI
  BH EXIT

| Rob


Re: Best (or any) practices to rewrite spaghetti

2011-02-03 Thread Miklos Szigetvari

Hi

Thank you very much for everybody.
The answers has confirmed my view , to overuse a good technique can lead
to obscure results.

On 2/3/2011 9:15 PM, Roger Bolan wrote:

I'm sure others will tell you about coding techniques and structured macros
etc.  My advice when improving old spaghetti assembler code is this:
Make sure you have a regression test library ready to insure that the
behavior of the new code matches the old code.  Spaghetti code can hide a
lot of little subtleties and you need to make sure that the more structured,
more readable code doesn't change or miss anything.   You also need to
compare performance.  On more than one occasion we found the performance of
the old spaghetti code module hard to beat or match.
--Roger

On Thu, Feb 3, 2011 at 10:16 AM, Miklos Szigetvari
miklos.szigetv...@isis-papyrus.com  wrote:


Hi

Asking here for the best practices to rewrite spaghetti assembler
code to use structured programming macros
I think I red a number of  SHARE presentations

My concern is currently the error handling
  Till now, if an error occurred, there  was a JUMP/BRANCH to an error
block, with all the possible error messages , and after a  JUMP/BRANCH
to the module RETURN.
Seems to me , instead of this,  some DOEXIT or ASMLEAVE would be more
complicated