.JUSTIFY
.FILL
.NO FLAGS CAPITALIZE
.LEFT MARGIN 0
.AUTOPARAGRAPH
.PARAGRAPH 0
.RIGHT MARGIN 68
.NUMBER 1
.TITLE (RSX) RATFOR DOCUMENTATION
.SUBTITLE VERSION 20 FEBRUARY, 1980
A. DESIGN
RATFOR attempts to retain the merits of FORTRAN (universality,
portability, efficiency), while hiding the worst FORTRAN
inadequacies. RATFOR is FORTRAN except for two aspects. First, since
flow control is central to any program, regardless of the application,
the primary task of RATFOR is to conceal this part of FORTRAN from the user
by providing decent flow control structures. Second, it is
possible at the same time to clean up many of the "cosmetic"
deficiencies of FORTRAN, thus providing a language which is easier to
read and to write.
Beyond these two aspects, flow control and cosmetics, RATFOR does
nothing about other weaknesses of FORTRAN, except that the STRING data
type is added. The design philosophy which has determined what should
be in RATFOR and what should not has been that RATFOR should not know
much FORTRAN. Further, that RATFOR should be as machine and operating
system independent as possible to facilitate transport of RATFOR
programs from one machine to another.
I strongly recommend "Software Tools" (Addison-Wesley) by
Kernighan and Plauger for more detail and not a little philosophy
on which RATFOR is based.
.NOFILL
David P. Sykes,
American Management Systems, Inc.
1515 Wilson Blvd.
Arlington, VA 22209
(703) 841-6086
.FILL
.PAGE
.NOFILL
B. THE RATFOR LANGUAGE
B.1 Statements
(a) DO Statement
Syntax:
DO limits
RATFOR statement
becomes:
DO label limits
FORTRAN statement(s)
label CONTINUE
.FILL
The "limits" can be any Control=Initial,Final,Increment string
accepted by the local FORTRAN compiler, since it is copied into the FORTRAN code
directly. RATFOR supplies the appropriate statement number. BREAK and
NEXT statements may be used within "RATFOR statement".
.NOFILL
(b) FOR Statement
Syntax:
FOR (initialize; condition; increment)
RATFOR statement
becomes:
initialize FORTRAN statement
label1 IF (.NOT.(condition)) GOTO label2
FORTRAN statement(s)
increment FORTRAN statement
GOTO label1
label2 CONTINUE
.FILL
The "initialize" statement is executed, then "condition" is
tested, if it is true, "RATFOR statement" is executed, then "increment" is
executed and "condition" is tested again. If "condition" is ever false,
the loop is broken and control passes to the next statement.
"Initialize" is any single FORTRAN statement, which is to be done just
once before the loop begins; "increment" is any single FORTRAN
statement to be executed at the end of each loop, before the test;
"condition" is anything that is legal in a logical IF to the local
FORTRAN compiler.
Any of the three parts may be omitted, although the semicolons
must remain. A null condition is treated as always true, so an
infinite loop results. BREAK and NEXT statements are allowed within
"RATFOR statement"; NEXT jumps immediately to "increment".
.NOFILL
Example:
FOR (I=80; I > 0; I=I-1)
IF (CARD(I) != blank)
BREAK
.FILL
Note that the IF and the statement controlled by it (BREAK) are
considered to be a single RATFOR statement, even though not enclosed
in braces.
.TEST PAGE 18
.NOFILL
(c) IF Statement
Syntax:
IF (condition)
RATFOR statement1
ELSE
RATFOR statement2
becomes:
IF (.NOT.(condition)) GOTO label1
FORTRAN statement1(s)
GOTO label2
label1 CONTINUE
FORTRAN statement2(s)
label2 CONTINUE
.FILL
The ELSE part is optional. The "condition" is anything legal
in a logical IF to the local FORTRAN compiler. If "condition" is true,
statement1 is executed, if it is false and there is an ELSE clause,
statement2 is executed. IF statements can be chained to provide the
equivalent of the CASE statement:
.TEST PAGE 10
.NOFILL
IF (condition 1)
RATFOR statement1
ELSE IF (condition 2)
RATFOR statement2
ELSE IF (condition 3)
RATFOR statement3
ELSE
RATFOR statement4
(d) REPEAT Statement
Syntax:
REPEAT
RATFOR statement
UNTIL (condition)
becomes:
label1 CONTINUE
FORTRAN statement(s)
IF (condition) GOTO label1
or
label1 CONTINUE
FORTRAN statement(s)
GOTO label1
.FILL
The UNTIL part is optional; if omitted, the loop is infinite and
must be broken some other way. The "RATFOR statement" is executed, then
"condition" (if any) is tested; if true, "RATFOR statement" is executed
again. "RATFOR statement" is always executed at least once. BREAK and NEXT
statements are allowed within the REPEAT, with NEXT jumping
immediately to the UNTIL (if any, otherwise, repeating the loop).
"Condition" can be anything legal in a logical IF to the local FORTRAN
compiler.
.NOFILL
.TEST PAGE 12
(e) RETURN (expression) Statement
Syntax:
RETURN (expression)
becomes:
function = (FORTRAN statement)
return
.FILL
where "function" is the name of a FORTRAN function subprogram
which RATFOR remembers from the last
"FUNCTION" statement it saw (ie., the one that started the function subprogram
in which the RETURN statement appears).
The parentheses are required (and are passed to the FORTRAN code).
This statement makes it very clear
exactly what value the function is returning as its value.
"expression" can be any valid single FORTRAN statement that the local compiler
allows to be equated to the function's name. The normal rules for FORTRAN
RETURNs apply: this statment is valid only within a FORTRAN function
subprogram; it may occur several times within a function; the normal
RETURN without the expression may occur anywhere, as always.
.NOFILL
.TEST PAGE 14
(f) WHILE Statement
Syntax:
WHILE (condition)
RATFOR statement
becomes:
label1 IF (.NOT.(condition)) GOTO label2
FORTRAN statement(s)
GOTO label1
label2 CONTINUE
.FILL
As long as "condition" is true (which may be never), "RATFOR statement"
is repeated; if it is ever false (including the first time)
the loop is broken and execution continues with the next statement. BREAK
and NEXT statements are allowed within "RATFOR statement"; with NEXT going
directly to the "condition". "Condition" can be anything legal in a logical IF
to the local FORTRAN compiler.
.NOFILL
.TEST PAGE 7
(g) BREAK and NEXT Statements
Syntax:
BREAK and
NEXT
.FILL
Allowed in REPEAT, WHILE, DO, and FOR loops to either proceed with
the next iteration, or to break out of the loop. The BREAK jumps out of only
one loop, regardless of how deeply nexted the BREAK is.
B.2 RATFOR Language Features
(a) Since symbols are clearer than the .EQ., .GT., etc. used by
FORTRAN, RATFOR allows the use of conventional mathematical symbols, which
it converts into the equivalent FORTRAN.
.NOFILL
.TEST PAGE 11
> or >> for .GT.
< or << for .LT.
>= FOR .GE.
<= for .LE.
== for .EQ.
!, _^, or ~ for .NOT.
!=, _^=, ~=, <>, or >< for .NE.
_\ or | for .OR.
_\_\ or || for .XOR.
_& for .AND.
_&_& for .EQV.
.FILL
(b) All characters between a pound sign (_#) and the end of the line
are treated as comments. This is equivalent to the exclamation point
comment feature in DEC FORTRAN. The pound sign may occur in the first
column, if desired, replacing the FORTRAN "C" in column one (which is
not allowed in RATFOR source code). In this case, the entire line
(with the "_#" replaced by a "C"), will be copied into the FORTRAN code
as a comment (unless the /CO switch is in effect).
(c) If the input file(s) contain more than one program module
(delimited by the FORTRAN "END"), each new program will be started at
the top of a new page in the listing file (if any) and will be separated
by a formfeed in the FORTRAN output file.
(d) RATFOR source code lines are automatically continued if:
.LEFT MARGIN 16
.INDENT -2
.NO AUTOPARAGRAPH
- The statement is obviously incomplete at the end of the line,
as in the middle of the conditional part of a FOR or IF
statement,
.INDENT -2
- When the line ends with a comma,
.INDENT -2
- When the line ends with an underline character, (the
underline character is deleted).
.LEFT MARGIN 0
.AUTOPARAGRAPH
(e) Statements may be placed anywhere on the line. By convention,
blocks of statements are usually indented three spaces. Multiple
statements may appear on one line if separated by semicolons (no
semicolon is required at the end of a statement which is on a line by
itself). If a statement begins with an all numeric token, it is
assumed to be a FORTRAN statement label and is placed in colums 1-5
of the FORTRAN output.
(f) RATFOR source lines may be up to 90 characters long. FORTRAN code is
generated with a maximum line length of 72 characters. Continuation lines are
created if necessary.
(g) Any group of one or more statements (within a single program and
a single file) can be enclosed in braces or square brackets and then
treated as a single RATFOR statement and used anywhere a single statement
may be used. Braces ({ }) and square brackets ([ ]) are synonymous.
.NOFILL
Example:
IF (I == J) [
J=1
I=2
]
causes both statements to be executed if I equals J, whereas
IF (I == J)
J=1
I=2
.FILL
causes only J=1 to be executed conditionally; I=2 would be executed in
any case because only one statement or bracketed group of statements is
controlled by the IF. "RATFOR statement" in any of the examples above could
be a bracketed group of several statements, or a single un-bracketed
statement.
(h) Strings in double quotes (e.g. "foo") are converted into the equivalent
Hollerith string (e.g. 3hfoo), since that is the only legal form in
ANSI standard FORTRAN. Single quotes strings (e.g. 'A') are passed to the
FORTRAN code unchanged. Both single and double quoted strings
are treated as single tokens; this means that symbolic constants
within them are not processed and that the string must be less
then "maxtok" (currently 70) characters long.
Two apostrophes (single quotes) next to each other are passed to
the FORTRAN code as a single apostrophe. Therefore, in direct access
READ/WRITE statements, use two apostrophes together (e.g. READ(1''23)).
(i) Imbedded blanks are significant to RATFOR because they separate
tokens and are used to break input code down into recognizable pieces
(along with special characters). Leading and trailing blanks are not
significant; in particular, the indentation of blocks of code is
meaningless to the pre-processor; it is for visual information only.
The pre-processor does no formatting of the RATFOR source code on the
RATFOR listing; you must provide indentation and other formatting
in the source code file the way you want it to appear on the listing.
.PAGE
C. PRE-PROCESSOR FEATURES
Keywords for pre-processor features must, like language keywords,
appear at the beginning of a line, or after a semicolon.
.SKIP 1
C.1 INCLUDEs
When a line of the form:
INCLUDE RSXfilespecification
is encountered in the RATFOR source code, the specified file is opened and
the input of source code continues from the start of that file until
its end is reached, at which time input reverts to the next line of
the original file. The INCLUDEd file may itself contain INCLUDEs; they can
be nested three deep. The format for the file specification is the standard
for RSX, optionally including UIC and device specifications, (the defaults are
the user's UIC and SY:); an extension (the default is RAT), and a version
(default is the latest version).
If the symbol "defaultopen" is defined (in RATRSX.RAT),
and if the include file is not found based on the file
specification as given in the INCLUDE statement, then the
defaults specified in "defaultopen" are prefixed to the specification in
the INCLUDE and another attempt to find the file is made. However, this occurs
only if the original specification in the INCLUDE contains neither a device nor
a UIC. Note that the default string defined in "defaultopen" MUST be
in quotes; it can contain a device specification, a UIC specification, or both.
.NOFILL
Example:
DEFINE (DEFAULTOPEN="LB:[1,1]")
INCLUDE FOO
causes an attempt to open using "FOO.RAT".
If that fails, another attempt to open using "LB:[1,1]FOO.RAT" is made.
.FILL
If you do not want the contents of the INCLUDEd file to be printed
in the listing file, a "no-list" switch is allowed in the INCLUDE:
INCLUDE/NL RSXfilespecification
Any INCLUDEs within the specified file will not be listed either,
regardless of the switch settings of their INCLUDE lines. (Only the
slash is actually checked for.)
Statements and lines cannot be split across file boundaries;
otherwise, the INCLUDEd code is processed just like it had been in
the original input file.
In order to set the INCLUDEd code apart from the normal code,
lines of code being taken from an INCLUDEd file are preceded by one
or more asterisks on the listing (if they are listed). First level
INCLUDEs are preceded by one asterisk, INCLUDEs within INCLUDEs by
two asterisks, and third level INCLUDEd code by three asterisks.
The INCLUDE feature is especially handy where COMMON blocks are to
be used by several different programs, since only one copy of the
COMMON block and all associated declarations need be kept up to date,
but subroutines, definitions, or any other code can be in an INCLUDEd
file. They are also very useful for files containing a standard set
of DEFINEs, which can then be INCLUDEd in a series of related programs
easily.
.SKIP 2
.TEST PAGE 4
C.2 DEFINE (Symbolic Constants)
The pre-processor contains a simple text-replacement macro
capability that allows the user to create symbolic constants (similar
to FORTRAN variables, but not limited to six characters), and specify
a "meaning" or definition for each, which can remain in effect across
several programs. When the RATFOR code is converted into FORTRAN
code, all occurrences of symbolic constants in the RATFOR code are
replaced by their defined equivalents in the FORTRAN code. The definition
itself may, in turn, be a symbolic constant.
DEFINEs may not appear in the middle of other RATFOR statements.
.NOFILL
Example:
if DEFINE (character=BYTE)
and DEFINE (maxlin=80)
then character LINE (maxline)
is converted into the equivalent FORTRAN code:
BYTE LINE (80)
.FILL
The symbolic constant ("character" in the first line above) and
its definition ("BYTE") must be enclosed in parentheses and separated
by either a comma or an equals sign.
Currently, the symbolic and its definition can each be up to 70
characters long (their length is DEFINEd in the pre-processor) but the
entire DEFINE statement must fit on one line.
The definition of a symbolic constant can be another symbolic
constant. Once a symbolic constant is defined, it cannot be redefined
within the files processed by a single command line. Symbolic constants
must be single, unique alphanumberic character strings beginning
with a letter; no special characters or blanks allowed. Definitions
can be any character string less than 70 characters long but may not
contain dollar signs. If the definition contains parentheses, they must be
balanced pairs.
The definition, either in whole or in part, can consist of a
simple integer mathematical relationship between one or more symbolic
constants and/or integers enclosed in less-then and greater-than signs
(< >). Addition, subtraction, multiplication, and division are allowed.
Evaluation of the expression is strictly left to right; there is no precedence
of operators. If the expression contains previously defined symbolic
constants, they are replaced by their definitions prior to mathematical
evaluation. The result of the part is included in the definition
in place of the expression (it may be the entire definition).
Numbers and the definitions of symbolic constants must be positive or
negative integers.
.TEST PAGE 14
.NOFILL
if DEFINE (foo=7)
then DEFINE (blatz=)
makes "blatz" equal "69" and is equivalent to
DEFINE (blatz=69)
and
DEFINE (dumb=VERSION )
makes "dumb" equal "VERSION 8"
.FILL
If the /SC switch is specified in the command line, a table of all
current (as of the end of the processing for that command line)
symbolic constants and their definitions is included in the listing file.
DEFINEs may occur anywhere in a RATFOR program. Definitions remain
in effect for the remainder of processing of the command line in which
the file containing them occurred. Normally, all definitions are
cleared before processing the next command line, but this can be
prevented by specifying the /RE (RETAIN) switch in the second command
line. A symbolic constant cannot be DEFINEd twice in files in the
same command line (or any INCLUDEd files used by that command line), or
a subsequent command line if the /RE switch is used, since that would
consitute redefinition, which is not allowed. DEFINEs and MACROs can be, and
often are, in INCLUDEd files.
.SKIP2
C.3 MACROs
The MACRO facility is exactly like the DEFINE facility (in fact,
the keywords are really synonymous), except that MACROs allow the passing
of a single argument to be included in the definition at one or more
places at pre-processing time. The place(s) in the definition where
the argument is to be inserted are specified in the definition with a
special flag character (a dollar sign). A MACRO is distinguished from
a simple DEFINE by the presence of at least one dollar sign in the
definition.
MACROs may not appear in the middle of other RATFOR statements, but may
appear anywhere else in the program.
.SKIP 2
.TEST PAGE 16
.NOFILL
Example:
MACRO (foo,$=$+1)
then foo(I) in the RATFOR code becomes
I=I+1 in the FORTRAN code.
because each "$" in the definition is replaced by the
argument "I".
if DEFINE (star=46)
and MACRO (flag=ECOL($)=star)
then flag(7) in the RATFOR code
becomes ECOL(7)=46 in the FORTRAN code.
C.4 IFDEF / IFNOTDEF / ENDIFDEF (Conditional processing)
.FILL
Sections of RATFOR code (one or more lines) can be selectively
processed into FORTRAN or ignored, depending upon the current define
status of a specific symbolic constant. When "IFDEF(symbol)" is
encountered in the RATFOR source code, a check is made to see if
"symbol" has previously appeared in a DEFINE or MACRO statement; if
it has, the source code up to the balancing ENDIFDEF statement is
processed; if not, the source code is skipped until the balancing
ENDIFDEF is found. The "IFNOTDEF(symbol)" is similar,
except that the RATFOR source code up to the balancing ENDIFDEF is
processed if "symbol" has NOT been previously defined.
The symbolic constant can be given a null definition, if it is being
defined only for use with the IFDEF/IFNOTDEF statements (e.g. DEFINE(foo=)
is sufficient). IFDEFs (and IFNOTDEFs) can be nested; if an outer
conditional is unsatisfied, all inner conditionals are skipped, just
like all other code within the unsatisfied conditional.
.TEST PAGE 10
.NOFILL
Example:
DEFINE (foo=3)
DEFINE (foo1=)
IFDEF (foo)
I=9
IFNOTDEF (foo1)
I=72
ENDIFDEF
ENDIFDEF
.FILL
I=9 is processed; I=72 is ignored. Because the IFNOTDEF is nested
within the IFDEF, if "foo" were not defined, I=72 would not be
processed regardless of the status of "foo1".
Undefined conditional code (that not processed into FORTRAN) is
normally printed in the RATFOR source listing, but will have no source
code line numbers on the lefthand side of the page. It can be deleted
from the listing entirely if a /NOIF switch is included in the
command line.
.SKIP 2
C.5 Literal Lines (%)
Occasionally, a line of code must be included in a program which
is modified in some undesirable way by the pre-processor. If a
percent sign (%) occurs in column 1 of the RATFOR source code line, the
entire line, except for the percent sign, will be passed to the
FORTRAN code without ANY modification whatsoever. Don't forget enough
leading blanks to put the start of the resulting FORTRAN line at or past
column seven, as required by FORTRAN.
.SKIP 2
C.6 Debug Lines (?)
If a question mark occurs in column one of a RATFOR source code
line, it is considered to be a debug line and will be processed into
FORTRAN (minus the question mark) only if the /DE (DEBUG) switch was
specified in the command line.
Multiple levels of debug statements can be specified by a
digit (1-9) in the second column (after the "?"). Debug lines
whose level is equal to or greater than the level specified in the /DE:n
switch are processed, but lines with a lower level are not processed into
FORTRAN. Lines with no level specified (blank in column two) are always
processed if the /DE switch is specified. A /DE switch with no value
causes all debug lines to be processed.
.NOFILL
Example:
?5 WRITE (5,1)
?5 1 FORMAT (" DEBUG LINE")
would be processed by specifying /DE or /DE:5 or /DE:4, etc,
but not be processed by specifying /DE:6 or /DE:9.
.FILL
C.7 STRINGs
Since character processing frequently requires the use of strings
(collections of characters of arbitrary length), the pre-processor
adds the STRING data type to FORTRAN. In FORTRAN, a STRING becomes a
character array with one character per element, plus one element for
the terminator (end-of-string character, in DEC-land, a zero byte).
.TEST PAGE 7
.NOFILL
Example:
STRING FOO "BLATZ"
becomes
character FOO(6)
DATA FOO /1hB, 1hL, 1hA, 1hT, 1hZ, eos/
.FILL
The string must be delimited by double quotes, single quotes are
not allowed. Single quotes, may, however, appear within the string.
Null strings are allowed, e.g. STRING#FOO#"".
Note that the STRING function requires that the symbolic constants
"character" and "eos" be defined (usually as "BYTE" and "0") when the
STRING keyword is first encountered; otherwise, "character" and "eos"
will be passed to the FORTRAN code as is and upset the compiler. (The standard
define file, DEFIN.RAT does this.)
Since ANSI standard FORTRAN requires that all DATA statements must be
grouped together and placed in the FORTRAN code after all other specification
statements, but before any executable statements, STRING statements
must be grouped together and appear in the RATFOR source code after all
other specification statements but before any DATA statements. The
pre-processor holds the DATA statement parts until it has output the
"character" statement parts for all STRINGs, then outputs the DATA
statements as a group.
The pre-processor really dosen't care if STRING statements are grouped in
this manner or not. DEC FORTRAN IV doesn't care either, but FORTRAN 4 PLUS
and the ANSI standard do.
Currently, there is a limit of 20 string
specification statements with a total of 300 characters (combined total
of the string names and the characters in the strings) in any one
program module. (DEFINEd as 'numstr' and 'maxstr' in RATDEF.RAT).
.PAGE
D. PRE-PROCESSOR USE UNDER RSX
D.1 FORTRAN is normally installed with the task name "...RAT" so that
in can be run as an MCR task or RUN independently:
.NOFILL
MCR>RAT command line
or
MCR>RUN RATFOR
RAT>command line
.FILL
In the first example, the specified cmmand line will be processed and
the MCR will return; in the second example, RAT will return for
another command line until given a CTRL/Z (EOF).
Regardless of the method of running RATFOR, an indirect command
file specification may be given by preceeding it with the usual
at sign (@). Only one level of indirect command files is allowed. The
default extension is CMD.
The RATFOR output file (default extension: FTN), RATFOR listing file (default
extension: LST), compiler output file for the /GO switch (default extension:
OBJ), and up to six input files (default extension: RAT)
may be specified in a single command line. The default device for all
files is currently SY0:. The default UIC is the user's current UIC.
If an explicit version number is specified, an explicit extension is
required. The FORTRAN output file and the listing file are optional, but one must
be present. The compiler OBJ output file specification is optional.
If only a single file name is specified on a command line
with no equals sign (with switches, if desired), that name is taken
as the name for the output file, listing file, compiler output file (if
/GO is used), and (only) input file.
.NOFILL
Example:
MCR>RAT FOO/SP is equivalent to
MCR>RAT FOO,FOO=FOO/LC or
MCR>RAT FOO,FOO,FOO=FOO/GO
.FILL
since this is the most common form of the command line.
Everything from a "!" to the end of the command line is ignored,
thus trailing comments can be used either when the command line is
input by the operator or from a indirect command file. Lines beginning
with a ";" or a "!" in column one cause the whole line to be ignored, but
are allowed in indirect command files only.
When more then one input file is specified, they are concatinated
together into single FORTRAN output and listing files, and all command line
switches and symbolic constant definitions are in effect for the
entire command line.
A single RATFOR input file may also contain more than one program
module. The end of the RATFOR program module is identified by the
FORTRAN "END" statement, and each will start a new page in the listing file.
The RATFOR source listing contains the RATFOR line number, which is
consecutive for all programs (and files) in a single command line.
It also includes (in parentheses, on the extreme left) the line
number of the FORTRAN code being generated for that RATFOR statement. These
numbers should match (approximately) the line numbers the compiler will
come up with for the FORTRAN code which is being generated by that RATFOR
line. These numbers are very useful for debugging, since compiler and
runtime errors are reported by line numbers. Almost always, you can
find the offending code in the RATFOR listing by looking up the matching
(or almost matching) line number. You should almost never have to look
at a compiler listing.
These numbers should be taken with a grain of salt; the ralationship
of RATFOR to FORTRAN code is neither simple nor straighforward. Many RATFOR
statements cause several FORTRAN statements to be generated; some generate
no FORTRAN at all; still others generate some FORTRAN now, some later.
In general, the numbers listed correspond to the first significant FORTRAN statement
generated by that RATFOR statement.
For example, an ELSE IF generally generates a GOTO and a CONTINUE before the
IF corresponding to the RATFOR IF. In such cases, the listed FORTRAN statement
number is for the IF. Complex RATFOR constructs may cause some of the
listed FORTRAN numbers to be off by 1 or 2, but the numbers always resyncronize
after a couple of simple RATFOR statements (that can be passed directly to the FORTRAN
output). The FORTRAN line numbers are correct for either DEC FORTRAN IV
or FORTRAN 4 PLUS (which differ in the way they number IF's), depending
on the status of symbol "decf4p" (in RATRSX.RAT).
.SKIP 2
D.2 Command Line Switches
The following command line switches are available to control the
actions of the pre-processor. They may be placed after any file specification
on the command line and apply to the entire command line. Where
appropriate, a switch can be negated by /NOsw or /-sw in the RSX style,
however, all of the default switch settings are NO.
.LEFT MARGIN 16
.NO AUTOPARAGRAPH
.INDENT -16
.SKIP 1
/DE:n debug
.BREAK
Causes all lines beginning with a question
mark in column one to be processed into FORTRAN
code; by default such lines are ignored. If
n is specified, only debug lines with an
equal or higher value in column two will be
processed.
.INDENT -16
.SKIP 1
/FO FORTRAN
.BREAK
Causes the generated FORTRAN code to be
included at the end of the listing file (if
one was specified). Each program module
starts a new page. Line numbers on the
listing agree with DEC FORTRAN or F4P
compiler line numbers. By default, the
FORTRAN code is not listed. For this switch to
work, you must also specify an FTN output file
or else the pre-processor must have been built
with "openclose" support, so it can create a scratch
output file.
.INDENT -16
.SKIP 1
/CO compress
.BREAK
Causes the FORTRAN code generated by the
pre-processor to be compressed for faster I/O
by eliminating all comments and unnecessary blanks
in the generated FORTRAN code. This makes the
FORTRAN essentially unreadable and is not recommended
except for well debugged programs. The default
is /NOCO.
.INDENT -16
.SKIP 1
/GO go
.BREAK
Causes the FORTRAN or F4P compiler to be spawned
with a command line of the form "FOO=FOO/SW", where
FOO is from the RATFOR command line, and /SW is
a string of switches for the compiler which can be
defined in the module SPAWNF. Thus, if you don't
want a fancy compile, this allows RATFOR to produce
a finished object module. This switch is available
only of RSX11M V3.2 systems which support the SPAWN
directive and the symbolic constant "SPAWNIT" must be
defined (in RATRSX.RAT). RATFOR does not wait for the compiler
to finish, but goes on to the next command line at once.
If a third output file specification is specified, it is
used on the output side of the compiler command line. If
not given, the device, UIC, and name from the first output
file specification (for the FTN file) are used for the OBJ
file as well. The compiler input file is always the FTN
file created by RATFOR.
.INDENT -16
.SKIP 1
/HE help
.BREAK
Causes a brief description of the command line
switches to be printed on the user's terminal.
The rest of the command line, if any, is ignored.
.INDENT -16
.SKIP 1
/IF ifdef non-listing
.BREAK
Causes RATFOR source code within unsatisfied
conditionals (IFDEFs that are not defined or
IFNOTDEFs that are defined) NOT to be printed in
the listing file, except for the IFDEF
or IFNOTDEF line itself. The default is /NOIF (print
unsatisfied conditionals).
.INDENT -16
.SKIP 1
/LC lower case
.BREAK
Causes RATFOR generated FORTRAN code to be
output in lower case characters (code that is
just transferred from the RATFOR source is in
upper case) making it easy to identify. Also,
RATFOR comments are also converted to lower case
when printed on the RATFOR listing, making it
easier to separate comments from code. The
default is /NOLC.
.INDENT -16
.SKIP 1
/RE retain
.BREAK
Causes the symbolic constant definitions (if
any) in effect at the end of the previous
command line to remain in effect for the current
command line. By default, any previous definitions
are removed at the start of each command line.
.SKIP 1
.INDENT -16
/SC symbolic constant table
.BREAK
Causes RATFOR to print a table of all symbolic
constants defined in a program (or group of programs)
at the end of the RATFOR source code listing (only if
a listing file is specified in the command line). The
table shows each symbol and its character string
definition.
.SKIP 1
.INDENT -16
/SP spool
.BREAK
Causes the listing file, if one is specified, to
be spooled to the line printer. The /SP switch is
useful only if the listing is directed to a
disk file; if directed to LP: the operating system
convention applies (spooled for RSX11/D, direct output
for RSX11/M v3.1, failure for v3.2). This switch works
only if the symbol "openclose" is defined in the
pre-processor.
.INDENT -16
.SKIP 1
/VE version
.BREAK
Causes the RATFOR pre-processor to print its current
version identification on the user's terminal.
The rest of the command line, if any, is ignored.
.LEFT MARGIN 0
.AUTOPARAGRAPH
.PAGE
E. CONVENTIONS AND SUGGESTIONS
While not required for proper pre-processor operation, I have
found the following helpful:
Start pre-processor features (INCLUDEs, IFDEFs, IFNOTDEFs,
ENDIFDEFs, DEFINEs, and MACROs) in column one of the RATFOR source
code lines. Start the first level of code in column four and indent
each logical level three more spaces.
If your line printer, editor, and terminal will print lower case
characters, make all symbolic constants lower case in the RATFOR
source code to make them easy to distinguish from variables. The case
of symbolic constants is not significant to the pre-processor, but
lower case makes them easy to locate in the listing.
If your line printer and FORTRAN compiler will handle lower case
characters, use the /LC switch, having the RATFOR-created FORTRAN code in lower
case makes it easier to read and debug the FORTRAN if you have to.
Also, having comments printed in lower case makes the RATFOR listing
easier to read.
On the listing, line numbering of pre-processor feature lines will
not be exactly correct if the keywords (IFDEF, INCLUDE, DEFINE, etc) are
not in upper case. However, processing of such keywords will be correct
regardless of case.
Symbols will be added to the symbolic constant table somewhat
more quickly if DEFINEs and MACROs are encountered in alphabetical order
by symbolic name.
A "standard" set of DEFINEs is contained in the file
DEFIN.RAT and is useful for most RATFOR programs as well as the
pre-processor itself. A shorter version, without definitions for
lower case characters is in DEFINS.RAT. Such symbolic constants as
EOS, YES, NO, CHARACTER, and STDOUT and macros as INCREMENT($) and DECREMENT($)
should be standardized for all your RATFOR programs.
If you like the IF...THEN, ENDIF, ENDDO, etc. convention used by
some other structured programming languages better then the brackets used by RATFOR,
you can DEFINE such keywords as open and close brackets; e.g. DEFINE(THEN=[),
DEFINE(ENDIF=]).
Leave the blank out of the FORTRAN DEFINE FILE statement, so it is
not confused with the RATFOR DEFINE; FORTRAN doesn't care.
You need to be careful of some DATA statements. For example,
DATA#foo#/"""/ or DATA#foo#/"_#"/ will both be misunderstood by the
pre-processor. In such cases, you can protect the lines with % or use
the decimal value of the character instead of the literal character.
Note that RATFOR does not allow the DEC convention of double quotes
for Octal constants unless the line is protected with a %.
The pre-processor uses a homebrew command line interpreter whose
calling sequence and structure are based on the RT11 routine ICSI.
Command line syntax and style are identical to the RSX conventions with
the following limitations on switch arguments: (1) Limit of one
argument per switch, (2) Character arguments are not allowed,
(3) Arguments are always decimal numbers; neither "." nor "_#" are
allowed to specify radix.
The pre-processor works under F4P on processors without
floating point processors, since it generates no FPP instructions,
provided that symbol "realcode" (in RATRSX.RAT) is undefined.
To include an apostrophe in a string or format statement, use
a double quoted string, e.g. FORMAT#("here's#Johnny"). For direct access
READs and WRITEs, use two apostrophies together, they are converted to
a single apostrophe in the output code, e.g. READ#(1''1).
When creating FORTRAN statements, the pre-processor uses statement
numbers starting at 20000 and going upward. Therefore, you should avoid
using statement numbers in this range. The pre-processor will issue a
warning message if it suspects a statement number conflict.
Study the RATFOR code of the pre-processor itself, it provides
some good examples of what can be done with the language.
I find that I virtually never have to look at the FORTRAN code
generated by RATFOR. I think the success of RATFOR depends
considerably on the concept that the RATFOR code IS the program, NOT
the generated FORTRAN code.
I find the most common RATFOR language error to be improperly
nested IF...IF...ELSE statements. ELSE statements always apply to the
most recent IF that does not already have an ELSE. Thus, if you have
an IF...IF...ELSE sequence, the ELSE applies to the second IF. That's fine
if that's what you want, but if you want the ELSE to belong to the first
IF, you must put brackets around the second IF to show that it is a complete
statement by itself; the ELSE will then fall back to the first IF.
.NOFILL
Example:
IF (statement) IF (statement) [
IF (statement) IF (statement)
statement statement
]
ELSE ELSE
statement statement
.FILL
Assuming the indentation relfects the programmer's intent
(ELSEing the first IF), the lefthand example is not correct, the
righthand one is. Note that if the following statement were
anything except an ELSE, both examples are equivalent, since the
IF#(statement)/statement is really one RATFOR statement and is
therefore controlled as a single unit by the first IF without the need
for brackets.
.PAGE
Here are some rough timing data for version 19:
The RATFOR input in all cases is the file RATRSX.RAT (version 19).
It contains 800 RATFOR source lines, including 157 symbolic
constant definitions. It produces 731 lines of FORTRAN.
The data were collected on a dedicated 11/70 running RSX11/M,V3.1.
All files were on the same RP06 disk.
.NOJUSTIFY
.NOFILL
...PREPROCESSOR#BUILT#WITH#COMPILER#OPTIONS....
FOR FOR FOR FOR F4P
/CD:THR /CD:EIS /CD:EIS V2.2 V2.51
V2.1 /OP:SPD /OP:SPD /CD:EIS
ASCII ASCII NOTASCII ASCII ASCII
----------------------------------------------------------------
COMPILE TIME
(F,F=RATRSX) :28 :27 1:30
----------------------------------------------------------------
RATFOR TASK
SIZE(WDS) 28,352. 30,560. 31,776. 30,720. 28,800.
----------------------------------------------------------------
RAT F=F 1:38 1:06 1:49 1:10 1:00
----------------------------------------------------------------
RAT ,F=F 1:56 1:18 2:17 1:20 1:09
----------------------------------------------------------------
RAT F,F=F 2:04 1:25 2:38 1:28 1:17
----------------------------------------------------------------
RAT F,F=F/LC 2:07 1:26 2:38 1:28 1:18
----------------------------------------------------------------
.FILL
.JUSTIFY
NOTES:
The first line is the time needed to compile the 731 lines of FORTRAN
output. The second line is the size of the pre-processor task if all pre-processor
routines are compiled with the specified compiler options.
The last four lines are the elapsed time (m:ss) require by the pre-processor to
process the 800 lines of RATFOR source, given the command line specified.
For the task sizes above, the symbols "openclose" and "spawnit" were not
defined. See the last page for a subroutine time breakdown which shows
where the (Version 19) pre-processor spends its time.
Overlaying (in Version 20) saves about 4kw off the task sizes given
above. In addition, other changes save about 3kw and speed up the
pre-processor about 8%.
If the symbol ASCII is defined when the pre-processor itself is processed,
the external character set (ASCII on PDP-11's) is not converted to the
internal character set (which is ASCII). Such conversion is not required
on any processor which uses ASCII as its character set, but would be on,
say, IBM machines. Relative to the second column, the third column
shows the overhead associated with this mapping.
Clearly, mapping every character on input and output
is very expensive, although the mapping routines could be speeded up
somewhat.
.PAGE
F. BUILDING RATFOR
A complete set of indirect command files is provided for RSX11/M, but should
work under RSX11/D as well. Under M+, D or IAS you may want to edit the compile
and taskbuild files to create a multi-user version.
The task build command files must be edited to use
the correct resident libraries (if any) and device assignments
for your system. All command files assume RATFOR and STRLIB are
in your current UIC, and that
the device is XX0:, you will have to assign XX0: before starting.
You may also have to edit the ODL file, which assumes you have a FOROTS.OLB.
Note that the build command file puts all modules into RATFOR.OLB for
the task builder.
When first installing RATFOR, build it from the FORTRAN files
provided. This will provide a
basic version of RATFOR. Edit the RATFOR source code to configure it
for your needs (most things are in RATDEF.RAT) and pre-process it using
the basic version of RATFOR. Compile and task build this customized version
to get your production version.
The pre-processor code is in four main files. RAT1, RAT2,
and RAT3 contain the computer-independent parts. All parts which
may have to be changed when moving RATFOR to a different environment
are lumped into RATRSX.RAT.
The whole thing is designed to be as
portable as possible without losing too much speed or capability.
The pre-processor also needs STRLIB.RAT (string library) and ICSI.RAT (command
line interpreter), and several COMMON block definition files which are
INCLUDEd all over the place.
A variety of symbolic constants are available in RATDEF.RAT to
configure the pre-processsor for specific environments. Also, device
assignments for all files can be set in the task build command files.
The internal character set used by the pre-processor is ASCII.
When used on a machine whose external character set it also ASCII,
PDP-11's, for example, much time is saved by not converting each external
character to the equivalent internal character (which is the same anyway).
However, if RATFOR is to be used on a machine whose external character set
is not ASCII (IBM for example), conversion to and from the internal
character set can be provided by undefining the symbolic constant
"ascii" in RATDEF.RAT because the internal-external conversion code is
all conditionally pre-processed. You must edit the ODL file to include
OUTMAP and INMAP.
If defined in RATRSX.RAT, the symbol "decf4p" configures the pre-processor
for use with DEC F4P, if undefined, the pre-processor is configured for DEC
FORTRAN IV. The primary difference is the statement numbering on the
FORTRAN code listing. It also determines which compiler is spawned by
the /GO switch.
If defined, the symbol "decwriter" makes listing on a slow device
faster by reducing the width of lines, especially the symbolic constant
table listing.
If symbol "strings" is undefined, the STRING data type and all code
needed for it are deleted from the pre-processor. No ODL changes are necessary.
Symbol "pagelength" can be adjusted for diferent line printers.
The symbol "openclose" (in RATRSX.RAT and ICSI.RAT) must be defined
if you want support for spooling of listing files included (the default is
still /NOSP). If "openclose" is defined, OPENs are used everwhere instead of
ASSIGN/FDBSET. This also allows for the odd case where you specify
/FO without creating a FORTRAN output file (by creating a scratch
output file). This also specifies the correct carriage control so PIP does
not get confused by the FORTRAN carriage control which otherwise applies
to the output files.
However, DEC's FORTRAN IV version 2.2 has a bug (feature?) and does
not properly handle the ERR= transfer out of the OPEN statement unless
the reason for the ERR is "no such file". Any other error, such as
a bad device name or non-existant UIC, causes an odd address trap (error 3).
Therefore, be advised, if you define "openclose" and use FORTRAN IV v2.2
and get odd address traps, don't panic, it's just DEC.
Another FORTRAN IV v2.2 bug causes the compiler to print comments
following an END statement as part of the just-finished program instead
of part of the next program (in a file with several modules).
The symbol "spawnit" (in RATRSX.RAT) must be defined if you
have RSX11/M v3.2 and want to spawn the compiler to do the OBJ file.
You can define a standard set of switches to be applied to the compiler
command line in module SPAWNF (in RATRSX.RAT).
The maximum nesting depth of INCLUDEs is one less then the value
of "nfiles". If this is increased, logical unit number assingments ("stdout",
etc) must be changed, since the input file LUNs are also the nesting level
(LUN 1 being the basic source code file).
The maximum length of a line of RATFOR source code input is defined
by "maxcard"; the maximum length of a DEFINE or MACRO definition by
"maxdef"; and the maximum length of a token (including quoted strings)
by "maxtok".
The maximum number of DEFINEs and MACROs allowed is defined by
"maxpts" and the total number of characters in all definitions is set by
"maxtbl".
.NOFILL
.PAGE
THIS IS TIMING FOR SYKES' RATFOR, VERSION 19.
(COURTESTY OF STEVE LAZARUS).
SINCE THIS TEST WAS RUN, SCOPY,TYPE,SPAD, AND SCOMPR HAVE BEEN
REWRITTEN TO SPEED THEM UP.
PROGRAM RUN ON 01/02/80 AND FINISHED AT 09:40:45.
122.53 SECONDS ELAPSED TIME 7229. SAMPLES 56 ROUTINES
STRPUT 28.94% 2092.0
STRGET 26.75% 1934.0
GTOK 6.47% 468.0
SLEN 4.14% 299.0
SCOPY 3.83% 277.0
GETTOK 2.70% 195.0
SEQL 2.45% 177.0
NGETCH 2.24% 162.0
DEFTOK 1.90% 137.0
LOOKFR 1.87% 135.0
SCOMPR 1.80% 130.0
TYPE 1.69% 122.0
OUTSTR 1.47% 106.0
SHELL 1.34% 97.0
.MAIN. 1.16% 84.0
SPAD 1.13% 82.0
SITOC 1.07% 77.0
OUTCH 0.79% 57.0
PRTLIN 0.73% 53.0
LEX 0.73% 53.0
UNFOLD 0.66% 48.0
RATLST 0.62% 45.0
PUTBAK 0.59% 43.0
INDEX 0.58% 42.0
EATUP 0.58% 42.0
EQLS 0.54% 39.0
GETLIN 0.48% 35.0
PBSTR 0.41% 30.0
PUTLIN 0.33% 24.0
OPENI 0.26% 19.0
ALLDIG 0.24% 17.0
PARSE 0.24% 17.0
STRIM 0.14% 10.0
BALPAR 0.14% 10.0
OUTTAB 0.12% 9.0
RELATE 0.10% 7.0
OTHERC 0.10% 7.0
OUTDON 0.08% 6.0
ADDDEF 0.06% 4.0
FORCOD 0.06% 4.0
LRPAR 0.06% 4.0
UNSTAK 0.06% 4.0