[comp.lang.asm370] memo on my structure assembler macros

phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (04/12/91)

*******************************************************************************
*Note that you can find these macros by FTP to vmd.cso.uiuc.edu (128.174.5.98)*
*and cd to phil.194 (no password to read).  If you cannot FTP and want a copy,*
*send email to phil-howard@uiuc.edu and ask for a copy, giving a BITNET node  *
*of a CMS node if you have one.                                               *
*******************************************************************************

                STRUCTURED ASSEMBLER PROGRAMMING MACROS
 
                                   by
 
                          Philip David Howard
 
               University of Illinois at Urbana-Champaign
                       Computing Services Office
 
 
 
The structured assembler macros provide two types of control structures:
decision and loop.  Listed below are the macros and which types they are
involved in:
 
    $AND      loop decision
    $BREAK    loop
    $DO       loop
    $ELSE          decision
    $ELSIF         decision
    $END      loop decision
    $EQU      loop decision
    $IF            decision
    $NEXT     loop
    $OR       loop decision
    $REPEAT   loop
    $THEN          decision
    $UNTIL    loop
    $WHILE    loop
 
 
The $EQU macro generates symbols needed in the generation of branch
instructions as well as generates symbols for register and save area
displacement equates.  It generates no executable code.  It should be
added to programs as a simple macro call near the end of the program.
 
 
Both types of control structures use a symbolic condition expression
that is to be matched with the actual condition codes generated by the
CPU executing programmer supplied instructions within the control
structure.  The decision control structure illustrates this most simply.
 
         $IF   condition-1
           .     \
           .      | programmer provided instruction(s)
           .     /  that set a condition code when executed
         $THEN
           .     \
           .      | programmer provided instructions(s) to be executed
           .     /  only if the conditions above match
    ________________
   /     $ELSE      \ optional
           .     \
           .      | programmer provided instructions(s) to be executed
           .     /  only if the conditions above do not match
   \________________/
         $END
 
 
The condition-expression on the $IF statement is one or more of the
condition symbols defined in the $EQU macro.  These symbols are
 
    ALL      CC2      GT       LT       NEGATIVE OVER
    ANY      CC3      HIGH     LZERO    NOT      OVERFLOW
    BORROW   EQ       LE       MINUS    OFF      POS
    CARRY    EQUAL    LESS     MIXED    ON       POSITIVE
    CC0      GE       LOGZERO  NE       ONE      ZERO
    CC1      GREATER  LOW      NEG      ONES     ZEROS
 
See the $EQU MACRO for the exact defined values for these symbols.
The symbols are equated to the same values as would be used in branch
on condition instructions and may be used with these instructions if
desired.  The symbols ALL, ANY, and NOT are equated to branch on all
conditions.  Condition expressions may be formed if done carefully.
One typical form is negated conditions.  Some examples are:
 
    NOT-EQUAL         matches any condition except equal
    NOT-MINUS         matches any condition except minus
    NOT-NEG-OVERFLOW  matches any condition except negative or overflow
 
Another typical form is summed conditions.  Some examples are:
 
    EQUAL+POS         matches an equal or a positive condition
    CC1+CC2           matches a CC1 or a CC2 condition
 
Care must be taken NOT to add two conditions with the same bits being
on, or to subtract a 1 bit from a 0 bit in any condition.  Arithmetic
operations are really meaningless for conditions codes, but may be used
if care is taken.
 
 
The instructions that follow the $IF instruction (call to macro) are the
ones that generate the condition code that will be matched with the
condition expression on the $IF.  These instructions are ended with the
$THEN instruction.  If the conditions match, then the instructions that
follow the $THEN will be executed.  These instructions are ended with a
$ELSE, $ELSIF, or $END instruction.  If the conditions fail to match,
and if one of the ELSE instructions is used, then the instructions that
are a part of that group will be executed.  The $ELSE macro defines a
simple alternative for failing conditions.  The $ELSIF macro makes an
ELSE group that really starts a new IF structure without any nesting.
Here is an example:
 
         $IF    condition-1
           (instructions to match cond-1)
         $THEN
           (executed if cond-1 matches)
         $ELSIF condition-2               \
           (instructions to match cond-2)  |
         $THEN                             | these are executed only
           (executed if cond-2 matches)    | if condition-1 fails to
         $ELSE                             | match.
           (executed if cond-2 fails)      |
         $END                             /
 
