RATFOR: User's Guide

Sandia National Laboratories · Model SAND80-1171 · 71 pages

User's Guide for Ratfor, a preprocessor for Fortran developed at Sandia National Laboratories (SAND80-1171). Ratfor adds structured control statements and improved cosmetics to Fortran, translating them into standard Fortran code for compilation.

Find parts for this model

Frequently Asked Questions

What is Ratfor?

Ratfor (Rational Fortran) is a preprocessor for Fortran that allows programmers to use structured control statements and free form input, originally developed by Kernighan and Plauger and described in their book "SOFTWARE TOOLS."

What structured control statements does Ratfor provide?

Ratfor provides if-else, while, for, repeat, and do loops, as well as break and next for controlling loop exits, and statement grouping with braces.

What are the cosmetic features of Ratfor?

Ratfor offers free form input, an unobtrusive comment convention, translation of symbols like > and <= into .GT. and .LE., quoted character strings, ascii variable types and string initialization, a define statement for symbolic constants, an include statement for including source files, and in-line switches to control generated code format.

How does this version of Ratfor differ from the original?

This version, developed at Sandia National Laboratories, improves on the original by printing all diagnostics on the user's terminal, adding enhanced string capabilities, expanded break and next features, new program debugging facilities, a formatter program to reformat code into a standard format, a cross reference generator, and an expanded Ratfor library integrated into the operating system.

Does Ratfor require knowledge of Fortran syntax to preprocess code?

No, a major design principle is that Ratfor does not know any Fortran. Other than its recognized keywords, Ratfor does not recognize Fortran statements; other statements pass through with only column formatting and define-statement symbol replacement applied.

Where did the original Ratfor preprocessor used as the basis for this manual come from?

The original version was obtained from the Advanced Systems Research Group, Computer Science and Applied Mathematics Department, Lawrence Berkeley Laboratory, based on the version from the Addison-Wesley Publishing distribution tape.

Manual text content

