All programming languages must use statements that control the execution of the program because, in most cases, it is not desirable to execute the statements in a program sequentially. Programs always have loops, decisions, and jumps.
Decision making is performed by the IF and SELECT commands. The general form of IF is:
IF COND(…) THEN(…) ELSE CMD(…)
The condition enclosed in the COND parameter is evaluated first. If it is true, the program executes the statement contained in the THEN parameter. If it is false, it executes the statement in the ELSE's CMD parameter. The ELSE command is optional.
If you have more than one statement to execute in either or both cases of the decision, you can use the DO/ENDDO command pair, as follows:
IF COND(…) THEN(DO) : : ENDDO ELSE CMD(DO) : : ENDDO
In this case, the program executes the statements embedded in the first DO/ENDDO pair if the condition is true, or the second DO/ENDDO if false.
The COND parameter can contain any expression that yields a true or false result, such as:
IF COND(&A *EQ &B)
In this example, both &A and &B are variables of the same type (character, decimal, or logical). The *EQ operator compares them for equality. Table 23.1 shows all the available comparison operators:
Less than or equal to
Not less than (same as *GE)
Greater than or equal to
Not greater than (same as *LE)
You also can combine these comparisons with *AND, *OR, and *NOT, using parentheses, if necessary. CL allows very complicated conditions in the COND parameter.
The general form of SELECT is:
SELECT WHEN COND(...) THEN(...) WHEN COND(...) THEN(...) OTHERWISE CMD(...) ENDSELECT
The conditions in the WHEN commands are evaluated one after another, beginning with the first WHEN command. If a condition is true, the program executes the statement contained in the THEN parameter and continues after the ENDSELECT command. If all of the WHEN conditions are false, the statement in the OTHERWISE command's CMD parameter is executed. The OTHERWISE command is optional.
As with IF, you can use DO/ENDDO to execute more than one command if a condition proves true:
SELECT WHEN COND(…) THEN(DO) : : ENDDO OTHERWISE CMD(DO) : : ENDDO ENDSELECT
V5R3 of i5/OS provides three looping structures: a top-tested loop (DOWHILE), a bottom-tested loop (DOUNTIL), and a counted loop (DOFOR). Here is the syntax for the DOWHILE command.
DOWHILE COND(...) : : ENDDO
The condition is evaluated before each iteration of the loop. If the condition is true, the system executes the commands in the body of the loop.
DOUNTIL is identical in syntax and differs only in that the condition is executedafter each iteration of the loop.
DOFOR requires a loop control variable, which must be of the integer or unsigned integer type:
DOFOR VAR(...) FROM(...) TO(...) BY(...) : : ENDDO
The control variable is initialized to the value in the FROM parameter. Before each iteration of the loop, the control variable is checked to determine whether it is in the range of the TO and FROM values. As long as the control variable remains within this range, the system executes the commands inside the loop. After each iteration, the value in the BY parameter is added to the control variable.
The LEAVE and ITERATE commands provide a way to alter the behavior of a loop. LEAVE causes an immediate exit from the loop. ITERATE forces the next iteration of a loop.
If the CMDLBL parameter has a value, the LEAVE or ITERATE command applies to the loop identified by the label. If no label is specified, the LEAVE or ITERATE command applies to the innermost loop.
LOOPA: DOWHILE COND(&RESPONSE *EQ '*YES') : LOOPB: DOUNTIL COND(&COUNTER *LT 0) : IF COND(&ERROR *EQ 1) THEN(LEAVE LOOPA) : ENDDO : ENDDO
If an error occurs, indicated by a true (‘1’) value in the variable &ERROR, control continues after the second ENDDO command.
The GOTO statement always transfers control to a label (or "tag") in the CL program. A label is a name, followed by a colon (:), which is written before a command name. For example:
GOTO CMDLBL(HERE) : : HERE: CHGVAR ...
The GOTO statement transfers control to label HERE, which points to the CHGVAR statement.
Another control command is the CALL command. With CALL, you can run another program (which can be written in any language) and exchange data with that program through positional parameters. When the other program ends, the system automatically returns control to your CL program. The CL program resumes execution at the statement immediately following the CALL.
You can pass either variables or constants as parameters. In general, passing parameters as constants is tricky. There are ways to make it work, but that discussion is beyond the scope of this book. A good starting point is to pass parameters as variables all the time. Once you gain experience, you can begin experimenting with constants.
The caller and the called program should normally agree in number of parameters. If program A calls program B, the CALL command in program A must list the same number of parameters as program B expects at its entry point. If the called program is an RPG program, the number of parameters doesn't necessarily have to agree. The compiler doesn't check to see that the number of parameters is the same, so the RPG program will not raise an error until it tries to use a parameter that was not passed to it.
Parameters must also agree in type and length, although some languages are less strict about this than others. When in doubt, make them agree. If program A calls B listing a 10-character string variable and a 7-digit numeric variable, be sure that program B expects the same.
When the called program ends, the parameters are returned to the caller. The parameters may have been changed by the program you called.
The ENDPGM and RETURN commands can be used to signal the end of a program. ENDPGM must be the very last statement in a CL program, but RETURN can be anywhere. While only one ENDPGM statement can be present, any number of RETURNs can be scattered throughout the CL program.
The commands perform the same function; absolutely no difference exists. You can use RETURN to terminate a program no matter where you may be within the program. This command saves you from having to code a GOTO command to take you to the ENDPGM. If the CL program you are running was called from another, either ENDPGM or RETURN can be used to return control to the caller.
Good coding standards insist on a single exit point from a program. If you scatter RETURN statements throughout the program, you can make it difficult for other programmers to maintain the program.