The sequence of ELSIF instructions may be quite large.  There is no
limit that applies to a single structure.  A limit of near ten thousand
per program applies due to limits on the generation of branching labels
and the number of macros that can be invoked.
 
The $END macro terminates one structure, ending the instructions in the
final $ELSE group, or in the final $THEN group if no $ELSE is used.
 
 
Loop structures may have tests performed at the entry to the loop,
or at the end of the loop to cause at least one pass to always be
executed.  If a test is to be performed at loop entry, the $WHILE
macro is used to begin the loop, to declare the condition expression,
and to begin the instruction group which is to be matched with the
condition expression.  Here is an example:
 
         $WHILE condition-1
           .     \
           .      | programmer provided instruction(s)
           .     /  that set a condition code when executed
         $DO
           .     \
           .      | programmer provided instructions(s) to be executed
           .     /  as the main body of the loop
         $END
 
The loop body instructions will be executed as long as the condition
instructions continue to match the condition expression defined on the
$WHILE macro.  The $END macro ends the loop structure just as it did
for the decision structure
 
Another form of loop structure enters the loop body before the test
is applied.  This assures that at least one pass of the loop body
occurs.  This is necessary for cases where the loop body contributes
to the condition code to be evaluated.  Here is an example:
 
         $REPEAT
           .     \
           .      | programmer provided instructions(s) to be executed
           .     /  as the main body of the loop
         $UNTIL condition-1
           .     \
           .      | programmer provided instruction(s)
           .     /  that set a condition code when executed
         $END
 
These loops begin with a $REPEAT macro followed by the loop body.
The condition expression is defined with the $UNTIL instruction
and is followed by the code to evaluate the condition code for
matching.  As you can expect by now, the loop ends with a $END.
 
 
These 2 loop forms may be combined into one where there are actually
two different looping tests, the first of which controls entry to
the loop.  The combination is formed this way:
 
         $WHILE condition-1
           .     \
           .      | programmer provided instruction(s)
           .     /  that set a condition code when executed
         $DO
           .     \
           .      | programmer provided instructions(s) to be executed
           .     /  as the main body of the loop
         $UNTIL condition-2
           .     \
           .      | programmer provided instruction(s)
           .     /  that set a condition code when executed
         $END
 
 
The sequence of steps always begins by testing the loop entry condition.
If the condition matches, the body is executed and then the exit
condition is checked.  It the exit condition FAILS, the loop will
continue by checking the entry condition again.  If it is not necessary
to retest the entry condition, then the loop should be coded as a
$REPEAT-$UNTIL-$END nested inside an $IF-$THEN-$END.
 
One final form of loop is a simple infinite loop:
 
         $REPEAT
           .     \
           .      | programmer provided instructions(s) to be executed
           .     /  as the main body of the loop
         $END
 
 
To exit the inifinite loop, or any other loop, the $BREAK macro may be
used.  $BREAK works like an executable instruction and causes a branch
to the instruction following the $END of the inner-most loop structure.
$BREAK uses no operands.  To control the breaking conditions, place the
$BREAK inside a nested decision ($IF) structure.  $BREAK always bypasses
all nested decision structures to get to the loop structure.
 
The $NEXT instruction works similar to the $BREAK except that instead of
exiting the loop, it causes a branch to the end of the body of the loop
to start the testing again.  It would be preferrable to place the
remainder of the loop body in a decision structure instead of using
$NEXT.
 
 
For both types of control structures, more complex condition systems may
be used for complex condition testing.  Two macros are provided for this
purpose:  $AND and $OR.  Both of these macros require a condition
expression as an operand.
 
The $AND ends a group of instructions that follow a $IF, $WHILE, or a
$UNTIL instruction.  If the preceeding condition fails to match, then
the condition(s) defined afterwards will not be evaluated and the entire
complex set of conditions will be considered failing.  If the preceeding
condition matches, then the condition following the $AND will be
evaluated and all further tests will be based on this new evaluation
of condition.
 
The $OR works like $AND except that its condition is evaluated only
when the preceeding condition fails to match.
 