i) y;~{ I '~~ ({, SANDfV)- 1171 J J:1hm, ~ d Release U~..- - - RATFOR: User's Guide - Bruce E. Wampler nJSTR :JTIDP ~ n: ' ":!rll'"'i IS U lLIM!TED DISCLAIMER This report was prepared as an account of work sponsored by an agency of the United States Government. Neither the United States Government nor any agency Thereof, nor any of their employees, makes any warranty, express or implied, or assumes any legal liability or responsibility for the accuracy, completeness, or usefulness of any information, apparatus, product, or process disclosed, or represents that its use would not infringe privately owned rights. Reference herein to any specific commercial product, process, or service by trade name, trademark, manufacturer, or otherwise does not necessarily constitute or imply its endorsement, recommendation, or favoring by the United States Government or any agency thereof. The views and opinions of authors expressed herein do not necessarily state or reflect those of the United States Government or any agency thereof. DISCLAIMER Portions of this document may be illegible in electronic image products. Images are produced from the best available original document. Issued by Sandia National Laboratories, ope~4ted .(pr the UnitPri StatPs- nr.ruart"'-:>nt qf Enu·j;, L,. !lamlla Cuu.JUtllt.ion. NOTICE: This report was prepared as an account of work sponsored by an agency of the :;~te 8 d 0 ~ta~~s ~'!r: ·~~r~;, !'!.:~u!e .. \tha'!t~"~t;ti~i~!~t .. ~:.~::~r::::."~~~~:,:rr:~~:;;,r. ~~~e~~~& i~:~~~fLfut':~~:~IJ~ 0 %cc~~~t%O~~f,.rte,.~,.~i,~~~~~~~;,~i~;i~f~!m~J~!t ,~~bv~'tu~: product, or process disclosed, or represents that its use would not infringe privately owned richts. Reference herein to any specific commercial product, process, or service ~;J:~~s n~~r!~~!~~r~C~~u:~~~':[~~. 0 ~r 0 ~~~,.~~~~eh~~~e"t}~~~~e~!~ fi~'!!'~~=n~: any agency thereof or any of their contractors or subcontractors. The views and ooinion li: expressed herein do not neceSM.tily st.at.e or reflect those of the United $\fot~$ Govrrnmr.nt anv !19'Ant'~ t thn~nnf ~ r any uf u,.,u_ ... vutuu,. tuu UJ. SUUCUUll'l:Lr!LIH' ~ l . 1 2 ... .... RRRRRR A R R A A R R A A RRRRRR AAAAAAA R R· A A R R A A R R A A SANDB0-1171 Unlimited Release Printed Jun~ 1980 TTTTTTT FFFFFFF T F T F T FFFFF T F 00000 0 0 0 0 T F 0 T F 00000 -------- = ... ~" -~-~,- >• USER'S GUI!)E 'Bruce E. Wampler Sandia National Laboratories Division 1723 Albuquerque, N.M. ABSTRACT RRRRRR 0 R R 0 R R 0 RRRRRR 0 R R 0 R R R R Rat for is a preprocessor for Fortran that allows pr•ugn:trnm~1· to use .structured control atatgment.s :1nrl the free form input. This manual describes a version of Ratfor developed at Sandia National Laboratories that has a number of enhancements over the original version developed at Bell Laboratories • r-Th-i•_boo_k_w_m : .. -,-m-en_""'" ___ ~of:::~~=~;;.· .......,:;::;;:=of:t:.he:U:ni:ted=S=te=te=,G=.,.,=n_:m:_en_t.,.l Neither tho United States Government nor any agency thereof, nor any of their employees .. makes any warranty, express or Implied, or assumes any legal liability or responsibility for the accuracy, completeness. or usefulness of any information, apparatus, product, or process disclosed, or represents that its use Y<Ould not infringe privately owned rights. Reference herein to any specilic comiTII!n:inl nroduct. Of~, or service by trade name, trademark, manufacturer, or otherwise, docs not necessarily constitute or imply its endorsement, remmmendation. or favodny Uy tM United States Government or any agency thereof. The views and opinions of authors expressed herein do not necessarily state or reltect those of the United States Government or anv ageney thereof. lliSTRIBUTIOt:l OF TmS t:lt'CiJMBH IS mJLIMiTE~ 3-4 r1 .. ... The rising cost programming practices both the development Preface of computer software has made the use of state of the art essential to improve productivity. One method of reducing and maintenance costs is the use of structured programming techniques, and a programming language that supports structured programming. While a· number of structured programming languages are currently available, there are often problems with these languages that prevent their acceptance by a large body of programmers. These programming languages often do not interface cleanly with the existing operating system and software libraries. The code produced by these compilers is often not efficient. In addition, due to the long term acceptiilnce of other languages such as Fortran, many programme·rs find it difficult to ~earn both the new .. control statements and data structures provided by the newer structured languages. The fact is that Fortran continues to be the language most widely used for a.large part of the software industry. Fortran has many good qualities that keep it the one truly universal programming language available today. First and foremost :is that it is available for virtually every computer made. Fortran is usually heavily supporte~ by the computer manufacturers, with the Fortran compiler often producing the best code of any language processor available for a particular machine. In addition, Fortran usually interfaces to a large library of system support routines and utility programs. In. spite of its universality and efficiency, Fortran does not contain the language features needed to support structured programming~ Fortran 77 is not muoh of an improvement. The programmer still lacks a complete set of loop control structures, is limited by data types, and is forced to use a rigid and unpleasant statement layout format. One answer to the problem is the use of a preprocessor that converts a language with structured control structures and better cosmetics into standard Fortran. All of the good points of Fortran are retained, while the benefits of a structured language are also obtained. Since the underlying language is Fortran, it is also easier for long time Fortran programmers to learn the new language~ One such language processor is Ratfor (for Rational Fortran), originally developed by Kernighan and Plauger and described ~n their book "SOFTWARE TOOLS." Ratfor provides structured control statements (if else; while, for, .repeat, and do loops) as well as some other features that make the language easier to use (free form inpu~, character string facilities, better comment conventions, define statement, and include file processing)~ Good Ratfor code is much easier to read l.hau even the be~t Fortran, thus making program development and maintenance easier. 5 6 The Ratfor designed with preprocessor portability as described in "SOFTWARE TOOLS" was originally a major goal. As a result, it lacks a number of features needed for program development work in a professional production environment, such as complete error diagnostics and a clean interface to the existing operating system environment. This document describes a new version of Ratfor and some associated tools that in large part make up for the deficiencies of the original version of the Ratfor preprocessor. The original yersion of the Ratfor preprocessor described in this manual was obtained from the Advanced Systems Research Group, Computer Science and Applied Mathematics Department, Lawrence Berkeley Laboratory, Berkeley, California, which was based on the version obtained from the distribution tape available from Addison-Wesley Publishing. Large portions of the text were used directly from the public Hatfor manual obtained from and written by the Advanced Systems Research Group. Thi~ v9r~ion of Ratfor h~a a number of improvomonto over the original. One of the main deficiencies of the original version was the poor output format of the error diagnost,ics· produced by-the preprocessor. All diagnostics are 'printed on the user's terminal in this -v~r$~on. There are also enhanced strini capabilities, and expanded features for break and next. New facilities have been added for program debugging. In addition to the Ratfor preprocessor, a formatter program to reformat Ratfor programs into a standard format has been developed. The formatter enforces ·a well defined set of indentation and layout rules, thus producing consistent code that is easier to read and debug. Besides the formatter, a cross reference generator has been implemented. The Ratfor library has been enhanced and expanded, and. a full description of each routine ·is included in this manual. The entire Ratfor system has been integrated into the operating system·, ~o that Ratfor is as easy to use as any other system lan~uaJe processor. ), TABLE OF CONTENTS 1.0 INTRODUCTION 1.1 Keyword Summary ••••••••••••• 10 2.0 BASIC RATFOR STATEMENT SYNTAX 2.1 Statement Grouping •••• 2~2 Null statements 2d 2.11 Multiple statements per line FreR form statement layout -~ 2.4.1 Continuation 2.4.2 Labels 2;4.3 Literal lines 'II 11 11 12 12 12 12 2.5 Generated Fortran output • • • • • • • • • 12 3.0 COMMENT STATEMENTS Comment statements ~ ~ ~ ~ • Preproceooor option switohee Debug statements 4.0 CONTROL-STATEMENTS 4.1 if-else 4.2 4.3 relational operators • function value return ,. • • .. • It ~ 13 13 14 14 15 15 7 8 5.0 LOOPS 5. 1 do loop 5.2 for loop 5.3 repeat until loop 5.4 5.5 while loop • • break and next 6.0 CWARACTEH~ 6.1 6.2 ascii declaration string declaration .• 16 17 18 18 18 20 20 6~3 Quoted character ~trings ••.• , • • • • • 22 6.4 Character sets 1.0 OTHER FEATURES 7. 1 define 7.2 include 8.0 PROGRAM INDENTATION AND LAYOUT 9.0 CONCLUSIONS 23 24 25 26 9.1 Summary •••••••••••••• ·· ••• 28 9.;2 References 28 APPENDIX A Error Diagnostics . . . 29 APPENDIX !3 Stand arc! Symhnl:;l • • )2 APPENDIX c - Library Routines . . . 35 APPENDIX D Formatting Program 54 APPENDIX E - Using Ratfor on the Local system 56 APPENDIX F Porting Rat for . . . . . . . 58 RATFOR ·USER'S GUIDE 1;0 INTRODUCTION Ratfor is a preprocessor for Fortran. Its primary purpose is to encourage readable and well-structured code while taking advantage of the universality, portability, and efficiency of Fortran. This is done by providing the con~rol structures not available in bare Fortran, and by improving the "cosmetics" of the language. Ratfor attempts to retaining its desirable statements: - "if"-"else" overcome the main deficiencies of Fortran qualities by providing structured control -"do", "while", "for", and "repeat"-"until" loops - "break" and· "next" for controllirig loop exits - statement grouping with braces while flow The cosmetic aspects of Ratfor have been designed to make it concise and reasonably.pleasing to the eye: - free form input - unobtrusive comment convention -translation of>, <=, etc. into .GT., .LE., etc. - quoted character strings - ascii variable types and string initial~zation - "define" statement for symbolic constants - "include" statement for including source riles - in line switches to control generated code format ·Ratfor is implemented as a preprocessor which translates the above features into Fortran, which can then be fed into almost any Fortran compiler. Each of the Ratfor features will now be discussed in more detail. In the following descriptions, a "statement" is any legal statement in Fortran: assignment, declaration, subroutine call, I/0, etc., or any of the Ratfor statements themselves. Any number of Fortran or Ratfor statements can be enclosed in braces-- } --to make a compound statement, which is then equivalent to a single statement and usable anywhere a single statem~nt can be used. 9 10 1.1 Keyword Summary A major design principle used in the preprocessor is that Ratfor does not know any Fortran. Other than the following keywords, Ratfor does not recognize any Fortran statements. Any statements not beginning with a keyword are passed through the preprocessor without any analysis other than formatting columns and replacing symbols that have been defined in a define statement. The following special. Each of following. % ;; if-else >,<,==,etc. return do for is a summary the keywords of is all the keywords recognized by Ratfor as explained in detail in the sections - statcaln::ul ~~·uuplng - statement separation - include ~ode literally -· l.!UllllUt:HilS - if else construct relational operators .. fnnr.-tion valuo return DO luuv - fnr lnnp repeat-until - repeat loop while - while loop • gxit from loop next - goto loop top ascii - Ratfor character type string - initialize string constants EOS - end of string marker define - constant definition include - include external file 2.0 BASIC RATFOR STATEMENT $YNTAX 2.1 Statement grouping Ratfor allows a group them in braces-- { and }. single Rat for statement of statements to be treated as a unit by enclosing This is true throughout the language: .wherever a be used, there could also be several enclosed in can braces. For example: if (x > 100) { call error ( ... ) err = 1 return If braces are not valid chara~ters in the local operating system, the characters "L" and "]" may be used instead of "{" and "}" respectively. 2.2 Multiple statements per line Ratfor supports multiple statements per line with the semicolon (;). When two or more statements on a single line are separated by semicolons, they are split and treated by the Ratfor preprocessor as single statements. No semicolon is needed at the end of each line because Ratfor assumes there is one statement per line unless told otherwise. Multiple statements per line can be useful for initializations, where stateme~t ordering i~ not particularly important. For example: first:O l~st:lOOO middle=500 2.3 Null statements Ratfor also allows null statements, most useful after "for" and "while" statements. A semicolon alone indicates a null statement. For instance, while (getlin(line, int) I= EOF) 11 12 would read lines from a file until the end-of-file was reached and for (i:1; u·ne(i) ==BLANK; i=i+1) positions after leading blanks in a line. 2.4 Free form statement layout 2.4.1 Continuation St.!'lt.PmPnt.c; may bo placed o.nywhet·e t_lll a llue. ~XPllCit continuation coutrol is not usually needed in Ratfor. Ratfor does not allow use of the Fortran column 6 continuatlnn nnnv.,.ntion. Linoo ending in d. uumma(,), star(• 1, pluR(+); minus(-), equal(=), greater(>), less(<), not(l), ancl(&), or(i), or a left paren(() are automatically continued. Parenthesized conditional expressions, such as those foun'd in the if statem~nt, are also automatically continued until . . the closing right parenthesis is found. For explicit control, statements ending with an underscore(_) are also continued, but the underscore is discarded. (Note: a slash(/) does not cause a continuation to allow compatibility with the DATA statement.) 2.4.2 Label8 Any statement that begins with an all numeric field is assumed to be a Fortran label and tR pl;ft:-f;'d in oolumno 1-5 upon outpuL. Thr;re arA no other restrictions on column alignment or line. length for Ratfor statemeuts. 2.4.3 Literal lines Statements may be passed through the Ratfor compiler unaltered by using the tt:'aale ohoroctel" ":!" uu a llue by itself· before' and after the lines desired to be literal. Thus, whenever a line beginning with "%" is encountered, all following lines ar~ left absolutely unaltered until another line containing only a "%" i ·"' f,-,,,;·pJ., (Note: This mean.! .!ymbol:::s lu::~lde %' s are not checked to see if they have been defined.) This is a convenient way to pass regular Fortran or assembly code through the Ratfor compiler. 2.5 Generated Fortran output The output produced by the preprocessor is made to fit in columns 1 through 12, with continuation marks in column 6 as necessary. All blanks (except in quoted strings) are removed from the output. It is often difficult to relate Ratfor source code with the corresponding Fortran generated c6de. If desired, the line number of the Ratfor source that generated ·the Fortran output line may be included in columns 73-80. This line number generation is controlled by the $N switch. (Note: see section 3.2 for a general description of Ratfor switches.) By default, line numbers do not appear in generated Fortran code. If a $N+ is inserted into any comment statement (e.g., "# $N+"), then the source line numbers will be included in columns 73-80 in the generated Fortran code. Line number generation is turned orr· with $N- in a comment. 3.0 COMMENT"STATEMENTS 3.1 ·Comment statements Ratfor does not recognize or allow comments with a C in column 1. Instead, a sharp character "#" in a·line mark~· the beginning of a comment and the rest of the line is considered to be.that comment. Comments and code can co-exist on the same line~ For example, function dummy (x) # Sample function to show some comments dummy = x return end # Simply returning the parameter Notice that Ratfor allows blank lines, which are removed by the pr~pruc~~sur. All comments are ignored by Ratfor, and do not normally appear in the t~an3lated output file. 3.2 Preprocessor option switches A number of preprocessor runtime options have been implemented in this version of Ratfor. These options are controlled by switches that appear anywhere inside of a comment statement. The general form of a switch in a comment is: # $X+ or # $X- where •x~ is the letter representing the switch, and '+' is used to turn the switch on while '-' is used to turn the switch off. This version of Ratfor 13 14 supports the following switches: $C controls comments in Fortran output $D controls inclusion of debug statements $H controls conversion of hollerith strings $N controls output of Ratfor source line numbers For example, the $C switch controls whether or not comments are included in the generated Fortran output. Ratfor comments may be included in the generated Fortran output by using the "$C" switch. When the $C switch is enabled (by a $C+ in a comment), all comments will be included the generated Fortran code. 3,3 D~hug ~tatements Comments beginning with a "#D" are treated as possible debugging statements, and are controlled by the "$D" switch. When the $D switch is enabled (by a· $D+ in a comment), then the "#D" is removed when the program is translated, and the rest of the statement is treated as a normal Ratfor statement. If the $D switch is off, the lines beginning with #Dare treated the same as normal comments (i.e., ignored), 4.0 CONTROL STATEMENTS 4.1 if-else Ratfor provides an "else" statement to handle the construction "if a condition is true, do this thing, otherwise do that thing". The syntax is if (legal Fortran condition) statement else statement where the "else statement" part is optional. The "legal Fortran condition" is anything that can legally go into a Fortran logical IF. The Ratfor statements may be one or more valid Ratfor or Fortran statements of any kind. If more than one statement is desired, the statements must be enclosed by braces. For example, if (a > b) k = 1 call remark( ••• ) else if (a < b) k = 2 call remark( ••• ) else return Ratfor does not allow the Fortran arithmetic if statement. The % mechanism may be used if absolutely necessary. 4.2 Relational operators Sometlmes the characters >, <=, etc. are easier to . read in Fortran condition statements than t.he, standard Fortran .EQ., .LT., et.c.. Ratfor allows either convention. If the special characters are used, they are translated in the follo.wing manner: -- .EQ. I= .NE. < .LT. > .GT. <= .LE. ): .GE • . oR. & .AND • • NOT. 4.3 Function value return Ratfor allows an to the calling program. called "fname" is: fname:value return alternative method for returning the value of a function . / The usual method for returning the value of a function 15 16 Ratfor allows the following: return value where "value" is anything valid on the right hand side of an assignment statement. For example: 5.0 LOOPS function min2(v1,v2) integer v1, v2 H (v1 < v?) return v1 aloe return v2 5. 1 do loop Ratfor allows the "do" statement with the same semantics as found in Fortran, but in a form that fits into the syntax of Ratfor. The syntax is do loopvar=legal-Fortran-DO-text statement where the part that follows the Ratfor "do" can be anything that is legal for a Fortran "DO" statement. However, no loop label is needed or allowed. The "statement" part uf the loop may be a single statement or multiple statements enclosed in braces. Ratfor automatically orovidA~ n lnnp lnb~l in tho generateu code. Following is an example of a Ratfor do: do i=1,100 { arr(i)=O arr2(i):O Often the operations to be performed in the do loop can be' more clearly expressed using a Ratfor "for" loop, although the _generated code will likely be more efficient for a do loop. 5.2 for loop The "for" statement is similar to the "while" except that it allows explicit initialization and increment steps as part of the statement. The syntax is for (init; condition; increment) statement where "init" is any single Fortran statement which gets done once before the loop begins. "Condition" is again anything that is legal in a logical IF. The condition is treated like a while condition in that it is tested before the loop. is executed, which allows the loop to he executed zero times. "Increment" is any single Fortran statement which gets done at the end of each pass through the loop, before the test. Any of init, condition, and increment may be omitted, although the semicolons must remain. A non-existent condition is treated as always true, so "for( ; )" is an indefinite repeat. The "for" statement is particularly useful for backward loops, chaining along lists, loops that might be done zero times, and similar things which are hard to express with a "DO" statement· and obscure to write directly. Here is an example of a "for" loop: integer function equal(str1, str2) ascii str1(ARB),str2(ARB) integer i for (i:l; str1(i) == str2(i); i=i+1) if (str(i) == EOS) return YES equal:NO return end The above code compares the strings in str1 and str2, returning YES if they are equal. 5.3 repeat until loop The "repeat-until" statement allows for repetition of a ·group of statements until a specified condition is met. The syntax is: repeat state.ment until ( condition 17 18 The "condition" (which must be enclosed in parentheses) is any one valid in a logical IF, and if more than one Ratfor statement is desired, the statements must be enclosed by braces. The "until" part is optional, and if omitted, results in an infinite loop which must be broken with a "break" or "next" statement (see BREAK and NEXT section). The condition is tested at the end of the loop, so the body of the loop will always be executed at least once. An example of a repeat-until loop is: repeat call putc (BLANK) col = col + 1 until (tabpos(col,tabs) -- YES) 5.4 while loop Ratfor provides a "while" statement, which is simply a loop: "while some condition is true, repeat this group of statements". The syntax is while (legal Fortran condition) statement The "legal Fortran condition", which must anything that can go into a Fortran logical IF. be enclosed in parentheses, is The condition is tested before execution of any of the Ratfor $tatements, sn if thP ~ondition is not motj the loop will be executed zero times. "StatArnPnt" ~an be any valid Ratfor or Fortran construct. If more than one statement is desired, the statements must be enclosed by braces. For example: while (getc(c) I= EOF) o • convrt(c) call putc(c) 5.5 break.and next Ratfor provides two statements for additional loop control, one for leaving a loop early and one for beginning the next iteration of the loop. "Break" causes an immediate exit from whatever loop it is contained in (which may be a "while", "for", "do", or "repeat"). Control resumes with the next statement after the loop just as though the loop termination condition had been met. In the normal case ( where simply "break" is used), only one loop is terminated by a "break", even if the "break" is contained inside several nested loops. "Next" is a branch to the bottom of the loop, so it causes the next iteration to be done. "Next" goes to the condition test part of a "while" or "until", to the top of an infinite "repeat", to the reinitialize part of a "for", and to the usual increment part of a "do". Examples of break and next: for (i=1; i<10; i=i+1) if (array(i) -- BLANK) next if (array(i) -- EOS) break This version of Ratfor has an extension to break and next, where an integer constant "n" or the word "all" ~ay follow "break" or "next" in the form "break n", "next n", "break all", or "next all". The integer constant "n" specifies how many loop levels ara to be exited. "Break ali" would cause all nested loops to be exited, while "next all" would cause a branch to the bottom of the outer most loop. The default value for "n" (where ~o integer value is given) is one, and is the normal case. The "n" or "all" forms of break and next must be used with caution· since adding or deleting a loop can change how many loops the "n" affects. For example: while ( a < b ) while ( c > d ) repeat if ( X :: Y break 2 # break 2 loop levels call doit(a,c,x) # end of repeat forever loop call done # break will come to here # end of outer most loop will cause two loop levels (while ( c > d ) and repeat) to be exited when x==Y· A "break aYl" would have caused the outer "while (a < b)" loop to be exited. 19 20 6.0 CHARACTERS 6.1 ascii declarations This version of Ratfor provides for characters. These variables may be declared to same syntax as "integer" or other Fortran type a data type be of type declarations: ascii chr, let ascii str(10) # simple character variable # character array for . manipulating "ascii" using the Although the name "ascii" has been chosen for this data type, it does NOT nece~~arily imply that characters are represented by the ASCII character set (see section on "CHARACTER SETS"). "ascii" was chosen instead of "character" to avoid conflict with the Fortran-77 "CHARACTER" type. Ascii variables will be mapped to the most appropriate Fortran type declaration for the local operating system. In the worst case, Ratfor characters may map to INTEGERs, but will often map to a "B1TE" type. In any case, if the programmer treats ascii variables as variables (arrays) capable of holding characters represented as small integers when performing calculations, machine independent Ratfor code should result. ascii arrays can be used to hold strings. By convention, any string contained in an array is terminated by a predefined ratfor constant called EOS (for end of string). A commonly used value for EOS is zero, but other values may be used on different systems. By always using the symbol EOS when manipulating strings, the actual value of EOS will not matter. If variable length strings are to be manipulated, then an ascii array large enough to hold the longest possible string must be used. 6.2 string declaration In order to make it more convenient for the programmer to use ascii arrays initialized to a desired string value, the "string" statement has been added to this version of . Ratfor. "String" is used to initialize a previously declared ascil array by generating the appropriate Fortran DATA statements. These data :s L•Lwments 1nit1nl11!:C each element of the a.:~oll ar·l'ay Lu a small integer value that is equivalent to the string's internal representation on the local machine. In order to maintain portability, string statements (as well as other DATA statements) should follow all other declaration statements. There are two forms of the string statement. One is for one dimensional arrays, while the other is for multi-dimension~! tables of strings. The syntax of "string" for one dimensional arrays is: string name 'value' where name is the variable name of the string, and value is the quoted value of the string. Either single or double quotes may be used to enclose the string. Ratfor emits data .statements to initialize the a~ray to the correct values. The last value of the ascii array will be initialized to EOS. The individuai characters of the string can be manipulated like ordinary ascii arrays. The ascii array to hold the string must be previously declared, and at least as long as the string plus one for the EOS (excess elements will be uninitialized). However, if the ascii array is not large enough to contain the entire string, the Ratfor preprocessor will not detect the error, and a Fortran compilation error will likely re~ult. The same is true if the array.has not been previously declared in an ascii statement. The syntax for the multi-dimensional string statement is similar to one dimensional strings •. The array is initialized column-wise, i.e., with the left most index varyirig most rapidly in ~he usual Fortran sense. the table variable name must be first declared using a "ascii" declaration, with the first subscript large enough to contain the longest string (plus the EOS) to be held in the table (elements not needed for shorter strings are left uninitialized), and the second subscript specifying the total number of strings to be contained in the table. The syntax for two dimensional strings is: string tname(*,~) 'value' where "tname" is the variable name of the table, "n" is the number used to refer to the column of tname to cont~in the string "'value'"· The "*" is present to indicate that the first subscript will be varied to initialize tname("1 •• length of 1 value 1 +1",n) to the individual characters of •value•. There will be one "string(*,n)" declaration for each string contained in the table, with the single appropriate "ascii" declaration appearing before its corresponding "strtable" declarations. The "n" part of strtable is general in the sense that it can be ~xtended to the form "n1,n2" if it is desired for some reason to initialize a three (or more) dimensional ascii array. In any event, the first subscript in the multi-dimensional string statement must be a "*", indicating that it is always the first (left most) subscript that is varied most rapidly. 21 22 Some examples of "ascii" and "string": ascii c, t fi simple character variables ascii token( 50) 41 50 character array ascii rat4(7) 41 array to hold string ascii tbl(10,3) fi table to hold 3 strings 41 longest string will be 10 chars:tbl(*,3) string rat4 'ratfor' fi initialize rat4 to 'ratfor<EOS>' string tbl(*,1) 'msg one' fi the first string of tbl string tbl(*,2) 'msg two' 41 the second string string tbl(*,3) 'msg three' fi last string, longest 6.3 Quoted character strings Thoro arc two form& of quoted gharaoter itringi reooaniz~d by the F~~for preprocessor. The quoted strings appearing in "string" statements.are one form. These strings are never passed to Fortran directly, but are i•ascii" arrays initialized by the appropriate "DATA" statements. The other kind of quoted character"strings are those appearing as actual arguments in subroutine or function call statements or in format statements. The internal representation of these strings is dependent on the local machine. ProvLsions are provided in Ratfor for converting text enclosed in matching double or single quotes appearing in statements other than "string" or "strtable" to nH ••• format. Depending on the particular installation, this conversion may be done by default, or quoted character strings may be left unaltered. In either case, it is possible to explicitly control the conversion by using a source code switch to the preprocessor. The hollerith control switch may appear in any comment in th.e source program. A comment of the fol:'m fi $H+ will turn the con~ersion on, while 41 $H- will turn conversion off. The $h (upper or lower h) may appear anywhere in any comment. For instance, fi $H+ call remark ('Error detected.') would produce the following translation: call remark (15hError detected.) For maximum portability, quoted character strings should be used only in format statements. If strings are needed in subroutine or function calls, then the "string" declaration should be used to initialize ascii arrays to the desired string. When quoted strings (or hollerith strings) are used in calls, the result is often a "packed" string, with several characters packed to a machine word. It is often impossible to determine the end of such strings on some operating systems. In addition, it can be difficult to manipulate packed strings on a character by character basis. It is also probably better to stick to single quotes, rather than mixing single and double quotes. 6.4 Character sets Different internal character sets are used on different computers. Probably the most common character set representation is the "ASCII" character set, but others are used such as "Display Code", "Field Data", or "EBCDIC". It is often impossible to write programs that are completely character code independent, but there are some techniques that can be used. The Ratfor "string" statements generate Fortran DATA statements that initialize the ascii array to values using the internal character set of the local machine, which may or may not be "ASCII". Thus, code using "string" will b~ portable, but the character values actually used on different machines may be different. (In addition, character sets do not map one to one, so that all special characters such as •:' are not found on all character sets.) some When manipulating ascii arrays and checking for specific .values, however, specific value must a~pear in a conditional statement, such as: "if (char 55)". What character the value '55' really represents will depend on the host machine's internal character representation. For example, in ASCII, a 55 represents a '7', while in Di~play Code a 55 represents an '&'. If the program is really meant to check for a '7', then a defined symbol should be used to represent the value, such as: "define(DIG7,55)" for ASCII machines. If the program were to be ported to a Display code machine, then it would only be necessary to change the define statement to: "define(DIG7,34)". Then the statement "if (char == DIG7)" would have the same meaning on both machines. The standard symbols library described in Appendix B will be changed for each implementation to represent the local character set. Thus, by always using the "Rtring" declaration. as well as the defined symbols for characters found in the symbols library, it is possible to write programs that are in fact character set independent. 23 24 7.0 OTHER FEATURES 7. 1 define Ratfor provides a very simple parameterless macro substitution facility. Any string of alphanumeric characters can be defined as a name: thereafter, whenever that name occurs in the input (delimited by non-alphanumerics) it is replaced by the defined value. (Note: the text within quoted strings and text on literal % lines is not checked for defined values. All other text is checked, and symbols replaced by their defined values when detected.) All parts of the defined value are also checked to see if they too were defined. The syntax of define is: define(dname,value) whore "dnnme" i~ Lhe 11am~ to be rap!Aced, and "valueH .is the replacement value. There can not be a space between the word "define" and the left p~r·iwthesis. The. value is ter~inated by a balanc~ng ")", and may continue over several lines (up to a maximu~ of 200 to~al characters). The define itself statement does not generate any Fortran output. An alternative form of define is define dname value where spaces are uses as delimiters. The "value" of "dname" is then terminated by a sharp (#) or the end of the line, ~nrl ~~n not b~ multi-lined. Some examples of the ••~~" nf ri'<lfin~: define(ROW, 10) define(COLUMN,25) dimension array (ROW, COLUMN) define(EOF,-1) lf (getlin(line, int) == EOF) .... define(msg,'error encountered') Defines may be included anywhere in the code, as long as they appear before the defined name occurs. Upper ~nrl lower aases ARE significant (thus EOF 1~ not the same as eof). It is suggested that constants be defined using UPPER CASE for the name, and all other variables and Ratfor keywords using lower case. This makes it easy to spot constants in the code. Defines should not be used to redefine Ratfor keywords since that may cause the formatter program to function incorrectly. 1.2· include External files may be inserted into the input stream via the "include" command. The statement include filename replaces the include statement with the text found in the alternate input file "filename". example, This is especially useful for inserting common blocks. For function exampl (x) include comblk # this line will be replaced exampl =, x + z return end might translate into _function exampl (x) common /comblk/q,r,z # replaces include line exampl = x + z return end The form of the filename is dependent on the local operating system. 25 26 8.0 PROGRAM INDENTATION AND LAYOUT The free format of Ratfor allows great flexibility in the layout of the programs. However, unless a consistent layout and indentation policy is used, chaos may result, especially when { } pairs are used. The following rules lead to Ratfor programs that are easy to read and debug. ( 1 ) Line up braces in the same column on separate lines. ThP. hr~I"~;>S of a begin end block should always appear by themselves on a separ:=~t.e line. ThP. corresponding and should be in the same column. This may "waste" lines, but it is very difficult to get the braces to match otherwise. Untils should also be lined up with the corresponding repeat. (2) Use indentation. Each major control statement (if, for, do, while, repeat) should be in the form: control statement statP.ment where the statement group under the control statement indented four spaces. (Note, this allows statements to begin either on a tab stop, or a tab stop + II spacP.R.) of.4, with the spaces. This If braces arc u3ed, they should be indentP.rl ? spaaes inEtood slatements enclosed hy t-he f l IZrnnp 11ti 11 b'iing indor1~.~:.d II allows the { and } to stand out for easy pairing, yet does not cause excessive indentation. (3) L.iue up nestea 'it' - else if's. When many if - else if - else if else's are nested, the ~nrle will be cooia3t to folluw lf all the else lines up with the original if. (4) Put defined constants in UPPER CASE and everything else in lower case. This makes it very easy to tell constants from variables, and also may avoid errors where a variable has been called the same name as a defined constant. All examples of Ratfor code included in this manual have followed these rules. The following example shows a somewhat more detailed example of these layout and indentation rules. All of these rules except the UPPER CASE rule for defines are automatically enforced by the Ratfor formatter program. The following Ratfor program shows the result of following the layout rules: define(AVAL,100) define(LIM,AVAL-1) define(BFACT,100) if ( a < b ) { i=1 j:2 else if ( a > b ) repeat else { call sub(a) call sub(b) until ( a < b ) # define name in upper case # note: defines re-check fl initial level # { in 2 # then part in 4 # same level line up U } lines up with { # else matches if fl else part in 4 # { in 2 more # in 4 from repeat # line. up # matching } # line up repeat, until # line up elses a:AVAL # AVAL is defined constant for (i=1; i<LIM; i=i+2) #LIM is a constant a:a/i b=O while ( b > a ) { call sub(a) b=b*BFACT # in 4 from for # out 4, not part of fori # part of while body # another constant ·u end of while loop # end of else part 27 28 9.0 CONCLUSIONS 9. 1 Summary Ratfor was originally written in C, a high-level language, on the Unix operating system. This version is written in Ratfor itself, and is brought up by a bootstrap version written in Fortran. Ratfor generates code by reading input files and translating any Ratfor keywords into standard Fortran. Thus, if the first token (word) on a source line is not a keyword (like "for", "wMtle", etc.) the entire otatcmcnt i3 3imply copied to the output with appropriate character tr~nslation and formatting, RAt.for rlnAfl nnt. li'nf.\'•1 any Fortran and. thuo doeo 11-:.t ht!i'tdle auy Ful'l,r•au t!r•r•ur• detection. Errors in Ratfor keyword syntax are generally noted by a message on the user's terminal along with an indication of the source routine namA ~nrl 1ine number. Ratfor error diagnostics are also included in the generated Fortran output file as comment lines beginning with "C???". Ratfor demonstrates that with modest effort Fortran-based programmers can increase their productivity ~Y using a language that provides them with the control structures and cosmetic features essential for structured programming design. Debugging and subsequent revision times are much faster than the equivalent efforts in Fortran, mainly because the code can be easily read. Thus it becomes easier to write code that is readable, reliable, and even esthetically pleasing, as well as being portable to other environments. 9.2 References 1) Kernighan, Brian W., "Ratfor--a Preorocessor for A RAtionAl Fortran", 8911 Laboratories publication. Also available from the UC Berkeley Computer Science libr'a!'y. 2) Kernighan, BriQ.n W. and P •• J. PlAilgAr·, ".St:'ftware Tools". 1\ddioon-Wcolcy Publishing Company, Reading, Mass., 1976. APPENDIX A - ERROR DIAGNOSTICS Errors in Ratfor keyword syntax are noted by a message to the user's terminal along with an indication of the ~ource routine name and line number. (A '?' for the name indicates no subroutine or function names have been found yet. The main program will either be called '?' or the name of the previously defined routine.) The offending line is also printed on the user's terminal. The error message is included in the generated fortran output fil~ as a comment line of the form "C??? message", which will allow the Fortran to be c0mpiled without errors being causen by the error message itself. bad nesting in previous routine Usually caused by unmatched braces in the previous subroutine or function; can also be caused by bad nesting of if else, while, repeat or for. bad switch value Illegal value, for a $S switch, should be - or +. can not open include file File to be included was not a local file or file could not be opened due to lack of internal buffer space • define hash table overflow Too many different symbols used in defines. definition too.long The number of characters in the definition exceeded Ratfor's internal array size. FATAL ratfor error! Fatal internal Ratfor error, such as running out of table space. Translation stops immediately. for clause too long For loop parts too long for internal Ratfor arrays. getdef is confused Define statement parser could not figure out definition. illegal break Break did not occur inside a valid "while", "for", "do" or "repeat" loop • illegal else El3c clau3e probably did not follow an "if" clause. 29 30 illegal next "Next" did not occur inside a valid "for", "while", "do" or "repeat" loop. illegal right brace A right brace was found without a matching left brace. illegal string value: no quotes The character string for the "string" type must be enclosed in quotes. includes nested too deeply Operating system dependent include depth exceeded. incomplete string "(*,n)" missing ")" or something in multidimensional string. invalid for clause The "fo1·" clau~~ ~id not contain a valia inlt, conaiti6rt, and/or increment section. invalid use of keyword A Ratfor reserved keyword was used in an invalid context, such as a normal Fortran statement or in a logical relation. missing comma in define Pare~thesis form of definitions must contain a comma between keyword and definition. missing left paren A .parenthe~is was expectea, prooaDiY in an "if" statement, hut not found. missing parenthesis in condition A fight parenthesis was expected, probably in an "if" statement, but not found. missing quote, assumed A quoted string was not terminated by a quote, the quote mark is assumed. missing right paren A right pnronthcoio w~o expected in a Vortran (a~ opposed to natfor) statement but not found. non-alphanumeric name Definition keywords may contain only alphanumeric characters. non-alphanumeric string name Name used for string must be alphanumeric. stack overflow in parser Statements were nested at too deep a level. statements nested at a time. token too long Current maximum is 100 A token (word) in the source code was too long to fit into one of Ratfor's internal arrays. too many characters pushed back The source code has illegally specified a Ratfor command, or has used a Ratfor keyword in an illegal manner, and the parser has at~empted but failed to make sense out of it. too many definitions Ratfor's internal arrays could not hold all the definitions. unbalanced parentheses Unbalanced parentheses detected in a Fortran (as opposed to·Ratfor) statement.··. unexpected EOF An end-of-file was reached before a statement had been accounted for. This can caused by unmatched braces or mismatched if-elses or unclosed loops. warning possible label conflict This message is printed when the user has labeled a statement with a label in the 23000-23999 range. Ratfor statements are assigned in this range and a user-defined one may conflict with a Ratfor-generated one. 31 32 APPENDIX B - Standard SYMBOLS include file The following is a list of standard definitions the user obtains when using an appropriate "include" statement. The exact form of the include statement to use is described in Appendix E - Ratfor on the local system. Note: this listing of •symbols.ir4' corresponds to the VAX version, which is an ASCII machine. If ASCII is not the native character set of the local machine, then the actual value of the symbols may be different, and not all the characters may be present. II SYMBOLS.IR4 II Should be put on a file named 'SYMBOLS.IR4' II standard definitions file II character definitiona define(AMPER,38) define(AND,38) define(ATSIGN,64) define(BACKSLASH,92) define(BACKSPACE,8) define(BACKTICK,96) define(BANG,33) define(BAR,124) define(BIGA,65) define(BIGB,66) u~flrr~(!IIGC,t5?) define(BIGD,68) define(BIGE,69) define(DIGF,70) dcf'ine(DI00,71) define(BIGH,72) define ( BIGI, 73) define(BIGJ,74) define(BIGK,75) define(BIGL,76) define(BIGM,77) define ( BIGN, 78) define(BIG0,79) det'ine t BIGP, ~0) define(BIGQ,81) define(BIGR,82) define(BIGS,83) define(DIOT,04) define(BIGU,85) define(BIGV,86) define(BIGW,87) define(BIGX,88) II Rmpersand '&' # same as ampersand fl '@' II '\' II ascii control char for BS II ' , ' II exclamation mark 'I' II or bar ': ' II 'A' define(BIGY,89) define(BIGZ,90) define(BLANK,32) define(CARET,94) define(COLON,58) define(COMMA,44) define(DASH,45) define(DIG0,48) define(DIG1,49) define(DIG2,50) define(DIG3,51) define(DIG4,52) define(DIG5,53) define(DIG6,54) define(DIG7,55) define(DIG8,56) de!'ine(DIG9,57) define(DOLLAR,36) define(DQUOTE,340 define(EQUALS~61) define(GREATER,62) define(LBRACE,123) define(LBRACK,91) . define(LESS,60) define(LETA,97) define(LETB,98) define(LETC,99) define(LETD,100) define(LETE,101) define(LETF,102) define(LETG,103) define(LETH,104) define(LETI,105) define(LETJ,106) define(LETK,107) define(LETL,108) define(LETM,109) define(LETN,110) def1ne(LET0,111) define(LETP,112) define(LETQ,113) define(LETR,114) define(LETS,115) define(LETT,116) define(LETU,117) defi.nP. ( I.ETV, 11il) define(LETW,119) define(LETX,120) II 'z' II blank II , .. ' II I: I tl ' ' ' II same as tl '0' tl '9' II '$' II Ill I II '=' II '>' tl ' { ' II ' [ ' tl '<' tl 'a' ' ' MINUS ' _, 33 34 define(LETY,121) define(LETZ,122) fl I z I define(LPAREN,40) fl I ( I define(MINUS,45) fl I- I define(PERCENT,37) fl I% I define(PERIOD,46) fl I . I define(PLUS,43) fl '+' define(QMARK,63) fl I? I define(RBRACE,125) fl I } I define(RBRACK,93) fl I ) I define(RPAREN,41) fl I ) I define(SEMICOL,59) fl I • I , define(SHARP,35) If I 4f I def1ne(SLASH,q7) ff I/ I define(SOUOTE,39) # I I I define(STAR,42) II I* I d&fine(TIIB,9) fr Meii tab control character define(TILDE,126) fl I- I define(UNDERLINE,95) fl I I II other standard definitions II following ~ defines are always automatically included in ·fl the VAX version of RAT4, and will usually be fl predefined to the appropriate values on other systems. #VAX define(ascii,byte) II what RAT4 character type maps to #VAX define(ASCII,byte) II both ways #VAX define(EOS,O) define(EOF,-1) define( ERR, -3) # End of string II End of file value ~~ Error flag define(FILENAMESIZE,50) #max. characters in file name II (incl EOS) used in openf and for include define(index,indexx) II avoid conflict with system utility define(INDEX,INDEXX) II ditto define(max,maxo)· define(min,minO) define(MAXCARD,130) define(MAXLINE,l32) define(NEWLINE,10) define(ALPHA,-9) define(ARB,100) define(DIGIT,2) define(LETTER,1) define(NO,O) define(OK,1) define(YES,1) define(OR,BAR) II to use fortran library II input and output "card" size # must be 2 more than MAXCARD fl end of line mark II can be used for alphanumerics II used for dummy array dimensions fl returned by library routine 'type' II returned by library routine •type' II returned when failure If success flag 4f returned when success If let them be the same APPENDIX C - RATFOR LIBRARY ROUTINES A useful set of Ratfor library routines has been implemented. These library routines have been compiled using the same set of definitions described in Appendix B, and will thus comply with the local convention for EOS, etc. "It is critical that the calling program declare the type (e.g.,. integer or ascii) of the library functions since the implicit type will often be real! They are described in alphabetical order on the following pages. *** string movement *** scopy - copy string at from(i) to to(j) stcopy- copy string at from(i) to to(j); increment j concat - concatenate two strings, move to a third addset - put c in array(j) if it fits, increment j *** string searching *** index - find character c in string str findst - find a substring - exact match fndpat - find i substring - ignore case findcs - find first ~haracter contained in a list skipcs - skip over characters contained in a list skipbl - skip blanks and tabs at str(i) getwrd - get next non-blank word from arg string ••• string comparison ••• equal - compare str1 to str2; return YES if equal equal2 - compare str1 to str2, length known equalf - compare str1 to str2, fold to one case sgrtr - compare str1 to str2; return YES if greater *** st~ing characteristics *** alldig - return YES if str is all ~igits length - compute length of -string type - determine type of character *** string conversion ••• ctoi - convert string at in(i) to integer, increment i itoc - convert integer to character string fold - convert string to lower case clower - convert character to lower case upper - convert string to upper case cupper - convert charact~r to upper case ••• terminal message I/0 ••• getdcl - get initial command line input getarg - parse line from getdcl ftlerr - print hollerith message and stop prompt - write a string to terminal; suppress cr/lf putmsg - write a string to terminal with cr/lf remark - print Fortran hollerith message to terminal reply - read a string from the user's terminal 35 36 *** miscellaneous *** NAME gtime - get current time gdate - get current date bubble - bubble sort integer array in increasing order shsort - shell sort integer array in increasing order addset - put c in array(j) if it fits, increment j SYNOPSIS stat = addset(c, array, j, maxsize) integer function ] DEE;CRirTION Adds a sing!~ character 1 c 1 to the Ratfor ascii array 'array' at 'array(j)' ·and then increment~ the index 'j'. I~ also 'checks 'maxsize' to be sure that there's enough room to do so. YES is returned if the routine succeeded, otherwise NO. SEE ALSO sc~py, stcopy, concat NAME alldig - return YES if ~tring is all digits SYNOPSIS stat = alld.ig( str) integer function DESCRIPTION Tests a string to see if it contains only digits. The string is a Ratfor uOtii array terminated with an Eon marker. Returns YES if string is all digits, otherwise NO. SEE ALSO type, skipcs, findcs NAME bubble - bubble sort integer array in increasing order SYNOPSIS call bubble(iv, n) [ subroutine ] DESCRIPTION Bubble sorts integer array iv(1) ••• iv(n) in increasing order using a bubble sort. SEE ALSO shsort NAME clower - fold c to lower case SYNOPSIS : ch = clower(c) [ ascii function DESCRIPTION Fold character 'c' to lower case,. if not already there. If 'c' is not alphabetic, returns it.unchanged. Argument 'c' is unchanged, but return value 'ch' may be same as 'c', thus causing replacement if desired. If the internal character set ha~ only one case, returns with no change. SEE ALSO fold, cupper, upper 37 38 NAME concat- concatenate 'str2' to •str1', result in •str3' SYNOPSIS stat= concat(str1,str2,str3,maxsize) integer function ] DESCRIPTION Concatenates 'str1' and 'str2', placing result in 'str3'· ( 1 Str2' is appended to the end of 'str1'.) 'Str1', •str2', and 'str3' are strings terminated with EOS. 'Str1' and 'str3' may be the same physical array. It uses •maxsize' to check that there's enough room in 'str~'. YES is returned if the routine succeeded, otherwise NO, which happens only if the length of 'str1 1 plus the length of •str2' is greater than 'maxsi~e'. the maximum length ~llnwPrl in •str3'. SEE ALSO scopy, stcopy, addset NAME ctoi - convert string at in(i) to integer, increment i SYNOPSIS n = ctoi(in, i) · [ integer function DESCRIPTION Converts a Ratfor ascii string to an integer. Starts looking at position 'i' of 'in'. Plus and minus signs are not allowed. Leading blanks and tabs are ignored; any subsequent numeric value. The first non-digit return, 'i' points to this position, digits are converted to the correct seen terminates the scan; upon 'n' is the value of the integer. The 'in' array is a Ratfor ascii array terminated with an EOS marker (or a non-numeric character). Zero is returned if no digits are found, and 'i' will remain unchanged. SEE ALSO itoc DIAGNOSTICS There are no checks for machine overflow. NAME cupper - convert cha~acter .to upper case SYNOPSIS ch = cupper(c) [ ascii function DESCRIPTION Converts character 'c' to upper case, if not already there. Non-alphabetic characters are returned unchanged. changed. If the internal character set has only one no change. SEE ALSO upper, clower, fold NAME equal - compare strl to str2; return YES if equal SYNOPSIS stat= equal(str1, str2) integer function ] DESCRIPTION Argument 'c' is not case, returns with Compares two strings, returning YES if they are the Bame, NO if they differ. Strings will be equal if their length i~ identical, and all characters are exactly equal (including case). Length of the strings is not known ahead of time. Each string is a Ratfor ascii array terminated with an EOS marker. SEE ALSO sgrtr, equa12, equalf 39 40 NAME equalf - compare folded str1 to str2; return YES if equal SYNOPSIS stat= equalf(str1, str2) integer function ] DESCRIPTION Compares two strings, differ. Strings will be characters when folded returning YES equal if their to one case except case is not significant. Length of time. Each string is a Ratfor ascii marker. if they are the same, NO if they length is identical, and all are equal. Identical. to 'equal', of the strings is not known ahead array terminated with an EOS SEE ALSO sgrtr, equa12, equal NAME equal2 - compare str1 to str2; return YES if equal SYNOPSIS ~LaL ~ equal2(strl, str~, len) integer function DESCRIPTION CumJJai·e::; Lwu ::~trings,. !"eturning YJ::S it' they are the same, NO if they differ. Strings will be equal if all characters are exactly equal. The length.of "str1" and "str2" is assumed to be the same and is specified in the "len" argument. Each stl"ing is a Ratfor ascii array terminated with an EOS marker. SEE ALSO sgrtr, equal, equalf NAME findcs - searches for first occurrence of characters SYNOPSIS place = findcs(str1,str2) ( integer function ] DESCRIPTION Scans •str2' for first occurrence of any character found in •str1'. 'Place' will be set to index or •str2' where any character of_ •str1' was found. Returris zero if no characters in 'str1' are found in 'str2'. SEE ALSO skipbl, skipcs, alldig, type NAME findst - find a substring in a string - use exact case SYNOPSIS stat = findst(pat, patbeg, str, strbeg) integer function ] DESCRIPTION Searches for the substring starting at patbeg of pat in strbeg. (pat(patbeg) is the substring, str(strbeg) is search) Both pat and · str are terminated by and EOS. str beginning at the string to The search must match exactly, e.g., case is significant. Findst returns a zero if the subs~ring is not found, otherwise it returns the index from str(strbeg) where the substring starts. SEE ALSO index, fndpat, findcs, skipcs 41 42 NAME fndpat - find a substring in a string - ignore case SYNOPSIS stat = fndpat(pat, patbeg, str, strbeg) integer function ] DESCRIPTION Fndpat is exactly the same as findst, except that upper and lower case is ignored, i.e., all letters are folded to one case for the search. Searches for the substring starting at patbeg of pat in str beginning at strbeg. (pat(patbeg) is the substring, str(strbeg) is the string to searcn) ~Otfi pat and str are terminated by and EOS. Findst returns a zero is the substring is not found, otherwise it returns the index from str(strbeg) where the substring starts. SEE ALSO index, find~t, findcs, skipcs NAME fold - convert string to lower case SYNOPSIS call fold (~1:.,·) P~SCRIPTION Converts characters in the ascii array 'str' to lower case characters. Non-~lphabetic characters are left unchanged. If the internal character set has only one case, returns with no change. The •str' array is a Ratfor ascii. array terminated by an EOS marker • .SF.E ALSO clower, cupp_er, upper NAME ftlerr - print single-line message, and stop SYNOPSIS call ftlerr (message) DESCRIPTION Ftlerr is useful when a fatal error is encountered in ~he calling program. Ftlerr writes the message onto the user's terminal, and then stops and returns to the operating system level. The message array is generally a Fortran quoted string used directly in the call statement and passed in the internal character format used by the local machine, and NOT the conventional Ratfor string ascii array. In order to perform the possible unpacking needed, messages printed using this routine should be terminated with a period: e.g., 'message.•. SEE ALSO prompt, putmsg, reply, remark. NAME gdate - get current date SYNOPSIS call gdate(date) DESCRIPTION 'Gdate• is used to get.the current date, which is returned as a Ratfor ascii array 'date•, terminated with an EOS, in the format: dd-mmm-yy or other similar form produced·bY the local operating system. IMPLEMENTATION Operating systems generally have some mechanism for picking up the current date. This date should be converted into a Ratfor a~cii string similar to the above format. SEE ALSO gtime 43 44 NAME getarg - get command line argument from in(i) into out, increment i SYNOPSIS len = getarg(in, i, out) [ integer function ] DESCRIPTION Starting at position 'i' in array 'in', skips any leading blanks and tabs and returns the next argument and its length. An argument is any series of characters terminated by a BLANK, TAB, NEWLINE, SLASH, or EOS. The terminator ;i,s not ret.urnFHi l'l.8 part of the argument. 1 i 1 is iu~o:r't:Hntmted to the position just past the end of the argument. in o.rray 'eut 1 •• If' Lhe l..~:!!'mluaLur· was a ::iLA::iH, then is called, the SLASH will be returned as the first argument. The word io returned the next time getarg character of the Both 'in' and 'out' are Ratfor ascii arrays terminated with an EOS marker •. When all of the words in 'in' are ekhausted, 'i' will be returned unchanged, and the returned length of 'out' will be zero. The purpose of getarg is to act as a parser for command lines obtained from 'getdcl' in the form like: 'FILNAME1/SW1/SW2 FILNAME2/SW3' Successive calls to getarg using the above string would yield five ar~s: 1 FILNAME1 i, '/SW1', 1 /SW2', 1 FILNAME2', and '/SW3'. DEE AL30 ~KiPbl, skipcs, findcs, getwrd, getdcl NAME getdcl - get initial command line input SYNOPSIS len = getdcl( str ) [ integer function DESCRIPTION Getdcl is used to return a command line entered by the user when the program is first run. It returns a standard Rat for string ter.minated by an EOS, converted to upper case. It is useful for passing switches or filenames to a program in a fashion close to system command line conventions. Getarg can be used to retrieve filenames and switches. IMPLEMENTATION Getdcl is rather system dependent, and may require that a program be run in a differen~ fashion than normal. For example, on the VAX implementation, instead of using the RUN command to run a program (called .PROG in .this example), the user must define a symbol in the following fashion: $ PROG::=$DRAO:PROG.EXE and then invoke the program with: $ PROG commands whe~e any characters following the "PROG" (i.e. "commands") are then available to the user program using getdcl. Note that the "$" and the "DRAO:" (or other symbol including a device) are critical in the definition of "PROG"~ If the local system is unable·to pick up a command line string, then 'getdcl' should issue some appropriate prompt, and then read in a command line from the user, perhaps using 'reply'. SEE ALSO reply, getarg 45 46 NAME getwrd -get non-blank word from in(i) into out, increment i SYNOPSIS len = getwrd(in, i, out) [ integer function ] DESCRIPTION Starting at position 'i' in array 'in', skips any leading blanks and tabs and returns the next word and its length. A word is any series of characters terminated by a BLANK, TAB, NEWLINE, or EOS. The terminator is not returned as part of the word. 'i' is incremontcd to the pu~ition just past the end of the word. The word is returnP.d in array 'out•. Both 'in' and 'out• are Ratfor ascii arrays terminated with~n EOS marker. When all of the words in 'in' are ~xhausteO. 'i' wilt be returned unchanged, and the returned length of 'out' will be zero. SEE ALSO skipbl, s·kipcs, findcs, getarg NAME gtime - get current wall-clock time ::iYNOP.'HS ·call gtiw~(~ime) DESCRIPTION 'Gtime' is used to get the current time, which is returned as a Ratfor ascii array 'time', terminated with an EOS, in the format: hh:mm:ss HIPLEMI!:NTAT!UN Oper_ating systems generally have some mechanism for pi.Qking l.lp the current wall-clock time. This time should be convertP.d into a Ratfor asul! string in a form similar the above format. SEE ALSO gdate NAME index - find character c in string str SYNOPSIS loc = index(str, c) [ integer function DESCRIPTION Returns the index of the first character in 'str' that matches 'G', or zero if 'c' isn't in the array. 'Str' is a Ratfor ascii array terminated with an EOS marker. 'o' is a single character. SEE ALSO findst, fndpat, findcs, skipcs NAME itoc - convert integer to character string SYNOPSIS length = itoc(int, str, size) [ integer function DESCRIPTION Converts an integer 'int' to characters in array 'str', .which is at most 'size' characters long. 'length' is returned as the number of characters . the integer took, not including the EOS marker. Characters are stored in a Ratfor ascii array terminated with an EOS marker. SEE ALSO CtOi 47 48 NAME length - compute length of string SYNOPSIS n = length(str) [ integer function DESCRIPTION Computes the length of a character string, excluding the EOS. The string is a Ratfor ascii array terminated with an EOS marker. SEE ALSO NAME prompt - output a line onto a terminal; suppress line feed/carriage return SYNOPSIS call prompt (line) . DESCRIPTION Prompt outputs the ascii string 'line' onto the user interactive terminal. The carriage return/line-feed sequence is suppressed so the line actually appears as a prompt. 'Line' is a Ratfor string, terminated by an EOS. SEE AL30 remark, putiJi.5g, z·~vly NAME putmsg - print single-line message SYNOPSIS call putmsglstr) DESCRIPTION 'Putmsg' prints the Ratfor string •str• on the user's terminal. The me3aage i~ J)dul..I:H.l with a 11 Carriage return/line feed 11 at the end. is a Ratfor ascii array string terminated with an EOS. SEE ALSO prompt, remark, reply •str' NAME remark - print single-line message SYNOPSIS call remark (message) DESCRIPTION Remark writes the message onto the user's terminal. A NEWLINE is always generated, even though one may not appear in the message. The message array is generally a Fortran quoted string used directly in the call siatement and passed in the internal character format used by the local machine, and NOT the conventional Ratfor string ascii array. In order to perform the possible unpacking needed, messages printed using this routi~e should be terminated with a period: e.g., 'message.•. Putmsg should be used for conventional Ratfor strings. SEE ALSO prompt, putmsg, reply, ftlerr NAME reply - read a string from the user's terminal SYNOPSIS ·call reply(str) DESCRIPTION Reply reads a string from the user's interactive terminal, and returns it in the Ratfor string •str' terminated by an EOS. An end of file will be indicated by setting •str(1)' to EOF. SEE ALSO prompt, remark, putmsg 49 50 NAME scopy- copy string at from(i) to to(j) SYNOPSIS call scopy(from, i, to, j) DESCRIPTION Copies the (sub)string of 'from', starting in location 'i'·, ·into array •to', starting at 'j'. SEE ALSO stcopy, addset, concat NAME sgrtr - compare two strings SYNOPSIS ival- sgrtr(word1,word2) integer function ] DESCRIPTION Compares •word1' to 1 word2'. Returns YES if 'word1' is alphabetically greater than 1 word2i, otherwise returns NO (word1 <= word2). If •word1' is a substring of •word2' (i.e., 1 word2' is the same but longer than 'word1'), then 'word2' is considered to be greater than 'wordl'• The internal character set collating sequence is used by sgrtr. SEE ALSO equal, equal2, equalf NAME shsort - sort integer array using shell short SYNOPSIS call shsort(iv, n) [ subroutine ] DESCRIPTION Shsort sorts integer array iv(1) ••• iv(n) in increasing order using a shell sort. SEE ALSO bubble NAME skipbl -·skip blanks and tabs at str(i) SYNOPSIS call skipbl(str, i) DESCRIPTION Starting at position 'i' of array •str', increments i while str(i) is a BLANK or TAB. •str' is a Ratfor ascii array terminated with an EOS marker. ,. SEE ALSO findcs, skipcs, getwrd 51 52 NAME skipcs - skip over characters SYNOPSIS index= skipcs(str1,str2) [ integer function ] DESCRIPTION Skips over all characters in •str2' that are found in •str1'. 'Str1' and •str2' are strings terminated by EOS. Returns index of •str2' of first character not in 'str1', or 7.P.rn if all characters in •str2' are also in •str1'. SEE ALSO getwrd, skipbl, findcs NAME stcopy - copy string at from(i) to to(j); increment j SYNOPSIS call stcopy(from, i, to, j) DESCRIPTION Copies the (sub)string of 'frOm', starting in location 'i', into array 'Lu', ~LarLlng at 'j'. 'j' i~ incremented to point to the next available pooition in 'to' (1.~. ~he EOS mar~er lnsetted by the copy). 1n all other respects, •stcopy' is similar to •scopy'. SEE ALSO scopy, concat NAME type - determine type of character SYNOPSIS t = type(c) [ ascii function ] DESCRIPTION This function determines whether the character 'c' is a letter, a digit, or something else; it returns LETTER, DIGIT, or the character itself. SEE ALSO alldig, findcs NAME upper - convert string to upper case SYNOPSIS call upper ( str) DESCRIPTION Converts the array •str' ·to upper case, if not already there. If any characters are non-alphabetic, it leaves them unchanged. If the internal character set has only one case, returns with no change. 'Str' is a Ratfor ascii array terminated wit~ an EOS marker. SEE ALSO cupper, fold, clower 53 54 APPENDIX D - RATFOR FORMATTING PROGRAM The "Program Indentation and Layout" section of the Ratfor User's Guide describes a set of rules that may be used for Ratfor programs. It can be difficult to follow those rules exactly, especially after a program has undergone extensive modification. It is also difficult for several programmers on a project to follow the rules consistently.. In order to alleviate this problem, a formatting program that will reformat any Ratfor program to follow the indentation rules is available. The formatting program strictly enforces the indentation rules stated in the User Guide. In addition to reformatting Ratfor programs to follow the indentatluu rules, the formatter has the following features: • Statements initially start indented four spaces. • Label$ always hAgin in oolumn nne. • The following policy is used for comments: - Blank lines are retained. -Lines containing only a comment are passed through untouched, i.e., no indentation is enforced. The formatter attempts to handle comment~ that appear on the same line following a Ratfor statement reasonably. The formatter will first attempt to line up all comments of this type in column 32. If the Ratfor statement extends beyond column 32, then the oomment i3 separated from the statement either by one blank or one tab stop, depending on the total length of the line. Any trailing comments beginning with a double sharp (##) will cause that co~ment to be separated from the etritement by only one blank instead of being forced to column 32. This is useful for commenting ends of loops following closing right braces ("}"), e.g., " } ##end for loop". - Any comment with a "#:#" in the first three columns is removed entirely from the generated output. This feature is mainly to allow the formatter to generate comments which will be automatically removed the next time the program is fnrmatt@d. - The "#D" of _debug lines are placed in the first two columns, and the rest of the debug statement lined up at the current indent level with out any additional keyword analysis. This means that a s~ries of 'if' 'else' debug statements will not generate the usual indentation. • Subroutine and Function definition lines (e.g., subroutine subr, integer function func(arg) ) are indented only two spaces to allow them to stand out. In addition, a three line separator comment field is automatically generated before each subprogram, with an 80 column line of ='s in the middle and the routine name centered on that line. The special "#:#" comment is used, thus allowing the formatter to regenerate the separator field each time. * The formatter does not perform automatic continuation for long lines. The user must split long lines. The formatter recognizes continuation lines, however. The first line of a multi-line statement is indented in the normal fashion. Continuation lines are in~ented two spaces to the right of the first line, thus setting them off without indenting the usual four spaces. *The formatter is keyword driven, i.e., it looks for indentation keywords like "if" or "while". Spacing within statements, such as the condition part of an "if" or all of non-critical statements such as a "call", is not altered in any way by the formatter. The formatter will always leave one blank between "if", "while", "for", and "until" and the following left paren. * Lines between literal brackets ("%") are passed through untouched. * Lines with an "else if ( •• )" are handled correctly. However, lines with both the "if" and its matching "else" on the same line are not recognize~, and will cause diagnostics. begin on separate It is up to the programmer to ensure that "else" statements lines. The formatter does detect braces ("{", "}") on the same line as other statements, and forces them to separate lines according to the rules. * Lines with multiple statements per line separated by";" are left on the same line if they contain no keywords. Null statements are handled correctly. * "define" and "include" statements are lined up to the current indentation level, but otherwise are untouched, thus avoiding possible conflicts with critical spacing and special characters. No define substitution processing is performed. * No c·ase conversion is performed. • The formatter pe~forms a fair amount of analysis, and will detect errors in block structure (mismatched braces, etc.). It does not, however, detect all Ratfor errors, and getting through the formatter with no errors does not mean . ' there will be no Ratfor or Fortran errors. Diagnostics printed by the formatter are generally the same as those generated by the Ratfor preprocessor. • 55 56 APPENDIX E - USING RATFOR ON THE VAX On the VAX implementation, Ratfor uses the 'getdcl' library function to get file names and switches. The system wide symbol, "SYS$RAT4" has been defined to refer to all files used or provided by Ratfor and can be used like a device specification (e.g., SYS$RAT4:symbols.ir4). The system wide definition "RATFOR:::$SYS$RAT4:RATFOR" allows Ratfor to be invoked by: $ RATFOR filename/switches where 'filename' is the Ratfor source code (a '.RAT' extension is assumed unless otherwise specified), and several switches are allowed: IN, equivalent to "$N+", include source line numbers; /H, equivalent to "$H+", convert to hollerith strings; /D, equivalent to "$D+", include lines beginning with #D; IC, equivalent to "$C+", include comments in generated code; and /V, which causes the name of each routine to be typed on the terminal as it is proge~~ed, and mBy also be invnked with a "$V·•" in a comment. The default values for the $N, $H, $D, $C, and $V switches are "-" or off. The translated output of Ratfor will ALWAYS have an extension of ".FR4". The Fortran compiler i~ no~ ~utomatic~lly invoked by using 1 RATFOR file'. A system wide symbol '("RAT4:==@~~S$RAT4:RAT4.COM") has also been defined to allow automatic invocation of the Fortran compiler. "RATFOR" as above, Y~1ng: $ RAT4 filename/switches Instead of using the causes Fortran to be invoked if there were no Ratfor errors. In addition to above switches, the switch /F=</forswitches> will pass all characters between the '<' and the '>' to Fortran. These switches must be in the form required by Fortran, including all "l"'s. To completely compile a Ratfor program, including source line numbers and comments in the •.FR4 1 output, and causini B Fnrtr~n listing file and checking, the following command could he used: $ RAT4 PROG/N/C/F:</CHECK:ALL/LIST> . When the statement "include SYS$RAT4:SYMBOLS.IR4" appears in the source program, all of the symbols described in Appendix A will be defined for the user program. (Note: It is suggested that all Ratfor include files on the VAX use a .IH4 extension to distinguish them from regular Fortran include files.) The library of Ratfor routines described in AppenrliY C is available as SYS$RAT4:RAT4LIB.OLB, and can be linked to user programs by: $LINK yourfile, ••• ,SYS$RAT4:RAT4LIB/LIB A system wide symbol ("FMTR4:::$SYS$RAT4:FMTR4") has been defined so that the Ratfor formatter is invoked by: $ FMTR4 filename[/L][/V] whero a •.nAT' eAL~o~lon is assumed unless otherwise specified. A new generation of the file is produced as the output. If the optional "/L" switch is specified, a listing file with a ".LR4" extension is produced with line numbers and loop nesting levels. The optional "IV" switch causes the name of each routine to be type on the terminal as it is processed. In addition to the formatter, a cross reference generator is available. A system wide symbol ("CROSSR4:::$SYS$RAT4:CROSS") has been defined so that the Ratfor cross reference generator may be invoked by: $ CROSSR4 filename[/R:reservedfile] where a '.RAT' input extension is assumed, and a file with a '.CRS' extension is produced as output. The output will be a list of all non-reserved symbols in the file. A standard file of reserved words is used by cross, and may be replaced by another file by using the '/R=' switch. The reserved word file name should contain a list of reserved words to be ignored by cross, one word per line. ·Alphabetical order is not important. A brief help message may be obtained by entering the VAX command "HELP RATFOR". 57 58 APPENDIX F - PORTING RATFOR F.1 INTRODUCTION This appendix describes how to port the version of Ratfor developed by Division 1723 at Sandia National Laboratories. Basically', bringing up Ratfor (referred to as Ratfor in Ratfor) involves performing a full bootstrap based on a very portable version of Ratfor written in Fortran-66 (called the bootstrap version). The ·full version is not completely portable to allow for custom tailoring for.the local operating environment. After necessary modifications have been made to the source code, Ratfor can be translated by the bootstrap \lt::l'l:l1un written in r·ortran. The entire full bootstrap process involves the following steps: 'I. Rri ng l)p th<i Fortran Bootott'Ai"' v~~·~1uu. 2. Modify tha Ratfor written in Ratfor for local conventions. 3. Use the Fortran bootstrap to bring up Ratfor in Ratfor. 4. Run the Ratfor in Ratfor through itself to obtain final version of the Ratfor preprocessor. (Ratfor in Ratfor produces slightly better code than the Fortran bootstrap version, eliminating some unnecessary GOTOs.) 5. Modify the manual to reflect local usage conventions. 6. Modify the Ratfor standard lihr~ry. This appendix is not a stand alone document. It is intended t6 be used in conjunction· with the Sandia version of Ratfor in Ratfor listing, as well as the Ratfor User's manual. F.2 BRINGING UP THE BOOTSTRAP VERSION The Ratfor bobt3tvap 1~ wr·1tLen in ro~tran-bb, and should require little or no modifioation. It u:J~~ t.w.-. F•.•I'Lr·;w I/O unite: ~ and b. Unil 5 1::~ used tor input (the Ratfor source program) and unit 6 is used for output (the generated Fortran code). (Note: error diagnostics will be printed inline with the generated Fortran code, and may be difficult to find. This is only a problem in the bootstrap version, however.) These units must somehow be aooigned to the proper files whenever running the bootstrap. Even though the bootstrap has some hooks for doing fi~e inclusion, the Ratfor in Ratfor version does not require file inclusion. The bootstrap uses mapping routines to achieve character set independence, and holds characters one per integer. It might be necessary to change the read and write fo·rmats in the routines getch and putch so that characters are read in and properly stored as small integer values. Once the bootstrap version has been used to get at least a preliminary working version of Ratfor in Ratfor, it will not be needed again, and can be saved off line if necessary. F.3 BRINGING UP RATFOR IN RATFOR F.3.1 Basics The version of Ratfor in Ratfor was designed to be both portabl~ (using the bootstrap), as well as containing the necessary features to make it adaptable to convenient use on any system. As such, and unlike the bootstrap version, it will require a number of customizations before it will run. The modifications to the Ratfor in Ratfor version generally deal with I/0 and conventions: filename 1. Improving 'the I/0. This involves optimizing possible character mapping, as well as:optimizing· the read and write statements for the local system. It was found on the VAX for example, that the exact format used to read in one lirie could account for over 20% difference in total execution time~ 2. Proper handling of file names and file assignment. This involves identifying the source and output file names, as will as included file names. The main effort here will be involve implementing the ability to dynamically open and close files. Since internally Ratfor uses ASCII, character mapping back to the local character set may be necessary. File names should be ma~e to conform to local system standards. 3·· Changing various constants to fit with local requir~ments. Various items, such as table size, switch defaults, character representation, etc. should be customized to produce optimal local pertormanu~. Each of these various customizations will be discussed more fully below. In the Ratfor·source code, code segments that may need attention are marked with comments lines beginning with "#$$$". It is typically easiest to use ·an editor to search for these lines to check for possible changes. One basic item that must be decided upon for each implementation of Ratfor is the representation of characters, and the character set used. Generally, one wants to minimize storage requirements for holding characters. Characters should be represented as small integers, and must be able to be accessed using normal Fortran array subscripts. Thus, any representation leading to packing of charauL~i'S in a word is not accept~hle unless the characters can be accessed individually using normal Fortran subscripts. and provide Fortran data types for accessing Many machines are byte oriented, bytes (typically called BYTE, 59 60 LOGICAL*1, or INTEGER*1). This is the ideal character representation. However, if no byte access is allowed, then characters should be represented as INTEGER. While this may seem wasteful of storage space, it leads to portable character manipulation, and is a necessary sacrifice. Ratfor application programs will probably want to work with the local character set representation. These character sets include ASCII, EBCDIC, FIELD DATA, DISPLAY CODE, and others. Ratfor itself is implemented using ASCII as its internal character set. In order to allow this, all characters are mapped from the local character set into ASCII when read, and remapped on output using the routines inmap and outmap. This mapping would be 1:1 on ASCII 'machines. Otherwise, a mapping function must be defined, and could typically be a table lookup. Mapping is described in more detail later. Once Lhe character set representation has been ch6sen (storage representation and character set), then the default representation for EOS autom~tically pruvlded bV Hatfor in Ratfor ohould b~ chosen. While zero is a typical value, EOS should not correspond to a normal character, and.ihould be chosen to be a unique value. Thus, zero is not acceptable for'EOS for DISPLAY CODE, for exa~ple, sinde zero is a valid character (-1 would work for this case). A number of other customizations should be made for each implementation of Ratfor. It is important to remember that one of the main goals of this version of Ratfor is to make the human interface easy to use. Most of the hooks needed for this are already present, but it 1~ likvly that oome ad~lLlunal pr6gramming will be required. F.3.2 Modifying Ratfor !'or th~ local RyRt.em The following sections discuss various features of Ratfor that may need modification for implementations on new operating systems. These discussions correspond to line~ in the Ratfor source code marked with "1$$$", and are pres~nted in the order they appear the source code. Each system dependent feature is described iq term~ of th~ routine th~t lL appeafs in. Sections describing each routine are marked with a '>>>' at the beginning. >>> System DePendent Symbol Dcfinit1on~ A number of system dependent symbols appear in define statements at the beginning of the source code. These symbols typically_~efine table sizes and default values. BUFFSIZE - this is the size of the pushback buffer used by the parser and lexical analyzer. The value of 300 should be left if possible, but if space is really tight, it probably can be reduced to 100. ascii, ASCII These definitions correspond the the translation used for the local representation of ascii variables such as BYTE, LOGICAL*1, or INTEGER. Since the Fortran bootstrap does not automatically define ascii, these defines must be present for Ratfor itself. They should correspond to the value for ascii defined in initrt, which will be the value automatically defined for Ratfor programs translated by Ratfor in Ratfor. CODEOUT,ERROUT,INPUTUNIT- Ratfor requires a number of ~ortran logical units: one for generated code output (CODEOUT), one for error message output (ERROUT, to the user's terminal), and several for Ratfor code input (starting with INPUTUNIT, and numbered up sequentially). Possibly, depending on how the command line is input specifying initial file name, a unit will be required for user terminal input. The initial source code will be read on INPUTUNIT. When an include is encountered, the current input unit is incremented, and the new unit used to read the include file. Each time a nested include is found, the unit will be incremented again. When an EOF is found, the current input unit is closed and the input unit variable nxtfil is decremented. The maximum number of files that may be open at any one time is specified by MAXFILE, and.will be operating system ~pendent. NFILES specifies how many levels of include nesting are allowed, and will be related to MAXFILE (NFILES = MAXFILE-4). COMDEFAULT, etc. - Several symbols are called xxxDEFAULT. They specify the default values for the various switches available. They may be changed if desired for convenient use on the local system. Specifying switches on the startup command line, or using inline $S+ type switches can be used to override the defaults. EOF - End of file~ This value is returned when an end of file is encountered. The system must be able to detect end of files. EOF should not be the same as EOS, NEWLINE, etc. EOS - End of String. This definition is to define the ASCII EOS character used internally within Ratfor. It may or may not correspond to the system default EOS provid~d by Ratfor and initialized in initrt. FILENAMESIZE - Defines the array size used to hold file names from the startup command line and from include statements. index - This redefines index so that it will not conflict with possible. usage of a Fortran library function of the same name. MAXCARD, MAXLINE - Used to define the size of the main ascii input array corresponds to the the maximum line length Ratfor may be expected to deal with on the local system. MAXDEF - Pefines the maximum characters that may be in the definition part of a define statement. May be too large or too small depending on the kink of usage define gets. 61 62 MAXHASH, MAXTBL - Define the maximum number of different symbols that may appear in define statements (MAXHASH), and the maximum number of characters available for those symbols plus their definitions plus 2 EOS's (MAXTBL). NEWLINE - Defines the character used to mark the end of input lines. As long as the internal character set used by Ratfor remains ASCII, this value is ok. other symbols - The rest of the symbols should be system independent. If for some reason it is desirable to redefine the characters used internally by Ratfor (to bypass inmap, for example), then caution must be used when using the rest of the symbols. >>> CLOSEF - close file routine This routine is used to close a fortran logical unit. The argument is the unit number to olooc. The mo5t impu1·LaoL u~e of clos~r 1$ to close fil~R trom include statements so that the logical unit numbers can be reused. Typically a call to a system dependent close routine will be necessary. >>> DOFILE Defile is the main routine used to get a "command line" from the user which will specify the Ratfor source code input file, and possible switches. Defile is one of the more system dependent routines, and accounts for most of the human interface of Ratfor. Assuming that the operating system allows files to he specified using character strings, the basic structure of defile should be usable. Some of the "type *,'message'" statements may need to be modified. defile ~alls getcmd and cipenf, which ar~ also system dependent routines. The Output unit an~ user terminal output tire also opened in defile, usiDR svstem dependent features. As it is currently implemented, the user need only specify the Ratfor input file, and defile automatically generates the proper name for the Fortran output file. It is important to make sure that dofile works well since most of the user command interface takes place here. It is possible that defile will have to be completely rewritten, with the current code serving as a guide. >>> GETCMD Getcmd is used to obtain a command line from the user when Ratfor is first invoked. If possible, the command line should be obtained from the original operating system command line when the user initially invoked Ratfor. If this is not possible, then getcmd could type a prompt, and read a command line from the uset. This is the only point input is required from the user terminal. Getcmd should return the command line folded to upper case, and some mapping to ASCII may be required. >>> GETCH Getch is the main input routine for Ratfor. The read statement and its associated format (1) should be optimized to get the best results when reading in a card image into the ascii array "incard". It might be worthwhile writing a few test programs to find out the best format to use. It may be best to replace the read statement with a call to a special "syste~ routine". Optimizing this statement on the VAX implementation resulted in a 20% improvement in the overall speed of the preprocessor. The read statement must also be able to detect end of files without causing the preprocessor to crash, which may be a system dependent ·function. End of file is typically detected with the 'END=' option. Once the card image is input into "incard", it may or may not have to be mapped into the ASCII character set used internally by Ratfor. (See inmap). >>> GETTOK Gettok handles file inclusion, and is therefore possibly system dependent. File names after the include will have been processed by DEFTOK, and th~refore may have heen alt~red. For example, in the VAX version, the square brackets used to specify file names will have been changed to curly braces. gettok must handle this. There is also a possibly system dependent output statement that writes the name of the included file to the generated output. gettok also detects subroutine and function names, and writes them to the user's terminal. All of the file names and routine names seen by gettok have been mapped to ASCII, and ·~ay have to be outmapped before printing on the user's terminal. Nothing will be harmed if these writes are removed except that the $V option is lost. >>> INITRT Initrt initializes various keywords used by Ratfor. Keywords are installed in the hash table for later use by LEX. If the local version of Fortran does not allow variable3 in common to be ini.tj~lized in subroutines, then the data declarations in initrt will have to be moved to a BLOCK DATA subprogram. The local system conventions for ascii variables and EOS are also defined in the data statements found in initrt. They should be modified to conform to the convention chosen for the implementation. The definition of vascii holds the local representation of ascii, up to 11 characters plus the EOS. This is enough to define ascii to be 'logical*1', for example. If you need more than 11 characters, then the size of vascii will need to be changed in the common /ckeywd/ throughout the preprocessor. Use the LETx defined constants to specify the local representation, following the example 'byte' given. The local representation of EOS must also be defined in veos. Veos has room for 5 characters plus the EOS. Veos should be initialized to the character string representing the numerical value EOS will take, and not to an actual numerical value. 63 64 >>> INMAP Inmap is used to map the external, local character representation as read by getch into the internally used ASCII character set. If the local character set is already ASCII, then inmap is 1:1, otherwise a local mapping function will have to be written. It is important to make this mapping as efficient as possible. The original versions of inmap and outmap (and the ones used by the bootstrap) are very portable., but take up to 80% of the total prqcessing time. The most efficient form of inmap and outmap would be a table lookup, where the small integer value of the local character representation is used as an index to an array to give the ASCII equivalent. All character sets do not contain the same set of symbols, so the mapping may not be 1:1 with ASCII. Be s11r~ to map local ~ymbols to the most appropriate ASCII equivalent. If only one alphabetic casP- (AmZ) i~ ~v~ilable, ruav Lu lower case ASCII. >>> OPENF Openf is used by defile and include processing in gettok to open Ratfor source files. It is passed a character string name in the usual Ratfor convention, terminated with an EOS. The name will have been mapped to the internal ASCII character set. Openf should open the file specified by the name. 'Nxtfil' is also manipulated by openf for proper functioning of nested includes. >>> OUTMAP Outmap is the complimentary operation of inmap. mapped to the local representation. See inm~p. >>> PUTCH ASCII characters are Putch is used to write out characters to the generated output file or the the user's terminal, depending on the unit number. Just as in getch, it is important to tune the write statement to obtain the fastest output availabl.e for the local system. >>> REMARK Internally, mo&L oharoeter st,•lugs are represented as small integers in asc11 arrays. However, a few error messages are represented as quoted character strings in call statements to remark. These quoted strings will be mapped to hollerith format by the bootstrap, and by Ratfor in Ratfor itself if the $H+ has been set. Since they are qunted oharactcr ~tring~, they Will be passed to remark in whatever internal format is used by the local Fortran compiler. Remark must handle this system dependent character representation and write the message to the terminal or file. Each message that calls remark will always have a period as the last character, which can be used to indicate the end of the string if necessary. Some machines will pack the strings several characters ~ to a word. Special techniques such as the use of ENCODE or DECODE statements available on many machines may be necessary to print out the message correctly. Remember that this version of Ratfor is intended to be a production version, so don't settle ~r garbage being printed out after the period if the packing doesn't come out even! Use the remark supplied as a model. >>> STRCOD There is nothing inherently machine dependent about strcod. It might be useful to note, however, that strcod calls outmap when determining the integer ·value to generate for the data statement, resulting in an output value that will be in the local character set representation. If ASCII is desired for some reason, then the call to outmap should be removed, and the integer values for ASCII will be generated instead. F.4 THE USER'S MANUAL The Ratfor User's Manual will aqqompany the Ratfor preprocessor on the distribution tape. It should be modified as necessary to reflect local usage conventions. Appendices B, D, and E are the most likely to need modification. F.5 THE RATFOR LIBRARY A fairly large library of useful routines written in Ratfor also accompanies the Ratfor preprocessor. These routines will for.the most part be system ind~pendent as long as the Ratfor conventions for string representation· are followed. ~everal of the routines are somewhat system dependent. These routines, such as gtime, ftlerr, or remark will have to be modified to meet the local conventions. Others, such as getdcl may not be directly implementable on the local syotcm, in whioh oase they Rhnuld be implemented to perform ~orne reasonable alternative action. Routines that are the most system dependent appear at the end of the listing. F.6 FINAL COMMENTS This version of Ratfor written in Ratfor is not completely portable, and wlll ~equire 3ome effort to get it working properly. However, the effort will be worth it. The resulting product will allow the user to process Ratfor files with a minimum of fuss, giving a number of ·options under the control of the switches, and produce inf6~mative error diagnostics on the user terminal • . "". 65 66 This implementation guide is intended to make the process of porting Ratfor easier. A number of steps .have been taken with this version of the Ratfor preprocessor to enhance its portability. It has been tested to be translatable by the Fortran bootstrap version. The bootstrap symbol table is just large enough to accomodate the defines used in Ratfor, and the include feature is not used. However, it is likely that non-portable features of Ratfor not mentioned here will be discovered. Just because a problem is not mentioned here does not mean that it does not exist. If a problem crops up even after .following the suggestions here, then the Ratfor source code will have to be carefully examined. However, the code is well structured and commented, and after all, it is written in Ratfor. DISTRIBUTION: .,. 1253 T. D. Sullivan 1523 R. E. Trellue 1524 F. D. Gutierrez 1700 w. c. Myre 1710 v. E. B1a ke, Jr. 1720 c. H. Mauney 17 21 J. w. Kane 1723 J. J. Baremore ( 25) 1723 A. Chipman 1723 R. F. Davis 1723 M. D. F1mple 1723 c. J. Fisk 1723 R. c. Mueller 1723 T. F. Runge 1723 K. J. Sen a 1723 N. A. Smith 1723 B. E. Wampler (20) 1723 s. J. Weissman 1725 J. H. Davis 1727 v. K. Smith 1729 J. D. Williams 1730 J. D. Kennedy 1738 R. K. Petersen 1750 J. E. Stiegler 17 58 c. E. Olson 1760 J. Jacobs 17 61 T. A. Sellers 1762 H. E. Hansen 1764 J. E. Hinde 1765 D. s. Miyoshi 2113 T. B. Linnerooth 2162 J. R. Park 2424 G. Carl1 2611 R. K. Vokes 2644 D. M. Darsey 3141 T. L. Werner (5). 31 51 w. L. Garner ( 3) for DOE/TIC (Unlimited Release) 4247 G. R. Montry 5530 w. Herrmann 5531 D. B. Saylors 8266 E. A. Aas DOE/TIC (25) ( R. p. Campbell, 3154-3) Tom Bennion MS: 970 . LASL ., . John Browning AFWL/NTYV KAFB Albuquerque, N. M. 87117 .} 67 68 Carlos Fernandez AFWL/ADD KAFB Albuquerque, N.M. 87117 Tom Mortenst:?n JAYCOR 8001 Mountain Rd., Pl. Albuquerque, N.M. 87110 Randall G. Rushe AFWL/ ARI n KAFB 4lbuquQrque, N.M. 87117 Dale Sparks MS: C9 L/\SL Tom Stup MS: 828 LASL ·- Org. Btdg. Name Rec'd by • Or g. Bldg. Name Rec'd by • - • R ec ip ie n t ~ initi a ~ Dn classified docUiflalll!!l.