This page was written when /free first came out in V5 of the OS. It will be relevant until the last fixed format program is converted to free or the sun burns out, whichever comes first. For clarity V5 or /free refers to when D specifications and /free /end-free tags were introduced into the language.
Welcome to CLEANLY converting fixed format calculations code to /free format. As will be noted later, there are many things that can not be directly converted and must be rewritten.
Quick Path To /Free
1) Regardless of what conversion utility you plan to use, first run the JCRFREESS (Free/Fixed Side-by-Side View) command to show your original rpg4 fixed format code on the left and what that code will look like converted to /free on the right. You will notice many lines of code on the /free side that have ????????. This is code that will not convert to /free.
2) Fix everything in your original source that will not convert to things that will convert. Very simple. (or not).
Note: If your code is still in RPGIII style format, like FACTOR1 IFEQ FACTOR2, Use the JCR4MAX utility to generate D specs and update a TON of things that will convert easier into /free.
3) Convert all *ENTRY and CALL parms to main procedure interface and CALLP prototypes. If you prefer fixed format D specs, use the JCR4PROTO utility. JCRPROTO will generate DCL-* statements.
4) When there are no more ??????? shown in JCRFREESS side-by-side, run the JCR5FREE utility to generate /free code from your source. The JCR5FREE utility reads your existing source and generates a new RPGLE source member. It does not alter your existing source.
5) Use the JCRNUMB command to reformat your new /free source code based on logic structures.
After you have generated the /free source, there are still things that may have to change in your /free code before it will compile.
Does your original program have any LOOKUP, CHECK, SCAN, CHECKR opcodes? This requires some effort as these opcodes were replaced by bifs. The opcodes set on an indicator or %found. The bif returns a numeric value to tell if the lookup was successful or not. The bif does not set an indicator and %found is not set by the bif. Anything in your code conditioned by the indicator or %found (related to these opcodes) will HAVE to have that logic rewritten.
Another thing about the %scan bif. It replaces the SCAN opcode if you were not using an array in the result field. The %scan bif will NOT load an array with each occurrence of the scan value, as did the SCAN opcode. Once again, if knowing every occurrence of the scan value is required, you will have to code your own looping logic and load your own array of positions. Note Arry(*) = Brry(*) or Arry(*) += 1 will load a value into each element.
Klist/Kflds. Recommended to move these, for now, up to immediately below the D specs. Move the /free statement down below the last kfld opcode. You will probably want to come back and scan/replace klists with in-line keys. chain (key1: key2) file.
The RPG manual has free suggestions over opcodes that are no longer valid. ADD, ANDxx, CABxx, CALL, CASxx, CAT, COMP, DEFINE, DIV, DOUxx, DOWxx, GOTO, IFxx, MOVE, MOVE(P), MOVEA, MOVEL, MOVEL(P), MULT, MVR, ORxx, PARM, PLIST, SCAN, SETOFF, SETON, SUB, SUBST, SUBST(P), TAG, TESTB, TESTN, TIME, WHENxx, Z-ADD, or Z-SUB. CALL opcodes must be converted to CALLP (call prototyped) and all PARMS must be converted to prototype structures.
MOVE and MOVEL opcodes are not valid in /free. Gone is all the wonderfully intentional disregard and confusion of data types, attributes, and field lengths these opcodes allowed. (Yeah!) The %DEC and %EDITC bifs address many of the functions provided be these opcodes. There are still situations, like intending to truncate the left of a decimal field, that require a data structure solution.
Super Important: Expression math will not truncate significant digits. You will get error message RNQ0103 The target for a numeric operation is too small to hold the result. This is a crucial difference for RPG programmers. We always took for granted that RPG will automatically truncate numbers (maybe even gotten in trouble with it a few times!). Please remain thoughtful when using expressions, you have to make the resulting field is large enough.
It is recommended to use the H spec keyword EXPROPTS (*RESDECPOS) if your program is going to have divide expressions with intermediate fields. This applies the "Result Decimal Position" precision rules and forces intermediate results in expressions to have no fewer decimal positions than the result. A=(C * (D/E)). The expression (D/E) is an intermediate result.
The DO opcode has been replaced by the FOR opcode, however there is no FOR with just a factor 2.
DO B // has no direct replacement. To duplicate this logic, you will have to code some type of artificial count value. For DummyCount = 1 to B. JCR5FREE will generate dummy counters where required. You will have to define the counters in the D specs.
MOVEA (move array) is another opcode that is probably used throughout your legacy code. It is not available in /free. You will have to code your own looping logic and handle the eval on an element-by-element basis or do some fairly complex pointer manipulations to emulate this functionality. Note Arry(*) = Brry(*) or Arry(*) += 1 will load a value into each element.
Many of the system APIs set bits and TESTB opcode was used to check these values. Replace TESTB with %bitand the /defined BitMask table in JCRCMDSCPY.
|dcl-c bit0 const(x'80'); // 10000000|
|dcl-c bit1 const(x'40'); // 01000000|
|dcl-c bit2 const(x'20'); // 00100000|
|dcl-c bit3 const(x'10'); // 00010000|
|dcl-c bit4 const(x'08'); // 00001000|
|dcl-c bit5 const(x'04'); // 00000100|
|dcl-c bit6 const(x'02'); // 00000010|
|dcl-c bit7 const(x'01'); // 00000001|
Scan jcrcmds source for %bitand to see this in action.
See JCRHFD command on main page to free format Header, File, and Definition specs.
Recommended: Read RPGIV JumpStart, Fourth Edition, by Bryan Meyers. RPG IV Jump Start It will be a big help. Note the JCRCMDS source is based on coding standards proposed in this book.
Last modified April 14, 2016