Both of thes macros, $AND and $OR function serially.  This means
that there is no equivalent to grouping logical expressions within
parenthesis.  The precedence of logical operators is equal and to
the left (or up in assembler).
 
A complex decision structure may look like this:
         $IF    condition-1
           (instructions to match cond-1)
         $AND   condition-2
           (instructions to match cond-2)
         $OR    condition-3
           (instructions to match cond-3)
         $THEN
           (executed if (cond-1 & cond-2) | cond-3 matches)
         $ELSIF condition-4
           (instructions to match cond-4)
         $OR    condition-5
           (instructions to match cond-5)
         $AND   condition-6
           (instructions to match cond-6)
         $THEN
           (executed if cond-4 | (cond-5 & cond-6) matches)
         $ELSE
           (executed if ((c1 & c2) | c3 ) & (c4 | (c5 & c6)) fails)
         $END
 
 
It is permissable to nest structures within the condition evaluation
parts.  There is no equivalent to this capability in common high
level languages except for the ?: operators in C.
 
 
The preceeding description of the structured programming macros and the
structured programming macros themselves are considered a work of art.
ABSOLUTELY NO WARRANTY is expressed, implied, or applicable in any way.
 
Do not send bug reports to:  (after all, works of art are flawless)
 
Author:     Philip David Howard,         Research Programmer
Internet:   <phil-howard@uiuc.edu>,      Bitnet (if you must): <phil@uiucvmd>
Voicenet:   (USA) 217-244-6246
Papernet:   Computing Services Office,   Room 1519
            Digital Computer Lab,        MC-256
            University of Illinois at Urbana-Champaign
            1304 West Springfield Avenue
            Urbana, IL  USA-61801
-- 
 /***************************************************************************\
/ Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu                              \
\ Lietuva laisva -- Brivu Latviju -- Eesti vabaks                             /
 \***************************************************************************/

phil@UX1.CSO.UIUC.EDU (Phil Howard KA9WGN) (04/12/91)

*******************************************************************************
*Note that you can find these macros by FTP to vmd.cso.uiuc.edu (128.174.5.98)*
*and cd to phil.194 (no password to read).  If you cannot FTP and want a copy,*
*send email to phil-howard@uiuc.edu and ask for a copy, giving a BITNET node  *
*of a CMS node if you have one.                                               *
*******************************************************************************

                STRUCTURED ASSEMBLER PROGRAMMING MACROS

                                   by

                          Philip David Howard

               University of Illinois at Urbana-Champaign
                       Computing Services Office



The structured assembler macros provide two types of control structures:
decision and loop.  Listed below are the macros and which types they are
involved in:

    $AND      loop decision
    $BREAK    loop
    $DO       loop
    $ELSE          decision
    $ELSIF         decision
    $END      loop decision
    $EQU      loop decision
    $IF            decision
    $NEXT     loop
    $OR       loop decision
    $REPEAT   loop
    $THEN          decision
    $UNTIL    loop
    $WHILE    loop


The $EQU macro generates symbols needed in the generation of branch
instructions as well as generates symbols for register and save area
displacement equates.  It generates no executable code.  It should be
added to programs as a simple macro call near the end of the program.


Both types of control structures use a symbolic condition expression
that is to be matched with the actual condition codes generated by the
CPU executing programmer supplied instructions within the control
structure.  The decision control structure illustrates this most simply.

         $IF   condition-1
           .     \
           .      | programmer provided instruction(s)
           .     /  that set a condition code when executed
         $THEN
           .     \
           .      | programmer provided instructions(s) to be executed
           .     /  only if the conditions above match
    ________________
   /     $ELSE      \ optional
           .     \
           .      | programmer provided instructions(s) to be executed
           .     /  only if the conditions above do not match
   \________________/
         $END


The condition-expression on the $IF statement is one or more of the
condition symbols defined in the $EQU macro.  These symbols are

    ALL      CC2      GT       LT       NEGATIVE OVER
    ANY      CC3      HIGH     LZERO    NOT      OVERFLOW
    BORROW   EQ       LE       MINUS    OFF      POS
    CARRY    EQUAL    LESS     MIXED    ON       POSITIVE
    CC0      GE       LOGZERO  NE       ONE      ZERO
    CC1      GREATER  LOW      NEG      ONES     ZEROS

See the $EQU MACRO for the exact defined values for these symbols.
The symbols are equated to the same values as would be used in branch
on condition instructions and may be used with these instructions if
desired.  The symbols ALL, ANY, and NOT are equated to branch on all
conditions.  Condition expressions may be formed if done carefully.
One typical form is negated conditions.  Some examples are:

    NOT-EQUAL         matches any condition except equal
    NOT-MINUS         matches any condition except minus
    NOT-NEG-OVERFLOW  matches any condition except negative or overflow

Another typical form is summed conditions.  Some examples are:

    EQUAL+POS         matches an equal or a positive condition
    CC1+CC2           matches a CC1 or a CC2 condition

Care must be taken NOT to add two conditions with the same bits being
on, or to subtract a 1 bit from a 0 bit in any condition.  Arithmetic
operations are really meaningless for conditions codes, but may be used
if care is taken.


The instructions that follow the $IF instruction (call to macro) are the
ones that generate the condition code that will be matched with the
condition expression on the $IF.  These instructions are ended with the
$THEN instruction.  If the conditions match, then the instructions that
follow the $THEN will be executed.  These instructions are ended with a
$ELSE, $ELSIF, or $END instruction.  If the conditions fail to match,
and if one of the ELSE instructions is used, then the instructions that
are a part of that group will be executed.  The $ELSE macro defines a
simple alternative for failing conditions.  The $ELSIF macro makes an
ELSE group that really starts a new IF structure without any nesting.
Here is an example:

         $IF    condition-1
           (instructions to match cond-1)
         $THEN
           (executed if cond-1 matches)
         $ELSIF condition-2               \
           (instructions to match cond-2)  |
         $THEN                             | these are executed only
           (executed if cond-2 matches)    | if condition-1 fails to
         $ELSE                             | match.
           (executed if cond-2 fails)      |
         $END                             /

The sequence of ELSIF instructions may be quite large.  There is no
limit that applies to a single structure.  A limit of near ten thousand
per program applies due to limits on the generation of branching labels
and the number of macros that can be invoked.

The $END macro terminates one structure, ending the instructions in the
final $ELSE group, or in the final $THEN group if no $ELSE is used.


Loop structures may have tests performed at the entry to the loop,
or at the end of the loop to cause at least one pass to always be
executed.  If a test is to be performed at loop entry, the $WHILE
macro is used to begin the loop, to declare the condition expression,
and to begin the instruction group which is to be matched with the
condition expression.  Here is an example:

         $WHILE condition-1
           .     \
           .      | programmer provided instruction(s)
           .     /  that set a condition code when executed
         $DO
           .     \
           .      | programmer provided instructions(s) to be executed
           .     /  as the main body of the loop
         $END

The loop body instructions will be executed as long as the condition
instructions continue to match the condition expression defined on the
$WHILE macro.  The $END macro ends the loop structure just as it did
for the decision structure

Another form of loop structure enters the loop body before the test
is applied.  This assures that at least one pass of the loop body
occurs.  This is necessary for cases where the loop body contributes
to the condition code to be evaluated.  Here is an example:

         $REPEAT
           .     \
           .      | programmer provided instructions(s) to be executed
           .     /  as the main body of the loop
         $UNTIL condition-1
           .     \
           .      | programmer provided instruction(s)
           .     /  that set a condition code when executed
         $END

These loops begin with a $REPEAT macro followed by the loop body.
The condition expression is defined with the $UNTIL instruction
and is followed by the code to evaluate the condition code for
matching.  As you can expect by now, the loop ends with a $END.


These 2 loop forms may be combined into one where there are actually
two different looping tests, the first of which controls entry to
the loop.  The combination is formed this way:

         $WHILE condition-1
           .     \
           .      | programmer provided instruction(s)
           .     /  that set a condition code when executed
         $DO
           .     \
           .      | programmer provided instructions(s) to be executed
           .     /  as the main body of the loop
         $UNTIL condition-2
           .     \
           .      | programmer provided instruction(s)
           .     /  that set a condition code when executed
         $END


