V5R3 CL Programming Enhancements, Part 1
March 17, 2004 Ted Holt
In the October 10, 2003, issue of Midrange Guru, I said I doubted that the good folks at IBM would ever enhance the CL programming language. Well, I was wrong. I recently had a long phone conversation with one of those good folks, and he told me what IBM is doing to beef up CL programming in V5R3. I liked what I heard, and I hope you’ll be as happy as I was to hear the news.
I’m going to tell you about what’s new with declarations, looping structures, and selection structures. The rest will have to wait until a later issue.
VARIABLE DECLARATIONS
When you move to V5R3, you will be able to define signed and unsigned integer variables with the DCL command by entering *INT or *UINT in the TYPE parameter. You may fill in the LEN parameter with 2 or 4 to indicate the number of bytes, not digits, that the compiler should allocate. If you do not code a length parameter, CL will allocate four bytes for integer variables. Being able to define these data types will come in handy when calling APIs. Just think, you may not have to use the %BIN function nearly as often as you do now.
The following table shows the ranges of values that may be stored in integer variables.
Type |
Minimum value |
Maximum value |
Unsigned, 2 bytes |
0 |
65,565 |
Unsigned, 4 bytes |
0 |
4,294,967,295 |
Signed, 2 bytes |
-32,768 |
32,767 |
Signed, 4 bytes |
-2,147,483,648 |
2,147,483,647 |
The maximum length for character variables has increased from 9999 to 32767 bytes. However, you can only specify a maximum of 3000 bytes in the VALUE parameter of a DCL declaration.
There is no change to decimal declarations. The maximum length remains 15 digits. The maximum number of decimal positions is nine.
LOOPING STRUCTURES
There are three new looping structures in V5R3: DOWHILE, DOUNTIL, and DOFOR. All of these control a body of commands terminated with an ENDDO.
DOWHILE is a top-tested loop, and DOUNTIL is a bottom-tested loop. Both of these commands accept one parameter, COND, which lets you specify the same sort of condition the IF command takes.
The following loop executes as long as indicator 03 is off. If indicator 03 is on when control reaches this point, the loop is not executed at all.
DOWHILE COND(*NOT &IN03) ... commands ENDDO
Here’s an example of DOUNTIL. The body of the loop will be executed at least once. After each iteration, the value of variable &ANSWER will be tested. If &ANSWER has a value of N, control will continue after the ENDDO.
DOUNTIL COND(&ANSWER *EQ 'N') ... commands ENDDO
The third looping structure is called DOFOR. It is similar in function to the DO and FOR op codes in RPG, the PERFORM . . . VARYING . . . UNTIL structure in COBOL, and the FOR loop in BASIC.
DOFOR requires a control variable, which must be of type *INT or *UINT, to be specified in the VAR parameter. DOFOR also requires the FROM and TO parameters, which denote the beginning and limiting values for the control variable. FROM and TO values may be integer literals or variables of the integer data types. There is an optional parameter, BY, with which you can identify the quantity to be added to the control variable before each iteration. Enter a negative value for descending loops and a zero or positive value for ascending loops. The BY parameter requires a literal; variables are not permitted. The default value of the BY parameter is 1.
DCL VAR(&POS) TYPE(*INT) LEN(2) DOFOR VAR(&POS) FROM(3) TO(53) BY(10) ... commands ENDDO
LEAVE AND ITERATE
The LEAVE and ITERATE commands alter the behavior of DOWHILE, DOUNTIL, and DOFOR loops. The LEAVE command exits a loop and passes control to the command following the loop’s ENDDO. The ITERATE command branches to the loop’s test condition to determine whether the body of the loop will be executed again.
RPG programmers will recognize these commands as the counterparts of the LEAVE and ITER op codes. However, there is a difference you should know about. You may provide the name of a label in the CMDLBL parameter. This label name must be a literal, not a variable. If you do not provide a label, the LEAVE or ITERATE refers to the innermost loop. If you provide a label, the LEAVE or ITERATE refers to the loop identified by the label. In the following example, the LEAVE command exits the outer loop, which is labeled NEXTFILE.
NEXTFILE: DOWHILE COND(&FILENAME *NE ' ') ... commands NEXTMBR: DOWHILE COND(&FILEMBR *NE ' ') ... commands IF (&TYPE *EQ 'DSPF') THEN(LEAVE CMDLBL(NEXTFILE)) ... commands ENDDO ... commands ENDDO
THE SELECT STRUCTURE
V5R3 CL programming includes a new case structure, which is implemented with the SELECT, WHEN, OTHERWISE, and ENDSELECT commands. SELECT and ENDSELECT begin and end the structure. They do not accept parameters. At least one WHEN group is required. The OTHERWISE command is optional.
WHEN is identical in structure to the IF command. The first parameter, COND, is a logical expression that must evaluate to true or false. The second parameter, THEN, is optional and indicates the action that is to be carried out if the condition is true. If you want to execute more than one command, use a DO command, as you would with IF. The system executes the first WHEN group whose condition proves true and ignores subsequent WHEN groups and OTHERWISE.
OTHERWISE is identical to ELSE in structure. You may specify a command to execute if none of the WHEN conditions is true. You may use a DO/ENDDO group to execute more than one command.
SELECT WHEN COND(&IN12) /* do nothing */ WHEN COND(&IN03) THEN(RETURN) WHEN COND(&DATE *EQ ' ') THEN(DO) CHGVAR VAR(&IN21) VALUE('1') ITERATE ENDDO OTHERWISE CMD(DO) CHGVAR VAR(&IN22) VALUE('1') CHGVAR VAR(&IN25) VALUE('1') ENDDO ENDSELECT
NESTING
There are limits to the number of levels of nested structures. You can nest up to 10 levels of IF statements. This is unchanged from previous releases of OS/400. You can nest up to 25 levels of DO, DOWHILE, DOUNTIL, and DOFOR commands. That is not 25 levels of each one, but 25 levels of all DOx operations. You can nest up to 25 levels of the SELECT command.
These limits are independent of one another. For example, you can have 10 levels of IF commands under a SELECT.
MORE TO COME
I hope your appetite has been whetted. In part 2 of this series, I’ll tell you about enhanced input/output, interprocess communication, and documentation. Until then!
This article has been corrected since it was first published. The article originally stated that if indicator 03 is off, the DOWHILE loop will not be executed. In fact, the DOWHILE will not be executed if indicator 03 is on. Also, references to *IN03 and *IN12 have been changed to &IN03 and &IN12. Guild Companies regrets the errors. [Corrections made 3/18/04.]
See the second article in this series: V5R3 CL Programming Enhancements, Part 2