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