(RSX) RATFOR DOCUMENTATION VERSION 21 APRIL, 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. David P. Sykes, American Management Systems, Inc. 1515 Wilson Blvd. Arlington, VA 22209 (703) 841-6086 (RSX) RATFOR DOCUMENTATION Page 2 VERSION 21 APRIL, 1980 B. THE RATFOR LANGUAGE B.1 Statements (a) DO Statement Syntax: DO limits RATFOR statement becomes: DO label limits FORTRAN statement(s) label CONTINUE 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". (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 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". Example: (RSX) RATFOR DOCUMENTATION Page 3 VERSION 21 APRIL, 1980 FOR (I=80; I > 0; I=I-1) IF (CARD(I) != blank) BREAK 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. (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 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: 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 (.NOT.(condition)) GOTO label1 (RSX) RATFOR DOCUMENTATION Page 4 VERSION 21 APRIL, 1980 The "RATFOR statement" is executed, then "condition" is tested. If not true, "RATFOR statement" is executed again. The UNTIL part is optional, if it is omitted, the FORTRAN becomes: label1 CONTINUE FORTRAN statement(s) GOTO label1 Thus, the loop is infinite and must be broken in some other way. "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. (e) RETURN (expression) Statement Syntax: RETURN (expression) becomes: function = (FORTRAN statement) return where "function" is the name of a FORTRAN function subprogram which RATFOR remembers from the last "FUNCTION" statement it saw (i.e., 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. (RSX) RATFOR DOCUMENTATION Page 5 VERSION 21 APRIL, 1980 (f) WHILE Statement Syntax: WHILE (condition) RATFOR statement becomes: label1 IF (.NOT.(condition)) GOTO label2 FORTRAN statement(s) GOTO label1 label2 CONTINUE 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. (g) BREAK and NEXT Statements Syntax: BREAK and NEXT Allowed in DO, FOR, REPEAT, and WHILE 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 nested the BREAK is. (RSX) RATFOR DOCUMENTATION Page 6 VERSION 21 APRIL, 1980 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. > 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. (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: - 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, - When the line ends with a comma, - When the line ends with an underline character, (the underline character is deleted). (e) Statements may be placed anywhere on the line. By convention, blocks of statements are usually indented three or four 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. FORTRAN 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. (RSX) RATFOR DOCUMENTATION Page 7 VERSION 21 APRIL, 1980 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 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 successive apostrophes (single quotes) 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) Embedded 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. (RSX) RATFOR DOCUMENTATION Page 8 VERSION 21 APRIL, 1980 C. PRE-PROCESSOR FEATURES Keywords for pre-processor features must, like language keywords, appear at the beginning of a line or after a semicolon. Except for Debug and Literal lines, these features must not appear in the middle of RATFOR statements, nor between an IF and it's ELSE. 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 double quotes; it can contain a device specification, a UIC specification, or both. 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. 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 as if it had been in the original input file. (RSX) RATFOR DOCUMENTATION Page 9 VERSION 21 APRIL, 1980 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. INCLUDEs are also very useful for files containing a standard set of DEFINEs, which can then be INCLUDEd in a series of related programs easily. 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. DEFINE statements may not appear in the middle of other RATFOR statements. Example: if DEFINE (character=BYTE) and DEFINE (maxline=80) then character LINE (maxline) is converted into the equivalent FORTRAN code: BYTE LINE (80) 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 constant 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. Symbolic constants must be single, unique alphanumberic character strings beginning with a letter; no special characters (except underline) or blanks are allowed. Underlines may be embedded in symbolic constants so that COBOL-like names can be used, e.g. DEFINE (DO_MONTH_END=YES). 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. Definitions can be any character string less than 70 characters long but may not contain dollar signs. If the definition contains parentheses, they (RSX) RATFOR DOCUMENTATION Page 10 VERSION 21 APRIL, 1980 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. 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" 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. DEFINE statements may occur anywhere in a RATFOR program, except in the middle of another RATFOR statement. 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. 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. (RSX) RATFOR DOCUMENTATION Page 11 VERSION 21 APRIL, 1980 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) 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. Example: DEFINE (foo=3) DEFINE (foo1=) IFDEF (foo) I=9 IFNOTDEF (foo1) I=72 ENDIFDEF ENDIFDEF 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 (RSX) RATFOR DOCUMENTATION Page 12 VERSION 21 APRIL, 1980 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. C.5 Literal Lines (%) Occasionally, a line of code which must be included in a program 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. 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. 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. 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). Example: STRING FOO "BLATZ" becomes character FOO(6) DATA FOO /1hB, 1hL, 1hA, 1hT, 1hZ, eos/ (RSX) RATFOR DOCUMENTATION Page 13 VERSION 21 APRIL, 1980 The string must be delimited by double quotes; single quotes are not allowed as delimiters. 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 doesn'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). (RSX) RATFOR DOCUMENTATION Page 14 VERSION 21 APRIL, 1980 D. PRE-PROCESSOR USE UNDER RSX D.1 RATFOR is normally installed with the task name "...RAT" so that in can be run as an MCR task or RUN independently: MCR>RAT command line or MCR>RUN RATFOR RAT>command line In the first example, the specified command 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 preceding it with the usual at sign (@). Only one level of indirect command files is allowed. The default extension is CMD. MCR>RAT FTN,LST,OBJ=RAT1,...,RAT6/switches From left to right, the command line denotes: 1. the FORTRAN output file (default extension FTN) 2. the RATFOR listing file (default extension LST) 3. the compiler output file (default extension OBJ) 4. up to six RATFOR input files (default extension RAT) The compiler output file will be produced if and only if the /GO switch is used. Here are some examples: MCR>RAT DB1:AL,AL,AL=AL/GO produces: AL.FTN, AL.LST, and AL.OBJ, all on DB1: (from SY:AL.RAT). MCR>RAT BOB,BOB,BOB=BOB produces: BOB.FTN and BOB.LST. There is no BOB.OBJ (even though it was denoted) because the /GO switch was omitted. MCR>RAT ED,ED=ED/-IN/NOSC produces: ED.FTN and ED.LST. MCR>RAT DM0:[3,3]FRED=FRED/GO produces: DM0:[3,3]FRED.FTN and DM0:[3,3]FRED.OBJ. MCR>RAT ,JAY=JAY/SP produces (and spools) only JAY.LST. A special feature of the command line interpreter allows the most common form of command line (all default extensions, single input file, all output files with the same name as imput file) to be abbreviated to a single file name. (RSX) RATFOR DOCUMENTATION Page 15 VERSION 21 APRIL, 1980 Thus, MCR>RAT MARY/GO/SP is equivalent to MCR>RAT MARY,MARY,MARY/SP=MARY/GO and MCR>RAT DK0:NANCY produces: DK0:NANCY.FTN and DK0:NANCY.LST from DK0:NANCY.RAT The default device for all files is 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 at least one must be present. The compiler output file specification is optional, but if desired, the /GO switch must be used. 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 concatenated 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 cause the start of 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 relationship 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 (RSX) RATFOR DOCUMENTATION Page 16 VERSION 21 APRIL, 1980 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). An index is printed at the end of the RATFOR source listing. It contains an entry for: - The start of each file specified in the command line. The full file specification, including defaults is listed. - Each RATFOR source code line that begins with "#$ " in column 1-3. The whole line is listed in the index. This is normally used to flag the beginning of each subroutine within the file. - Each INCLUDE file. The full file name, including defaults is listed. This index is not only very useful for finding a particular routine within the listing, but it is also a handy outline of the program structure because is shows at a glance the files, programs and includes. The index can be suppressed with the /NOIN switch. 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. For most of the switches, a default value (YES or NO) can be defined in RATDEF.RAT. The standard defaults are: /NODE/NOFO/NOCO/NOGO/NOHE/IF/IN/NOLC/NORE/SC/NOSP/NOVE /DE:n debug 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. DEFAULT: /NODE /FO FORTRAN 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. 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. DEFAULT: /NOFO /CO compress 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 (RSX) RATFOR DOCUMENTATION Page 17 VERSION 21 APRIL, 1980 the FORTRAN essentially unreadable and is not recommended except for well debugged programs. DEFAULT: /NOCO /GO go 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 symbol "ftnswitches". Thus, if you don't want a fancy compile, this allows RATFOR to produce a finished object module. This switch is available only on 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 unless the symbol "waitforftn" is defined in RATRSX.RAT. If a third output file is specified, it is used on the output side of the compiler command line. Example: MCR>RAT X,Y,Z=FOO/GO creates Z.OBJ 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. Example: MCR>RAT X,Y=FOO/GO creates X.OBJ The compiler is not run if there were any RATFOR errors. The compiler input file is always the FTN file created by RATFOR. DEFAULT: /NOGO /HE help 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. DEFAULT: /NOHE /IF ifdef listing Causes RATFOR source code within unsatisfied conditionals (IFDEFs that are not defined or IFNOTDEFs that are defined) to be printed in the listing file. /NOIF suppresses printing of the code except for the IFDEF or IFNOTDEF line itself. DEFAULT: /IF /IN index Causes the RATFOR source code index to be printed at the end of the listing file. DEFAULT: /IN /LC lower case 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. In addition, RATFOR comments are also converted to lower case when printed on the RATFOR listing, making it easier to separate comments from (RSX) RATFOR DOCUMENTATION Page 18 VERSION 21 APRIL, 1980 code. DEFAULT: /NOLC /RE retain 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. DEFAULT: /NORE /SC symbolic constant table 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. DEFAULT: /SC /SP spool 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 This switch works only if the symbol "openclose" is defined in the pre-processor. DEFAULT: /NOSP /VE version 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. DEFAULT: /NOVE (RSX) RATFOR DOCUMENTATION Page 19 VERSION 21 APRIL, 1980 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 than 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 (RSX) RATFOR DOCUMENTATION Page 20 VERSION 21 APRIL, 1980 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 command line is converted to upper case before scanning. 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 successive apostrophes; 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. A common problem if you use FORTRAN 4 PLUS is statements in the generated FORTRAN that cannot be gotten to (FORTRAN IV) doesn't care). Example: IF (... RETURN ELSE IF (... ... results in an unlabeled GOTO right after the RETURN. F4P is smart enough to know you can't get to the GOTO and reject it. The solution is to change the ELSE IF to just an IF, which is logically equivalent. 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. Example: IF (statement) IF (statement) [ IF (statement) IF (statement) statement statement ] ELSE ELSE statement statement (RSX) RATFOR DOCUMENTATION Page 21 VERSION 21 APRIL, 1980 Assuming the indentation relfects the programmer's intent (ELSEing the first IF), the lefthand example is not correct, but 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. Note that the following RATFOR keywords are reserved and must not be used as variable or symbolic constant names: IF ELSE DO FOR REPEAT UNTIL WHILE RETURN FUNCTION STOP END BREAK NEXT DEFINE INCLUDE MACRO STRING IFDEF IFNOTDEF ENDIFDEF Further, these keywords must appear as single tokens preceeded and followed by blanks, tabs, and/or punctuation characters. The keywords must not contain embedded blanks. (RSX) RATFOR DOCUMENTATION Page 22 VERSION 21 APRIL, 1980 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. ...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 ---------------------------------------------------------------- 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) required 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) reduces the task size given above by about 4kw. 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. (RSX) RATFOR DOCUMENTATION Page 23 VERSION 21 APRIL, 1980 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, 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. 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). RATDEF.RAT contains several symbols of the form "dfltXX" which define the default settings for most of the switches. xx is the switch name. (RSX) RATFOR DOCUMENTATION Page 24 VERSION 21 APRIL, 1980 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". Symbol "pagelength" can be adjusted for diferent line printers. 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. 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 or M PLUS 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 by defining symbolic constant "ftnswitches" in RATRSX.RAT. Note that the defined switch string must be a string in double quotes. (RSX) RATFOR DOCUMENTATION Page 25 VERSION 21 APRIL, 1980 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