ILE RPG, RPG IV Subroutines

RPGLE Subroutines

The RPG IV subroutines are basically used to perform any specific, recurring task. However you can simply write some complex statements or logic inside a subroutine even if it's not recurring. The ILE RPG compiler has no objection to that.

The C Spec code outside any subroutine just after the declaration and field renames is called the mainline code.

A subroutine begins with the opcode BegSr opcode. This opcodes takes the subroutine name as a parameter in the factor1 at 12th position. The end of subroutine is marked by the opcode EndSr. The subroutine name is optional here.

Once a subroutine has been defined inside a program, you can call this subroutine from anywhere by opcode ExSr. You have to specify the subroutine’s name in the factor 2.

Some important points about subroutines are given below.

  • Nesting of subroutines is not allowed.
  • Recursive call of subroutine is not allowed.
  • A subroutine should be defined after the mainline.
  • You change the value of any variable inside a subroutine, this value will be reflected everywhere in the program. (In case of Nonmodular program).
  • Scope of a variable declared in a subroutine is global(RPG III method of variable declaration. Not recommended!).

The following example describes a typical usage of subroutines in ILE-RPG.

Example of Subroutines in ILE RPG (Or RPG IV)

DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++
DW@Num1           S             15P 5 Inz(10)            
DW@Num2           S             15P 5 Inz(20)            
DW@Product        S             15P 5                    
 ** Mainline begins                                                     
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result+++++++
C     'Calling Sr'  Dsply                                
C                   ExSr      #CalcProduct               
C     W@Product     Dsply                                
C                   Return                               
 ** End of Mainline                                                     
 ** The Subroutine #CalcProduct is defined below.        
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result+++++++
C     #CalcProduct  BegSr                                
C                   Eval      W@Product = W@Num1 * W@Num2
C     'Multiplied'  Dsply                                
C                   EndSr

Output of the example is given below. Never mind the extra zeros. This happens due to numeric to character conversion.

DSPLY  Calling Sr     
DSPLY  Multiplied     
DSPLY         20000000

Initialization subroutine (*InzSr) in RPG
The initialization subroutine is same as any other subroutine except that this subroutine is executed first, even before any mainline statement. This is true even if you define initialization subroutine in between two other subroutines in a program, even at the end. The following example will demonstrate this.

Example of Initialization subroutine

D @Num1           S             15P 5                  
D @Num2           S             15P 5                  
DW@Product        S             15P 5                  
 **                                                    
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result+++++
C     'Calling Sr'  Dsply                              
C                   ExSr      #CalcProduct             
C     W@Product     Dsply                              
C                   Return                             
 **                                                    
 **                                                    
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result+++++
C     #CalcProduct  BegSr                              
C                   Eval      W@Product = @Num1 * @Num2
C     'Multiplied'  Dsply                              
C                   EndSr                              
 **
 ** The Initialization subroutine  
 **               
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result
C     *InzSr        BegSr                         
C     *Entry        PList                         
C                   Parm                    @Num1 
C                   Parm                    @Num2 
C     '*InzSr'      Dsply                         
 **                                               
C                   EndSr                         

Output of the initialization subroutine is given below. For this run, the input were given as 25 and 15. The output will help you understand the control flow during the program execution.

DSPLY  *InzSr         
DSPLY  Calling Sr     
DSPLY  Multiplied     
DSPLY         37500000

The opcode LeaveSr
The opcode LeaveSr is used to prematurely terminate the subroutine. The LeaveSr when executed takes the control to the last line (EndSr) of the subroutine. Remember, the last line, not the immediate statement following the ExSr statement from where the subroutine was called.
Return Versus LeaveSr
To return to the statement immediately after the ExSr opcode, Use the Return Opcode. The Return Opcode passes the control to the statement immediately after the calling statement.

A typical examle of the statement would be as follows

CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result+++++
C                   ExSr       Sr1          1
C      '1'          Dsply          6
...
...
CL0N01Factor1+++++++Opcode&ExtFactor2+++++++Result
C     Sr1           BegSr          2
C                   Eval       W@abc += 1          3
C                   LeaveSr          4
C     '1'           Dsply          7           
 **                                               
C                   EndSr          5

In the example above, the flow of the program will be 1 through 6. The statement 7 is never executed. If we use Return instead of LeaveSr in line 4, the statement 5 would also not have been executed.(i.e the flow would be 1-2-3-4-6).

We will learn more about initialization subroutine in program calls when using files. For now remember that the first statement inside the initialization subroutine is the first statement to be executed in a program.