Reputation: 91
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
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
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
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