- Free-format (ILE RPG IV): source begins with
**FREE - Fixed-format (RPG IV): H-spec, D-spec, C-spec, P-spec
- RPG II/III (fixed-format): C-spec with implicit variable declarations via result field sizing
- Mixed-format: a column-oriented member that also carries free-format code
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:
- The procedure name is in positions 7-21.
- Position 24 holds
Bto begin the procedure orEto end it. - Keywords go in positions 44-80.
EXPORT,SERIALIZEandREQPROTO(*NO)are recognized there; see REQPROTO(*NO) - Exempting One Procedure.
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:
- RPG IV (ILE RPG, as compiled by
CRTBNDRPG): C-spec opcode in columns 26-35, F-spec device in columns 36-42. - RPG II/III (classic layout, as compiled by RPG/400
CRTRPGPGM): C-spec opcode in columns 28-32, F-spec device in columns 40-46, F-spec file name in columns 7-14.
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.