theju112
theju112

Reputation: 91

Converting fixed format RPG to Free format

I have the below pieces of code written in Fixed format RPG in a report generation program. I have tried rewriting this in Free format. The report produced before and after seems to be the same on checking. However please let me know if there are any mistakes in this.

 *                                                 
 *   CONTROL BREAK WITHIN SOLIDS OR PATTERNS       
 *                                                 
C*    WOSRT1        IFEQ      '1'                  
C*    WOBKCL        ANDNE     SVCOLR               

C*    WOSRT1        OREQ      '2'                  
 ****       WOPATT    ANDNESVPATT                  
C*    WOCLT#        ANDNE     SVCLT#               

Equivalent:

If ( (WOSRT1 = '1' and WOBKCL <> SVCOLR) or                          
     (WOSRT1 = '2' and ( WOCLT# <>  SVCLT# or WOCLTH <> SVCLTH )) ); 

Code snippet - 2:

 *   CONTROL BREAK WITHIN SOLIDS OR PATTERNS     
 C*    WOSRT1        IFEQ      '1'                
 C*    WOBKCL        ANDNE     WOBKCLsave         

 C*    WOSRT1        OREQ      '2'                
 C*    WOCLT#        ANDNE     WOCLT#save         

Equivalent:

If ( (WOSRT1 = '1' and WOBKCL <> WOBKCLsave) or    
     (WOSRT1 = '2' and ( WOCLT# <>  WOCLT#save     
                      or WOCLTH <> WOCLTHsave ))); 

The condition WOCLTH <> SVCLTH in the first snippet and WOCLTH <> WOCLTHsave in the second snippet is an additional condition that I needed to add to the Break logic.

When I tried adding this condition in Fixed format (last line), the report records got changed in an unintentional way. Kindly can someone also point out what is wrong with the below?

 *   CONTROL BREAK WITHIN SOLIDS OR PATTERNS
C     WOSRT1        IFEQ      '1'           
C     WOBKCL        ANDNE     WOBKCLsave    

C     WOSRT1        OREQ      '2'           
C     WOCLT#        ANDNE     WOCLT#save    
C     WOCLTH        ORNE      WOCLTHsave    

Upvotes: 1

Views: 1334

Answers (3)

jmarkmurphy
jmarkmurphy

Reputation: 11473

Charles answer is the best because explicit precedence with parenthesis is easier to read than the fixed format implicit precedence, and you should not be using fixed format any more. However, to do what you want, in the old style fixed format without extended operators, you will have to do this:

 *   CONTROL BREAK WITHIN SOLIDS OR PATTERNS
C     WOSRT1        IFEQ      '1'           
C     WOBKCL        ANDNE     WOBKCLsave    

C     WOSRT1        OREQ      '2'           
C     WOCLT#        ANDNE     WOCLT#save    

C     WOSRT1        OREQ      '2'           
C     WOCLTH        ORNE      WOCLTHsave



tl/dr;
If you break down the last condition in your parenthesized expression

(WOSRT1 = '2' and ( WOCLT# <>  WOCLT#save or WOCLTH <> WOCLTHsave ))

you have A and (B or C). The problem with old style fixed format RPG is that you can't put OR in parenthesis. You need to rewrite it so that the parenthesis surround the AND. Fortunately, AND is associative so you can write this as (A and B) or (A and C).

Upvotes: 1

Player1st
Player1st

Reputation: 1605

This is almost certainly an issue with operator precedence. Operator 'And' takes higher precedence than operator 'Or' so without anything to group your last code block, the equivalent free format is:

If (WORSRT = '1' And WOBKCL <> WOBKCLsave) Or
   (WOSRT1 = '2' And WOCLT# <> WOCLT#save) Or
   (WOCLTH <> WOCLTHsave);

This does not match with what you expected. I'm not particularly fluent in fixed format RPG so I don't know if you can use parentheses to fix the issue in your fixed format code but this should give you an idea of the issue.

Upvotes: 0

Charles
Charles

Reputation: 23783

The free form converter in RDi converts that as:

   IF WOSRT1 = '1'
   AND WOBKCL <> WOBKCLsave
   OR WOSRT1 = '2'
   AND WOCLT# <> WOCLT#save
   OR WOCLTH <> WOCLTHsave;

Since AND has precedence over OR, I'd add parens like so:

   IF (WOSRT1 = '1'
       AND WOBKCL <> WOBKCLsave)
   OR  (WOSRT1 = '2'
        AND WOCLT# <> WOCLT#save)
   OR WOCLTH <> WOCLTHsave;

Thus explaining why you get a difference results than you'd expect from your free-form version.

Complex IFs are difficult with legacy fixed format IFxx op-codes, why would you bother?

Even in fixed format, you could use IF with an extended factor 2

 C                   IF        ( (WOSRT1 = '1' and WOBKCL <> SVCOLR)                           
 C                               OR (WOSRT1 = '2'   
 C                                   and ( WOCLT# <>  SVCLT#  
 C                                         or WOCLTH <> SVCLTH   
 C                                       )                       
 C                                  )                             
 C                             )                                   
 C                   endif

Upvotes: 3

Related Questions