Thursday, September 27, 2007

Free format RPG

MAKING THE TRANSITION TO FREE-FORMFree-form RPG is a controversial topic. I've received a number of messages from readers who feel strongly that I should provide my code samples in free-form RPG -- but I've also received messages from people who don't like it. Before starting to include free-form code in the newsletter, I thought it would be a good idea to introduce some of the aspects of free-form RPG to the readers. Unfortunately, I don't have nearly enough space to cover everything, so I will show some samples to get you started.
HOW TO CODE FREE-FORM STATEMENTSFree-form code only replaces the calculation specifications ("c-specs") of your program. The H,F,D,I,O, and P specs are still coded in the same way that they would be if you were writing traditional fixed-form code. Instead of coding a form type in position 6 of every record, free-form code is identified as a block. You code the "/free" compiler directive in position 7 of the record to start the block, and you code the "/end-free" compiler directive when you want the block to end. All free-form statements are typed in columns 8-80 of the record. Every free-form statement ends with a semi-colon. If no semi-colon appears at the end of a line of code, the compiler will assume that the statement is not finished and will interpret the next line as part of the same statement. The following is a very simple RPG program that uses free-form: D msg s 50A D wait s 1A /free eval msg = 'Hello World'; dsply msg ' ' wait; eval *inlr = *on; /end-free Just to make it absolutely clear -- the semi-colon ends every statement. It does not matter where one physical line begins and another ends. For example, the following statement is ugly, but perfectly valid: eval *inlr = *on; In free-form, the op-code is always specified first in each statement, followed by the factor1, factor2, and result fields. If a particular op-code does use the factor1, factor2, or result field, it is simply omitted. The following is a traditional C-spec for the chain op-code: C RRN chain MyFile This is the free-form equivalent: chain RRN Myfile;
THE EVAL AND CALLP OP-CODES ARE SPECIAL You do not have to specify an op-code when coding an EVAL or CALLP operation. The following lines of code are equivalent: eval msg = 'Hello World'; msg = 'Hello World';
MANY OP-CODES HAVE BEEN REMOVED One of the most controversial aspects of free-form RPG is that many of the op-codes that you have in traditional fixed-form RPG have been removed. For the most part, they were removed because of the expressions that you have available in the EVAL statement. The "Websphere Development Studio ILE RPG Reference" manual in the Information Center will tell you if an op-code is supported in free-form, and if not, it will suggest an alternative. For example, if you look up the TIME op-code in the manual, you'll see that it says: "Free-Form Syntax: (not allowed -- use the %DATE, %TIME, or %TIMESTAMP built-in function)"
SAMPLE FREE-FORM REPLACEMENTS In most cases where fixed-form op-codes were removed from free-form RPG, an expression or built-in-function (BIF) can be used instead. Most of the things that I'm going to explain here aren't only available in free-form and on the traditional C-specs using the EVAL op-code. Since RPG IV was introduced in V3R1, it has been possible to do math operations using expressions in the EVAL op-code. These same expressions work nicely in free-form. Here are some typical math operations: C A ADD B TOTAL1 C A SUB B TOTAL2 C A MULT B TOTAL3 C X DIV Y Z And this is how you'd code them as expressions: Total1 = A + B; Total2 = A - B; Total3 = A * B; Z = X / Y; Starting in V5R2, there are new operators in EVAL statements that can be used when performing a math operation that affects itself. C ADD 1 COUNT1 C SUB 1 COUNT2 C MULT 2 COUNT3 They can be coded with the special operators as follows: COUNT1 += 1; COUNT2 -= 1; COUNT3 *= 2; Prior to V5R2, you could accomplish the same thing by doing the following: COUNT1 = COUNT1 + 1; COUNT2 = COUNT2 - 1; COUNT3 = COUNT3 * 2; It's often useful to be able to get the remainder of a division operation. For example, if you want to know the remainder of X divided by Y, you'd traditionally code the following: C X DIV Y UNUSED C MVR R With the %REM() BIF, you no longer need to do division first -- and you no longer need to define a variable that you don't need elsewhere. You can simply code this: R = %REM(X : Y); The Z-ADD and Z-SUB op-codes were used in the old days to assign a numeric value to a variable. c z-add 15 A c

No comments: