Coding Free Format RPG IV April 2010 SEMIUG & MMUG Coding Free Format RPG IV: Jim Martin Author of Free Format RPG IV Copyright Jim Martin 2006 - 2010 1:1 Coding Free Format RPG IV Power / i aka AS/400, iSeries, System i5 Coding Free Format RPG IV: Jim Martin Author of Free Format RPG IV Copyright Jim Martin 2006 - 2010 1:2 Coding Free Format RPG IV Overview • • • • Free Format – Is it just a new ‘Style’? Introducing Free Format RPG IV What’s new in I/O using free format Program flow – without a Goto! – Logic groups – Proper ‘Ends’ – Call’s • Data manipulation – Eval vs Move – Conversion of decimal, date, & character data types – Must now use the BIFs • Style issues • Problem areas Copyright Jim Martin 2006 - 2010 1:3 Coding Free Format RPG IV Free Format Is it just a new style? Copyright Jim Martin 2006 - 2010 1:4 Coding Free Format RPG IV Free Format – Is it just a new ‘Style’? It is the newest ‘style’ – yes. It takes extended factor 2 and makes the space larger, but wait – there’s more! Big changes affect you!!! Here’s a few: No C in column 6 allowed. Must use compiler directive /free to tell the compiler that you are entering the Free-format style. Other compiler directives are OK, such as /Copy. Many fixed format operations are not available, such as Add, Sub, Move, MoveA, Lookup. Some are gone, and some are replaced with Built-in functions Let’s go into detail – in the pages that follow… Copyright Jim Martin 2006 - 2010 1:5 Coding Free Format RPG IV The free format code block The free format code block begins with compiler directive /Free (starting in position 7), and ends with /End-free. For example: /Free MPG = miles / gallon; Read FileA; Dow not %eof(FileA); Fieldx = Name; Read FileA; Enddo; Name = %trim(First_N); Invalid_Name = *On; /End-free Copyright Jim Martin 2006 - 2010 1:6 Coding Free Format RPG IV The free format code block Syntax rules within the free format block: 1. Enter all statements within positions 8 and 80. 2. End all code statements with a semicolon. If a line of code doesn’t fit on one line, just continue on the next line – there is no continuation character, except for character constants. 3. Positions 1 through 5 can be anything. 4. Do not put a C (or anything) in position 6. 5. Do not put a * in position 7 for comments. Comments are placed in the 8-100 area, beginning with //. You can put a comment after the semi-colon that ended the RPG code. 6. Position 7 can be used for additional compiler directives, such as /copy 7. You must end the free format block to enter embedded SQL. Copyright Jim Martin 2006 - 2010 1:7 Coding Free Format RPG IV Within the free format block • All 55 (V5R4) supported free format operations are supported, as well as all 76 built-in functions. • The fixed format scheme of level indicators, left hand indicators, defining a field on the fly, and resulting indicators are gone. • The general scheme of coding is: – Op-code Factor 1 Factor 2 • Not all of fixed format’s operations are supported. There are 112 operation codes in fixed format! Many of these are just not needed (ADD, SUB, MULT, etc.). • Many op codes are implemented via built-in functions. • The generic End statement is gone, you must use the correct End, such as Endif, Enddo, etc. • There is no GOTO operation, so only structured logic can be used, with loop interrupters Leave and Iter. Copyright Jim Martin 2006 - 2010 1:8 Coding Free Format RPG IV What about “work” variables? • Work variables, if needed, are defined on the D definition specifications – You need many fewer than before. – Longer names for work variables will work out fine – there’s plenty of room. – The notion of expressions, that started with Extended Factor 2, continue with lots of space. – The use of numbered indicators is discouraged; use named indicators instead. Copyright Jim Martin 2006 - 2010 1:9 Coding Free Format RPG IV Assignment statements Probably the most common free format operation is the assignment statement. An assignment statement is just an Eval statement without the Eval specified. Sometimes you need to put the Eval back in, such as when you want half-adjust in a math expression. Examples: Field30 = Field10; Eval(h) Pay = Hourly_Rate * hours; More complex forms: *In44 = RRN > *zero; // This statement checks for RRN // greater than 0. If it’s true indicator // *In44 is set on; if it’s false, the // indicator is set off. *In21 = *In43 or (Pay > 100); // This statement sets *In21 to *On // if either *In43 is *On or Pay > 100. Copyright Jim Martin 2006 - 2010 1:10 Coding Free Format RPG IV QUIZ ! What happens when you use Eval to add 1 to a 3 digit decimal field that currently contains 999? Have we come to the point in RPG where we do not need any numbered indicators? Is it possible to check a keyed file for the existence of a specific record key without doing a Chain operation? True or False? Free format RPG IV does not need to set *Inlr on to end a program. It’s now automatic. Copyright Jim Martin 2006 - 2010 1:11 Coding Free Format RPG IV QUIZ ! answers What happens when you use Eval to add 1 to a 3 digit decimal field that currently contains 999? An exception occurs: RNQ0103 Have we come to the point in RPG where we do not need any numbered indicators? Yes. Is it possible to check a keyed file for the existence of a specific record key without doing a Chain operation? Yes. Use the Setll operation, then use an If with %equal True or False? Free format RPG IV does not need to set *Inlr on to end a program. It’s now automatic. False. We must still set *Inlr on. The cycle lives on. Copyright Jim Martin 2006 - 2010 1:12 Coding Free Format RPG IV No Klist or Plist – now what? The free format block does not support Klist or Plist, so if you think you need them you will have to code them outside the free format block. The truth is: you don’t need them anyway! The Klist situation is handled by a new scheme to specify the key arguments when using ReadE, ReadPE, Setxx, or Chain. Here’s an example: Chain (arg1:arg2) Filex; Isn’t that neat! Another solution exists using a key data structure, which will be shown later. The Plist group isn’t needed either. More details will follow in this presentation, but in reality any program or procedure can be called without a Plist! The method used requires a definition group called a prototype. Copyright Jim Martin 2006 - 2010 1:13 Coding Free Format RPG IV What’s new in I/O using free format Most I/O functions are the same in free format as they were in fixed format. However, the way you code them follows the syntax of free format. There is no resulting indicator, so you must use %eof or %found, depending on the operation requested. Examples: Read FileA; Dow not %eof(FileA); Write DBRecord; Probably the biggest change is the way we specify key arguments in ReadE, ReadPE, Setxx, and Chain operations, as was shown on the previous page. The key data structure method is shown on the next page. Copyright Jim Martin 2006 - 2010 1:14 Coding Free Format RPG IV What’s new in I/O using free format Here’s an example of the key data structure method: D Rec_Key DS LikeRec(FileX:*key) * Let’s assume FileX has key fields CustNo and Acctno /free Rec_key.CustNo = Arg_Cust; Rec_key.AcctNo = Arg_Acct; Chain %kds(Rec_key) FileX; If %found(FileX); // process found record here Endif; Copyright Jim Martin 2006 - 2010 1:15 Coding Free Format RPG IV What’s new in I/O using free format The Update operation was given a third parameter (using BIF %fields) that helps to insure that only specified fields are updated. This has been done for years using exception output and O output specifications, Here’s how you do it: /free Update RecordA %fields(Name:Zip:AmountDue); The Delete and Exfmt operations are not changed. A small change was made to printer files. You may now specify a named indicator for the OFLIND keyword, instead of numbered ones, or OA-OG and OV. By choosing a name carefully, the program can be less cryptic. Copyright Jim Martin 2006 - 2010 1:16 Coding Free Format RPG IV Program flow – without a Goto! There are many programmers who have used Goto in RPG programs. In free format calculations, there is no Goto. The experts have said for years that Goto is not a good structured programming method. Doing without a Goto can improve the readability and performance of your programs. Knowing you can’t use Goto forces you to consider other options. Eliminating Goto removes one of the biggest issues in RPG: “spaghetti code.” Structured program flow is done with the following operations: Dou (Do until) Dow (Do while) If (with Else, Elseif, and Endif) Select (with When, Other, and Endsl) For (with index incrementing up or down) Leave (interrupt logic flow and leave a loop) Iter (interrupt logic flow. skipping to the loop end Copyright Jim Martin 2006 - 2010 1:17 Coding Free Format RPG IV Proper ‘Ends’ Free format RPG IV does not permit the generic End statement. Every If, Dou, Dow, Select, or For requires the correct Endxx statement. This should be a big help when developing or maintaining a program. The compiler will issue diagnostic messages if you use the wrong Endxx statement in a program. Even this seemingly small detail will help make your programs easier to read and modify. Copyright Jim Martin 2006 - 2010 1:18 Coding Free Format RPG IV Calls Neither the Call nor CallB operations are available in free format. And, we previously said that Plists aren’t available either! So, how do we call other programs either dynamically (the old Call) or statically (ILE binding – the CallB operation)? The answer lies in the CallP operation. CallP means Call a prototyped procedure. The CallP operation references a definition group called a prototype. A keyword on the prototype statement specifies whether the prototype is for an external program (dynamic call) or external procedure (bound call). The prototype defines the parameter list, but there are flexible rules on calling interfaces. Also, similar to the Eval operation, the Callp op code can be omitted when specifying the call. Parameters are passed using a list along with the prototype name. Copyright Jim Martin 2006 - 2010 1:19 Coding Free Format RPG IV Call example - dynamic D Check_Date D D PR date flag D Yes_or_No Extpgm(‘DATCHK’) 8 S 0 n n /free CallP Check_Date(ScreenDate:Yes_or_No); This is an example of using a prototype to call an external program dynamically. The parameters in the prototype do not need to be named, but any kind of documentation is beneficial. Copyright Jim Martin 2006 - 2010 1:20 Coding Free Format RPG IV Call example - static D AR0300R D D Amount1 Amount2 PR Extproc(‘AR0300R’) 5 7 2 2 /free CallP AR0300R(ScreenAmt:DBAmt); This is an example of using a prototype to call a procedure statically (bound call). Copyright Jim Martin 2006 - 2010 1:21 Coding Free Format RPG IV Called program A called program using free format will need to have both a prototype and a procedure interface. The parameters specified in the procedure interface will be used in the program. In a recent article, in V7R1, only the procedure interface will be needed in sub-procedures. This will eliminate unnecessary code. Until you get to V7, continue to code both. Copyright Jim Martin 2006 - 2010 1:22 Coding Free Format RPG IV Quiz 2 True or False: There was an IBM RPG language before 1965? I can get a remainder in RPG IV without doing a divide operation? How do I check for a run time error in an Eval in RPG IV, since you can’t use the (e) Op code extender? Copyright Jim Martin 2006 - 2010 1:23 Coding Free Format RPG IV Quiz 2 True or False: There was an IBM RPG language before 1965? True! It was used on 1401, 1410. 1440 I can get a remainder in RPG IV without doing a divide operation? True. Use the %rem BIF. How do I check for a run time error in an Eval in RPG IV, since you can’t use the (e) Op code extender? Use Monitor prior to the Eval, and On-error after the Eval. Copyright Jim Martin 2006 - 2010 1:24 Coding Free Format RPG IV Data Manipulation Eval vs. Move We all love Move and Movel. We’ve had years to practice using them. So, is Eval the same as Move? The short answer is No. Let’s get acquainted with Eval before going on. Eval blanks or zeroes out the variable on the left side of the equals sign (except for substringing), then copies the item on the right side of the equals sign to it. For numeric fields, decimal alignment occurs. For character fields, left alignment occurs. This makes Eval for character fields equivalent to a MOVEL operation with the Pad option. The EvalR operation works only with character fields, and is equivalent to a MOVE with the Pad option. Copyright Jim Martin 2006 - 2010 1:25 Coding Free Format RPG IV Data Manipulation Eval vs. Move (continued) Except for the rare cases where the receiving field is longer than the sending field, and padding is not desired, Eval or EvalR will do the job nicely. There are two built-in functions that can provide the solution for these rare cases. Consider the substring BIF (%subst) or the replace BIF (%replace) to handle these situations. Copyright Jim Martin 2006 - 2010 1:26 Coding Free Format RPG IV Conversion of decimal, date, and character A common occurrence is that the wrong data type for the perform. Numeric data comes vice-versa. Dates come into and we need to do some date the data we have is in process we need to to us as characters, or our program as numbers, arithmetic. There are many built-in functions that can solve this situation. Conversion of alpha to numeric can be done with either the %dec or %int BIFs. Conversion from numeric to alpha can be done with the %char BIF. All three of these BIFs can be used to convert a variable of date data type. There are several date formats that can be used to specify an input or output numeric string. Copyright Jim Martin 2006 - 2010 1:27 Coding Free Format RPG IV Must now use BIFs By now you must have gotten the message: BIFs do a great deal of the work in a free format RPG IV program! In fact, without them the RPG language would be crippled! There are 76 BIFs and only 55 operation codes! This means that we must spend some effort in getting to know the BIFs, in detail. It is just as important as learning the op codes. As with the C language that uses nested functions, we in the new free format RPG world will probably start using more and more nested BIFs to get a desired result. It looks cool, but it can become a maintenance nightmare, since the intermediate work fields generated by the compiler are not debug-able. My suggestion is “no more than 3 deep” in nesting. Copyright Jim Martin 2006 - 2010 1:28 Coding Free Format RPG IV Style issues There are syntax rules in this free format scheme, and then there are good programming style rules. Style is like beauty, it’s in the eye of the beholder. But some basic rules may help the future readers of your free format RPG program. First, start coding in position 8, not out in the middle. The compiler doesn’t care but your maintenance programmers will. Also, when using logic nesting, using Dow, Select, and If, indent by two spaces for the next level inward. This helps the future reader better see the logic being used. Programmers in other free format languages have been doing this for a long time. Here’s a style issue that may not fly for everyone: Stop using numeric indicators, for anything. You don’t need them anymore. For general logic requirements, create a named indicator in your D definition specs. Pick a name that describes the situation. For example, use Invalid_Acct_Num instead of *IN45. This removes a level of indirection when someone has to figure out how the program works. Use the file indicator data structure (keyword INDDS) to describe indicators used in display or printer files. Copyright Jim Martin 2006 - 2010 1:29 Coding Free Format RPG IV Style issues No discussion of style would be complete without mentioning comments. Some people use them, and some people don’t. I am a big advocate of comments. In fixed format RPG we could specify comments on a line by themselves (* in 7), or put comments in positions 81-100. In free format we have an opportunity to describe line functions on the same line as the operation, but without panning right using the F8 key. We do this by specifying a // after the semicolon and type away. Be sure not to “parrot” the code. Complete line comments are still useful, and block comments are still needed. Put in all the comments you have time for. Copyright Jim Martin 2006 - 2010 1:30 Coding Free Format RPG IV Problem Areas Many programmers are still not swayed to try free format because many of their favorite operations are not supported, or convert poorly. The biggest complaints come from programmers who use MoveA a lot. MoveA was created many years ago (RPG II time frame) when there were NO character manipulation operations available. A programmer who needed to inspect or modify a character string moved the string to an array (defined 1 character per element), using the MoveA operation. I did this too. Then the array could be scanned using Lookup, and loop logic could be used to find multiple occurrences of something. The characters could be changed as needed too. At the end of the data handling, the array could be moved back to a field, again using MoveA. Sound familiar? Today we have %scan to find strings; we have %subst and %replace to modify parts of strings; we have concatenation and %trim to put together strings; and we have %xlate to modify selected characters in a string. Conclusion: We don’t need MoveA for character manipulation. Copyright Jim Martin 2006 - 2010 1:31 Coding Free Format RPG IV Problem areas Using MoveA to move array information to another array is another story. We need to do this sometimes, and the MoveA operation is a great way to do it. So now what? I don’t have a glib response for this situation. But there are ways to do what we need to do in free format, it’s just going to be a bit longer. On the next page is an example of using a based array (using a pointer) to imitate the MoveA operation using the %subarr BIF. Other schemes can be devised, using For loops to get information from one array to another. It’s always possible that IBM will write a new BIF some day that duplicates the MoveA op code. I don’t think I’ll hold my breath on that one. Copyright Jim Martin 2006 - 2010 1:32 Coding Free Format RPG IV MoveA Example Using the %subarr BIF with a based array to imitate the MoveA operation code: D D D D D Array1 Array2 i Arx S S S 1 Dim(100) 100 Dim(50) 5U 0 Dim(100) Like(Array1) Based(Ptr) In the fixed format we could move entire Array1 into element i of Array2 by saying: C MOVEA Array1 Array2(i) In free format there is no MOVEA, but we can use the based array to overlay an element of Array2 as follows: Copyright Jim Martin 2006 - 2010 1:33 Coding Free Format RPG IV MoveA Example Example continued… Ptr = %addr(Array2(i)); // Set the pointer to array element Arx = %subarr(Array1:1) // This moves the data from Array1 // to Array2 element i The based array (Arx) is only a template. It doesn’t have any storage of its own. When the pointer is set above, the template is laid over the 100 bytes of Array2, element i. The assignment statement modifies those 100 bytes just like the old MOVEA did. Copyright Jim Martin 2006 - 2010 1:34 Coding Free Format RPG IV So… What do you think? My opinion is that free format RPG IV is here to stay. Every article and example you see in print or on the web uses free format - only. RPG IV is now surprisingly similar to many of the other modern languages of today. It is only a short jump from Extended Factor 2 format to “complete” free format. Now, go do it!!! Copyright Jim Martin 2006 - 2010 1:35 Coding Free Format RPG IV STOP!!! Copyright Jim Martin 2006 - 2010 1:36 Coding Free Format RPG IV Copyright Jim Martin 2006 - 2010 1:37