The sequence of steps always begins by testing the loop entry condition.
If the condition matches, the body is executed and then the exit
condition is checked.  It the exit condition FAILS, the loop will
continue by checking the entry condition again.  If it is not necessary
to retest the entry condition, then the loop should be coded as a
$REPEAT-$UNTIL-$END nested inside an $IF-$THEN-$END.

One final form of loop is a simple infinite loop:

         $REPEAT
           .     \
           .      | programmer provided instructions(s) to be executed
           .     /  as the main body of the loop
         $END


To exit the inifinite loop, or any other loop, the $BREAK macro may be
used.  $BREAK works like an executable instruction and causes a branch
to the instruction following the $END of the inner-most loop structure.
$BREAK uses no operands.  To control the breaking conditions, place the
$BREAK inside a nested decision ($IF) structure.  $BREAK always bypasses
all nested decision structures to get to the loop structure.

The $NEXT instruction works similar to the $BREAK except that instead of
exiting the loop, it causes a branch to the end of the body of the loop
to start the testing again.  It would be preferrable to place the
remainder of the loop body in a decision structure instead of using
$NEXT.


For both types of control structures, more complex condition systems may
be used for complex condition testing.  Two macros are provided for this
purpose:  $AND and $OR.  Both of these macros require a condition
expression as an operand.

The $AND ends a group of instructions that follow a $IF, $WHILE, or a
$UNTIL instruction.  If the preceeding condition fails to match, then
the condition(s) defined afterwards will not be evaluated and the entire
complex set of conditions will be considered failing.  If the preceeding
condition matches, then the condition following the $AND will be
evaluated and all further tests will be based on this new evaluation
of condition.

The $OR works like $AND except that its condition is evaluated only
when the preceeding condition fails to match.

Both of thes macros, $AND and $OR function serially.  This means
that there is no equivalent to grouping logical expressions within
parenthesis.  The precedence of logical operators is equal and to
the left (or up in assembler).

A complex decision structure may look like this:
         $IF    condition-1
           (instructions to match cond-1)
         $AND   condition-2
           (instructions to match cond-2)
         $OR    condition-3
           (instructions to match cond-3)
         $THEN
           (executed if (cond-1 & cond-2) | cond-3 matches)
         $ELSIF condition-4
           (instructions to match cond-4)
         $OR    condition-5
           (instructions to match cond-5)
         $AND   condition-6
           (instructions to match cond-6)
         $THEN
           (executed if cond-4 | (cond-5 & cond-6) matches)
         $ELSE
           (executed if ((c1 & c2) | c3 ) & (c4 | (c5 & c6)) fails)
         $END


It is permissable to nest structures within the condition evaluation
parts.  There is no equivalent to this capability in common high
level languages except for the ?: operators in C.


The preceeding description of the structured programming macros and the
structured programming macros themselves are considered a work of art.
ABSOLUTELY NO WARRANTY is expressed, implied, or applicable in any way.

Do not send bug reports to:  (after all, works of art are flawless)

Author:     Philip David Howard,         Research Programmer
Internet:   <phil-howard@uiuc.edu>,      Bitnet (if you must): <phil@uiucvmd>
Voicenet:   (USA) 217-244-6246
Papernet:   Computing Services Office,   Room 1519
            Digital Computer Lab,        MC-256
            University of Illinois at Urbana-Champaign
            1304 West Springfield Avenue
            Urbana, IL  USA-61801
--
 /***************************************************************************\
/ Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu                              \
\ Lietuva laisva -- Brivu Latviju -- Eesti vabaks                             /
 \***************************************************************************/

icking@gmdzi.gmd.de (Werner Icking) (04/15/91)

phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
[...]
>                STRUCTURED ASSEMBLER PROGRAMMING MACROS
> 
>         $IF   condition-1
>           .     \
[...]
Using a good Assembler (like ASM-H with SLAC extensions) there is no need to
code such programmer-unfriendly code like
R0        EQU   0
HWORD     DS    H
          LH    R0,HWORD
          $IF   ZERO
          LTR   R0,R0
          $THEN

If your Assembler supports type- and length attributes in outer and inner
macros, if you add some own types like "Register" you can code the same
similar to "high level languages" like FORTRAN:
R0       #EQUR  0
HWORD    DS     H
         IF     HWORD,EQ,0,THEN

We started this type of programming in the late 60-th -- and stopped it
some years ago. If anybody is interested I will look for a description
and the corresponding macro-library.
-- 
Werner Icking          icking@gmdzi.gmd.de          (+49 2241) 14-2443
Gesellschaft fuer Mathematik und Datenverarbeitung mbH (GMD)
Schloss Birlinghoven, P.O.Box 1240, D-5205 Sankt Augustin 1, FRGermany
                                  "Der Dativ ist dem Genitiv sein Tod."

news@ucf1vm.BITNET (04/15/91)

phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
[...]
>                STRUCTURED ASSEMBLER PROGRAMMING MACROS
>
>         $IF   condition-1
>           .     \
[...]
Using a good Assembler (like ASM-H with SLAC extensions) there is no need to
code such programmer-unfriendly code like
R0        EQU   0
HWORD     DS    H
          LH    R0,HWORD
          $IF   ZERO
          LTR   R0,R0
          $THEN

If your Assembler supports type- and length attributes in outer and inner
macros, if you add some own types like "Register" you can code the same
similar to "high level languages" like FORTRAN:
R0       #EQUR  0
HWORD    DS     H
         IF     HWORD,EQ,0,THEN

We started this type of programming in the late 60-th -- and stopped it
some years ago. If anybody is interested I will look for a description
and the corresponding macro-library.
--
Werner Icking          icking@gmdzi.gmd.de          (+49 2241) 14-2443
Gesellschaft fuer Mathematik und Datenverarbeitung mbH (GMD)
Schloss Birlinghoven, P.O.Box 1240, D-5205 Sankt Augustin 1, FRGermany
                                  "Der Dativ ist dem Genitiv sein Tod."

phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (04/19/91)

icking@gmdzi.gmd.de (Werner Icking) writes:

[text deleted]

You have taken a simple example:

>R0        EQU   0
>HWORD     DS    H
>          LH    R0,HWORD
>          $IF   ZERO
>          LTR   R0,R0
>          $THEN

And coded it using another method:

>R0       #EQUR  0
>HWORD    DS     H
>         IF     HWORD,EQ,0,THEN

Try THIS one, which is slightly more difficult:

           $IF   NOT-EQUAL           if does not begin with                     
             CLI   0(R2),X'40'         a blank                                  
           $AND  NOT-EQUAL           nor                                        
             CLI   0(R2),X'05'         a tab                                    
           $AND  POS                 and                                        
             MVI   PROCESS,0           (header start so clear flag)             
             BAL   R14,TESTHDR         this is a header we process              
           $THEN ,                   then                                       
             MVI   PROCESS,1           process this header                      
           $END  ,                                                              

Then this one which is more difficult yet:

           $IF   ON                  if                                         
             TM    PROCESS,1           this header is being processed           
           $AND  HIGH                and                                        
             STM   R2,R3,ORIGREC       save original address and length         
             BAL   R14,FIXIT           processing causes                        
             CL    R3,=F'80'           an overflow                              
           $AND  HIGH                and                                        
             BAL   R14,SQUEEZE         squeezing will not fix                   
             CL    R3,=F'80'           the overflow                             
           $THEN ,                   then                                       
             LM    R2,R3,ORIGREC       restore original                         
           $END  ,                                                              

And then this one which is starting to really get hard:

         $IF   POS                 if (the following test is positive)          
                                                                 SPACE          
           $IF   ZERO                if                                         
             TM    8(R5),B'10000000'   upper-right value is positive            
           $THEN ,                   then                                       
             LCDR  FPR2,FPR4           test lower-left for negative             
           $ELSE ,                   else                                       
             LTDR  FPR2,FPR4           test lower-left for positive             
           $END  ,                                                              
                                                                 SPACE          
         $OR   POS                 or (the following test is positive)          
                                                                 SPACE          
           $IF   ZERO                if                                         
             TM    0(R5),B'10000000'   upper-left value is positive             
           $THEN ,                   then                                       
             LCDR  FPR2,FPR0           test lower-right for negative            
           $ELSE ,                   else                                       
             LTDR  FPR2,FPR0           test lower-right for positive            
           $END  ,                                                              
                                                                 SPACE          
         $THEN ,                   then                                         
           EX    *-*,PLOTOI(R7)      OI 0(R6),B'one bit'                        
         $END  ,                                                                

