Supported RPG Features

Mixed-Format Source

A column-oriented member may hold free-format code alongside its fixed-format specs, in either of two forms:

     C                   EVAL      X = 1
      /FREE
       X = 2;
      /END-FREE
     C     X             DSPLY

or without the block directives - a free-form statement is recognized by its blank column 6:

     C                   EVAL      X = 1
       X = 2;
     C     X             DSPLY

Statements execute in source order, whichever form each line is written in: both programs above display 2, because the free-format assignment runs between the two fixed C-specs that surround it. Free-format declarations mixed into a column-oriented member behave the same as declarations written in either format alone.

Note that this applies to a column-oriented member. A **FREE member is fully free-format throughout and cannot contain fixed-format specs.

Procedure Names

RPG has no reserved words, and the compiler follows suit: a free-form DCL-PROC / DCL-PR / DCL-PI name may be any valid RPG name, including words that are keywords elsewhere (value, open, date, main, …) - the DCL-* marker itself makes the name position unambiguous. Calling such a procedure works like this: in an expression (r = open(21);) the name is always taken as a call, and as a standalone statement use an explicit CALLP (callp date(7);) - a bare leading keyword would read as the opcode. END-PROC optionally repeats the procedure name; when present it must match the DCL-PROC name (case-insensitively) or the compile fails with TRN1005.

Variables Named Like Opcodes

The same no-reserved-words rule applies to fields and parameters. A variable may be named with a definition keyword or an opcode word - value, date, static, select, chain, write, return, in, out, and the like - and used freely in declarations, expressions, conditions, BIF arguments, EVAL targets, and DCL-PARM positions, in both source formats:

dcl-s in char(10);
dcl-s out char(10);
dcl-s chain char(10);
eval in = 'left';
if out <> '' and in <> '' and chain <> '';
  msg = %trim(in) + '/' + %trim(out);
endif;

One position is reserved: a free-form statement that starts with a word that is a calculation opcode (in, out, chain, write, return, select, setll, …) is always that opcode. A bare assignment to such a variable (chain = 'x'; or in += 1;) is therefore a syntax error, and the assignment must be written with the explicit EVAL prefix (eval chain = 'x';). A variable whose name is not an opcode (value, date, static, …) assigns with no prefix (value = 1;). Fixed-format C-specs are unaffected: the opcode column already states EVAL, so these names work there without further ceremony. (FOR, TO, and BY are not accepted as variable names.)

Fixed-Format Subprocedures (P-spec)

A fixed-format P-spec (column 6 = P) marks a subprocedure boundary, the same way free-format DCL-PROC/END-PROC does:

Between the begin and end P-specs, a PI D-spec (def-type in positions 24-25) declares the procedure interface - its return type comes from the length, data-type, and decimal columns, and the following blank-def-type D-specs are its parameters (VALUE/CONST keywords set the parameter passing mode). Other D-specs are procedure-local variables, and the C-specs form the procedure body. A matching PR prototype is accepted; the call binds to the procedure by name. A value-returning procedure uses RETURN with the return value in extended factor 2 (for example C RETURN num * 2). Subprocedures require DFTACTGRP(*NO).

Fixed-Format Dialect Detection

Fixed-format source uses one of two column layouts that differ in field positions:

The compiler selects the layout automatically from the source content - no flag or file extension is required. RPG IV is the default; a source written in the classic layout is recognized as such. A source containing a D-spec or P-spec is always read as RPG IV, since neither exists in RPG II/III.

Every device is available in both layouts. A classic WORKSTN F-spec declares a display file and reaches the same screen-I/O support as its RPG IV equivalent - EXFMT, READ, WRITE, subfiles and response indicators all behave identically:

     FR3SCR   CF  E                    WORKSTN
     C                     EXFMTSCR01

One difference follows from the layout rather than the device: the classic F-spec has no free-form keyword area. Columns 44 onward carry the classic layout's own structured entries, so RPG IV F-spec keywords (INFDS, USROPN, COMMIT, RENAME, PREFIX, SFILE, …) are an RPG IV spelling only, and are not read from those columns in an RPG II/III source.

Continued Character Literals

A character literal too long for one line ends the line with + or - while the literal is still open and resumes on the next line. Both continuation characters are supported in both source formats, and they differ in one respect - what happens to the blanks that begin the continuation line.

In free-format, + discards them and - takes the line from position 1:

plus  = 'AB+
     CD';        // ABCD

minus = 'AB-
     CD';        // AB     CD

In fixed-format the same pair applies to a D-spec continuation line, but a - resumes at column 44, the start of the keyword area, rather than at position 1 of the line. Here the continuation text sits at column 48, so four columns of blanks survive:

     DMSGP             S             40A   INZ('AB+
     D                                         CD')      MSGP = ABCD

     DMSGM             S             40A   INZ('AB-
     D                                         CD')      MSGM = AB    CD

Use + when the source is indented for readability and the indentation is not part of the string; use - when it is. A literal may continue over any number of lines, and the two forms may be mixed within one.

Text before the continuation character is kept exactly as written, including a blank immediately before it - so

dcl-c KMSG 'A named constant continued +
     across two lines';

is A named constant continued across two lines, with the single space that preceded the +. Blanks between the continuation character and the line break are not part of the value: the continuation character is the last non-blank character of the line.

A + or - anywhere else in a literal is an ordinary character, so 'A+B' is unaffected. A + that falls outside a literal is still the concatenation operator, and an expression may be split across lines with it as usual:

m = 'AB' +
    'CD';

Continuation works wherever a literal does - a CTL-OPT keyword such as COPYRIGHT, a DCL-C named constant, a D-spec INZ value, and an executable statement alike.

The Extended Factor 2 Area (RPG IV)

The opcodes that take an expression - EVAL, EVALR, EVAL-CORR, IF, ELSEIF, DOW, DOU, WHEN, FOR, RETURN, and CALLP - read the extended factor 2, which spans columns 36 - 80 of the C-spec and leaves Factor 1 blank. The whole area is expression text: an expression operation has no Result, field-length, decimals, or resulting-indicator fields for the expression to work around.

An expression too long for one line continues on the next, which must be blank in columns 7 - 35 and contributes its own columns 36 - 80:

     C                   EVAL      msg = src.name + '|' + %char(src.amount) +
     C                             '|' + src.only2 + '#'

Text is never silently dropped from this area. An expression the compiler cannot consume in full - because it is malformed, or because it runs past column 80 - is reported as TRN1051; none of it is compiled.