Control Flow in RPG
Learn conditionals, loops, and structured control flow in modern free-form RPG IV - IF/ELSE, SELECT, FOR, DOW, DOU, LEAVE, and ITER
Control flow determines the order in which a program’s statements run - which branches it takes and how many times it repeats a block of work. As a procedural, imperative language, RPG provides a familiar set of structured control-flow constructs: conditionals, multi-way selection, and several kinds of loops.
What makes RPG’s history interesting is that these constructs are relatively recent. The original 1959 language had no IF or DO statements at all - instead, it relied on the program cycle (an implicit read-process-write loop) and numbered indicators to drive branching. Structured programming constructs like IF/ENDIF and DO loops did not arrive until RPG III in 1978. Modern free-form RPG IV gives you clean, readable structured control flow while the old cycle still runs underneath for traditional file processing.
This tutorial uses fully free-form RPG (**FREE). You will learn how to write IF/ELSEIF/ELSE conditionals, multi-way SELECT groups, counted FOR loops, condition-driven DOW and DOU loops, and how to break out of or skip iterations with LEAVE and ITER. Every statement ends in a semicolon, and RPG remains case-insensitive throughout.
Conditionals: IF / ELSEIF / ELSE
The IF construct is the workhorse of RPG branching. It evaluates a condition and runs the matching block, closing with ENDIF. Optional ELSEIF clauses add more conditions, and ELSE handles everything else.
Create a file named control_flow_if.rpgle:
**FREE
dcl-s temp int(10) inz(72);
dcl-s msg varchar(50);
if temp > 80;
msg = 'It is hot';
elseif temp >= 60;
msg = 'It is comfortable';
else;
msg = 'It is cold';
endif;
dsply msg;
*inlr = *on;
Key points:
- The condition is a boolean expression;
temp >= 60uses the relational operators covered in the operators tutorial. elseifis a single keyword (notelse if) and you can chain as many as you need.- Every branch closes with a single
endif. - RPG has no ternary operator (
?:). Where other languages would write a conditional expression, RPG uses a fullIFblock or assigns inside the branches, as shown above.
Multi-Way Selection: SELECT / WHEN / OTHER
When you need to choose among several mutually exclusive cases, SELECT is clearer than a long IF/ELSEIF chain. It is RPG’s equivalent of a switch/case statement. Each WHEN holds a full boolean condition (not just a constant), the first matching WHEN runs, and OTHER is the catch-all. The group closes with ENDSL.
Create a file named control_flow_select.rpgle:
**FREE
dcl-s score int(10) inz(85);
dcl-s grade char(1);
dcl-s msg varchar(50);
select;
when score >= 90;
grade = 'A';
when score >= 80;
grade = 'B';
when score >= 70;
grade = 'C';
other;
grade = 'F';
endsl;
msg = 'Grade: ' + grade;
dsply msg;
*inlr = *on;
Key points:
- Because each
WHENis a full condition,SELECThandles ranges and complex tests, not just equality. - Only the first matching
WHENexecutes - there is no fall-through, so nobreakis needed. OTHERis optional; if noWHENmatches and there is noOTHER, the group simply does nothing.- With
score = 85, thescore >= 90test fails andscore >= 80matches first, producing gradeB.
Loops: FOR, DOW, and DOU
RPG offers three structured loops, each suited to a different situation.
FOR- a counted loop with a start, limit, and optional step (BY/DOWNTO). Use it when you know the iteration count.DOW(Do While) - tests its condition before each pass; the body may run zero times.DOU(Do Until) - tests its condition after each pass; the body always runs at least once.
All three close with ENDFOR (for FOR) or ENDDO (for DOW/DOU).
Create a file named control_flow_loops.rpgle:
**FREE
dcl-s i int(10);
dcl-s count int(10) inz(0);
dcl-s n int(10) inz(10);
dcl-s msg varchar(50);
// Counted FOR loop: 1 to 3
for i = 1 to 3;
msg = 'FOR iteration ' + %char(i);
dsply msg;
endfor;
// FOR counting down by 2: 6, 4, 2
for i = 6 downto 2 by 2;
msg = 'Countdown ' + %char(i);
dsply msg;
endfor;
// DOW: condition checked BEFORE each pass
dow count < 3;
count += 1;
msg = 'DOW count ' + %char(count);
dsply msg;
enddo;
// DOU: body runs at least once, condition checked AFTER
dou n <= 8;
n -= 1;
msg = 'DOU n ' + %char(n);
dsply msg;
enddo;
*inlr = *on;
Key points:
%char(i)converts the integer to its character form so it can be concatenated into the message and displayed.FOR ... DOWNTO ... BY 2decrements the index by 2 each pass.count += 1andn -= 1use the compound-assignment operators from the operators tutorial.- The
DOWbody runs whilecount < 3is true; theDOUbody runs untiln <= 8becomes true.
Loop Control: LEAVE and ITER
Inside any loop you can change the normal flow with two operations:
LEAVE- immediately exits the innermost loop (likebreakin other languages).ITER- skips the rest of the current pass and starts the next iteration (likecontinue).
Create a file named control_flow_iter.rpgle:
**FREE
dcl-s i int(10);
dcl-s msg varchar(50);
for i = 1 to 10;
// Skip even numbers - jump to the next iteration
if %rem(i:2) = 0;
iter;
endif;
// Stop the loop entirely once we reach 7
if i = 7;
leave;
endif;
msg = 'Odd value: ' + %char(i);
dsply msg;
endfor;
*inlr = *on;
Key points:
%rem(i:2)returns the remainder ofidivided by 2; a result of0meansiis even.- When
iis even,ITERskips thedsplyand moves to the next value. - When
ireaches 7,LEAVEends the loop before anything else runs, so 7, 8, 9, and 10 are never processed. - The loop therefore displays only the odd values 1, 3, and 5.
Running on IBM i
RPG requires an IBM i system. There is no open-source RPG compiler for Linux, macOS, or Windows, and no Docker image is available - so these examples cannot be containerized.
If you have access to an IBM i system, compile and run each program with CL (Control Language) commands. For example, to build and call control_flow_if.rpgle:
| |
Repeat with a different program name for each source file (for example CTLSEL, CTLLOOP, CTLITER). To get access to an IBM i for practice, see the options in the Hello World tutorial - the free public PUB400.COM system is a good starting point.
Expected Output
control_flow_if.rpgle (temperature 72 falls in the comfortable range):
It is comfortable
control_flow_select.rpgle (a score of 85 maps to grade B):
Grade: B
control_flow_loops.rpgle (the three loop types in sequence):
FOR iteration 1
FOR iteration 2
FOR iteration 3
Countdown 6
Countdown 4
Countdown 2
DOW count 1
DOW count 2
DOW count 3
DOU n 9
DOU n 8
control_flow_iter.rpgle (even values skipped, loop stops at 7):
Odd value: 1
Odd value: 3
Odd value: 5
On IBM i, each DSPLY shows its message interactively (press Enter to acknowledge) or writes it to the job log in batch mode, prefixed with DSPLY.
Key Concepts
IF/ELSEIF/ELSE/ENDIFprovide standard structured conditionals;ELSEIFis one keyword and chains freely.- RPG has no ternary operator - use a full
IFblock or assign within branches instead of a conditional expression. SELECT/WHEN/OTHER/ENDSLis RPG’s multi-way switch; eachWHENis a full condition, only the first match runs, and there is no fall-through.FORis the counted loop, supportingTO,DOWNTO, and aBYstep; it replaced the olderDOoperation in modern free-form RPG.DOWtests before the body (may run zero times);DOUtests after the body (always runs at least once).LEAVEbreaks out of the innermost loop andITERskips to the next iteration.- Structured control flow is a later addition to RPG (RPG III, 1978); the original language relied on the implicit program cycle and numbered indicators for branching.
- Conditions reuse RPG’s relational and logical operators, and statements always end with a semicolon in free-form syntax.
Comments
Loading comments...
Leave a Comment