And finally this one which also looks rather hard:

         $IF   EQUAL               if                                           
           CLI   0(R10),X'FF'        there are no arguments                     
         $OR   NOT-CC0             or                                           
           $IF   EQUAL               ( if                             )         
             CLI   8(R10),X'FF'      (   there was just one argument  )         
           $OR   ZERO                ( or                             )         
             LM    R2,R3,8(R10)      (   (get position argument)      )         
             LTR   R2,R2             (   the pos argument was omitted )         
           $OR   NOT-CC0             ( or                             )         
             DECINT ,                (   >>> the number cannot convert)         
           $THEN ,                   ( then                           )         
             LA    R1,1              (   assume position to be 1      )         
           $END  ,                   ( endif                          )         
           LM    R2,R3,0(R10)        ( get address, length of list    )         
           BAL   R14,FINDELEM        >>> the element cannot be found            
         $THEN ,                   then                                         
           SLR   R3,R3               use a null element                         
         $END  ,                   endif                                        

>We started this type of programming in the late 60-th -- and stopped it
>some years ago. If anybody is interested I will look for a description
>and the corresponding macro-library.

I'd like to see the description.  I'd suggest posting it.

What is the difference between these methods?  Well obviously a lot of
detail difference.  I don't know for sure what Werner's method really is,
but it looks syntactically like one I read about in an assembler text.
Unfortunately the one in that text had limitations that restricted the
scope of what kinds of conditions could be tested, and had an even more
primitive looping macro setup that required things be expressed in terms
of BXH/BXLE conditions only.  I did not include any loops in the examples
above, but I can include them.  BTW, the "DECINT" in example 4 above is a
macro that calls a subroutine that is generated elsewhere by the same macro,
OR generates inline code in place, depending on the setting of a global
variable by one of yet other macros (INLINE, INTORG, EXTABS, etc.).
-- 
 /***************************************************************************\
/ Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu   |  Guns don't aim guns at  \
\ Lietuva laisva -- Brivu Latviju -- Eesti vabaks  |  people; CRIMINALS do!!  /
 \***************************************************************************/

news@ucf1vm.BITNET (04/19/91)

icking@gmdzi.gmd.de (Werner Icking) writes:

[text deleted]

You have taken a simple example:

>R0        EQU   0
>HWORD     DS    H
>          LH    R0,HWORD
>          $IF   ZERO
>          LTR   R0,R0
>          $THEN

And coded it using another method:

>R0       #EQUR  0
>HWORD    DS     H
>         IF     HWORD,EQ,0,THEN

Try THIS one, which is slightly more difficult:

           $IF   NOT-EQUAL           if does not begin with
             CLI   0(R2),X'40'         a blank
           $AND  NOT-EQUAL           nor
             CLI   0(R2),X'05'         a tab
           $AND  POS                 and
             MVI   PROCESS,0           (header start so clear flag)
             BAL   R14,TESTHDR         this is a header we process
           $THEN ,                   then
             MVI   PROCESS,1           process this header
           $END  ,

Then this one which is more difficult yet:

           $IF   ON                  if
             TM    PROCESS,1           this header is being processed
           $AND  HIGH                and
             STM   R2,R3,ORIGREC       save original address and length
             BAL   R14,FIXIT           processing causes
             CL    R3,=F'80'           an overflow
           $AND  HIGH                and
             BAL   R14,SQUEEZE         squeezing will not fix
             CL    R3,=F'80'           the overflow
           $THEN ,                   then
             LM    R2,R3,ORIGREC       restore original
           $END  ,

