RPG Language

HLL for Business Applications

Coding in RPG (Report Program Generator) has been taking place since 1959. Of course, the language has changed dramatcially over the last half century. RPG has had to change in order to keep pace with the changing demands of midrange system application requirements. From IBM S/3, to S/34, through the S/38 and S/36 years, and through the AS/400, iSeries machines, and now the Power i products, RPG has been the overwhelming language of choice for application development on the IBM midrange platform.

The language began as a fixed-format columnar code for report writing and has morphed into a free-format language of tremendous scope. As of Release 7.1 of the i OS, new operations after TR7, RPG is no longer framed by fixed-format instructions, or definitions.

Introduction and RPG II

IBM introduced RPG to the business world in 1959. In 1969, RPG II made its debut. (Intro to RPG) It was a staple on IBM's S/3 platforms.

      *================================================================
      * This is a sample of RPG II code
      *================================================================
      *
     C  21NU2             SETON                       62
     C  21N62 U2          GOTO END
     C  21                EMPNOCHAINMASTER            99
     C  21                ADD  1         CNT     30
     C  21                ADD  CSALE     TCSALE  80
     C  21                ADD  CGROSS    TCGROS  80
     C  21                ADD  CPD       TCPD    80
     C  21                ADD  CCL       TCCL    80
     C  21                ADD  CRES      TCRES   80
     C  21                ADD  YSALE     TYSALE  80
     C  21                ADD  YGROSS    TYGROS  80
     C  21                ADD  YPD       TYPD    80
     C  21                ADD  YCL       TYCL    80
     C  21                ADD  YRES      TYRES   80
     C  21                Z-ADDCPERG     CPERG1  52H
     C  21                Z-ADDYPERG     YPERG1  52H
     C                    END       TAG 

RPG III

In 1979, RPG III offered major enhancement. IBM's S/38 RPG compilers were still dependent on fixed-column code. However, logic operations (op codes) made the language more versatile. As a common practice, programmers abandoned using left-hand indicators.

      *----------------------------------------------------------------
      * Put the line of text in the window data structure
      *----------------------------------------------------------------
B1   C                   DOW       *IN26 = *OFF
<--- C                   EXSR      @WLIN
     C                   READ      INPUT                                  25
B2   C                   IF        *IN25 = *ON
     C                             OR FMTID = 'FMT'
     C                   EVAL      *IN26 = *ON
B3   C                   IF        X < RCDS
     C                   EVAL      RCDS = X
E3   C                   ENDIF
E2   C                   ENDIF
B2   C                   IF        *IN25 = *OFF
     C                             AND X <= RCDS
     C                             AND FMTID <> 'FMT'
     C                   EVAL      #LRCD = NMBR1
E2   C                   ENDIF
      *----------------------------------------------------------------
B2   C                   IF        X > RCDS
     C                   MOVE      '+'           BTMBAR
     C                   EVAL      *IN26 = *ON
E2   C                   ENDIF
E1   C                   ENDDO

RPG IV and ILE

In 1994, RPG compilers became a part of the Integrated Language Environment (ILE) which allowed RPG programs to use procedures. Free format code, arrived in 2001, so RPG calculations were no longer dependent on fixed-column code. Logic loops and in-line case structures became common and programmers could indent the code to make the logic clearer. Binding and activation groups added a degree of complexity to RPG application development but offered a tremendous degree of functionality to RPG applications.

              DOU %eof(SC0320DF);                                                                   
                 READC SC0320S1;                                                                    
                 listAction = *off;                                                                 
                 IF NOT %eof(SC0320DF);                                                             
                    IF Z$OPT <> *BLANK;                                                             
                       listAction = *ON;                                                            
                       thisOption = %triml(z$opt);                                                  
                       ThisFormat = fmtnam;                                                         
                       ThisPgm = prgnam;                                                            
                       GetOption(Thispgm:ThisFormat:thisOption:macro:authl);                        
                       SELECT;                                                                      
                         WHEN SUBOP = 'CALL';                                                         
                            EXSR @CALLS;                                                              
                         WHEN function = 'PROCESS';                                                   
                             objectFound = retrieveObject( exobnm:exobtp );                           
                             IF objectFound;                                                          
                                objectFound = ObjectProcess();                                        
                             ENDIF;                                                                   
                         WHEN function = 'RESET';                                                     
                             objectFound = retrieveObject( exobnm:exobtp );                           
                             IF objectFound;                                                          
                                objectFound = ResetProcess();                                         
                             ENDIF;                                                                                                                                                                                              
                       ENDSL;                                                                       
                       z$opt = *BLANK;                                                              
                       IF before <> after;                                                          
                          SELECT;                                                                   
                             WHEN p$mode = 'C';                                                     
                                OBJECT = after;                                                     
                                exdesc= '*changed';                                                 
                             WHEN p$mode = 'D';                                                     
                                exdesc = '*deleted';                                                
                                sflProtect = *ON;                                                        
                          ENDSL;                                                                    
                       ENDIF;                                                                       
                       z$rrn2 =  z$rrn1;                                                            
                       UPDATE SC0320S1;                                                             
                       sflProtect = *OFF;                                                                
                       CLEAR MACRO;                                                                 
                    ENDIF;                                                                          
                 ENDIF;                                                                             
              ENDDO;                                         

OPM vs ILE

Contrary to popular recruiting terms, there is no such thing as ILE RPG. ILE is not a programming language, it is a modeling concept. The term OPM and ILE are often tied to a version of RPG, but it is a refrence to the model of development. The Original Program Model (OPM) is more limited in scope than the Integrated Language Environment (ILE) model. The Integrated Language Environment has broaden the scope of RPG application developement.

OPM ILE
  • Allows for subroutines
  • Supports multiple language calls
  • Subprogram invocation
  • Capable of CGI through API calls
  • Supports subprocedures - internal invocation
  • Supports dynamic calls to subprograms
  • Supports calls to service programs
  • ILE RPG has integrated modular API support
  • Offers binding of same language, or multi-language modules into an executable program or service program