And then this one which is starting to really get hard:

         $IF   POS                 if (the following test is positive)
                                                                 SPACE
           $IF   ZERO                if
             TM    8(R5),B'10000000'   upper-right value is positive
           $THEN ,                   then
             LCDR  FPR2,FPR4           test lower-left for negative
           $ELSE ,                   else
             LTDR  FPR2,FPR4           test lower-left for positive
           $END  ,
                                                                 SPACE
         $OR   POS                 or (the following test is positive)
                                                                 SPACE
           $IF   ZERO                if
             TM    0(R5),B'10000000'   upper-left value is positive
           $THEN ,                   then
             LCDR  FPR2,FPR0           test lower-right for negative
           $ELSE ,                   else
             LTDR  FPR2,FPR0           test lower-right for positive
           $END  ,
                                                                 SPACE
         $THEN ,                   then
           EX    *-*,PLOTOI(R7)      OI 0(R6),B'one bit'
         $END  ,

And finally this one which also looks rather hard:

         $IF   EQUAL               if
           CLI   0(R10),X'FF'        there are no arguments
         $OR   NOT-CC0             or
           $IF   EQUAL               ( if                             )
             CLI   8(R10),X'FF'      (   there was just one argument  )
           $OR   ZERO                ( or                             )
             LM    R2,R3,8(R10)      (   (get position argument)      )
             LTR   R2,R2             (   the pos argument was omitted )
           $OR   NOT-CC0             ( or                             )
             DECINT ,                (   >>> the number cannot convert)
           $THEN ,                   ( then                           )
             LA    R1,1              (   assume position to be 1      )
           $END  ,                   ( endif                          )
           LM    R2,R3,0(R10)        ( get address, length of list    )
           BAL   R14,FINDELEM        >>> the element cannot be found
         $THEN ,                   then
           SLR   R3,R3               use a null element
         $END  ,                   endif

>We started this type of programming in the late 60-th -- and stopped it
>some years ago. If anybody is interested I will look for a description
>and the corresponding macro-library.

I'd like to see the description.  I'd suggest posting it.

What is the difference between these methods?  Well obviously a lot of
detail difference.  I don't know for sure what Werner's method really is,
but it looks syntactically like one I read about in an assembler text.
Unfortunately the one in that text had limitations that restricted the
scope of what kinds of conditions could be tested, and had an even more
primitive looping macro setup that required things be expressed in terms
of BXH/BXLE conditions only.  I did not include any loops in the examples
above, but I can include them.  BTW, the "DECINT" in example 4 above is a
macro that calls a subroutine that is generated elsewhere by the same macro,
OR generates inline code in place, depending on the setting of a global
variable by one of yet other macros (INLINE, INTORG, EXTABS, etc.).
--
 /***************************************************************************\
/ Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu   |  Guns don't aim guns at  \
\ Lietuva laisva -- Brivu Latviju -- Eesti vabaks  |  people; CRIMINALS do!!  /
 \***************************************************************************/

RAF@NIHCU.BITNET (Roger Fajman) (04/23/91)

> Gaak... Looks almost like PL/360.. ;)

Only superficially, I think.  As I recall PL/360, it uses a lot of one
or two character operators to represent the instructions.  ALP uses
regular machine instructions and macros, with the addition of the
special control structures (which generate only branching
instructions).  It's probably the Algol-like syntax that makes you
think of PL/360.  I didn't care for PL/360 either.  :-)

By the way, one of the advantages of ALP over a macro package is that,
being a preprocessor, it can (and does) have control structures for
macro definitions too.  They generate AIFs and ANOPs.

RAF@NIHCU.BITNET (Roger Fajman) (04/24/91)

> Rojer, maybe you're used to it, but to my eye that ALP code is
> actually harder to read than well-written normal ASM.
>
> /Leonard

Well, in many respects it's a different language -- just one that has a
lot of similarity to assembler.  No one expects to understand C or PL/I
programs without having studied the language at all.  Some people like
ALP, some don't -- just like anything else.  I found the examples with
the structure macros difficult to follow, but I'm sure it would be much
easier if I were used to them.

I've been writing 360/370 assembler code since 1965 and found it
awkward for writing and maintaining large systems, with the flow of
control being a big part (but not all) of the problem.  Apparently
others agree or there wouldn't be so many control structure macro
packages around.  By the way, ALP is based on a package called AL
originially developed at the Mitre Corporation.  We took it and greatly
enhanced it (500 lines of PL/I became over 3000).  If I were picking a
language to write a large system in today, I might well choose C, in
spite of the things I don't care for about it.  C was not available in
1973, when ALP was done.

Roger