A Portable Fortran 77 Compiler
The Fortran language has just been revised.
The new language, known as Fortran 77,
became an official American National Standard on April 3, 1978.
We report here on a compiler and run-time system for the new extended language.
This is believed to be the first complete Fortran 77 system to be implemented.
This compiler is designed to be portable,
to be correct and complete,
and to generate code compatible with calling sequences produced by C compilers.
In particular, this Fortran is quite usable on
In this paper, we describe the language compiled,
interfaces between procedures,
and file formats assumed by the I/O system.
An appendix describes the Fortran 77 language.
The Fortran language has just been revised.
The new language, known as Fortran 77, became an official American National Standard [1] on April 3, 1978.
for the language, known as Fortran 77, is about to be published.
Fortran 77 supplants 1966 Standard Fortran [2].
We report here on a compiler and run-time system for the new extended language.
The compiler and computation library were written by SIF, the I/O system by PJW.
We believe ours to be the first complete Fortran 77 system to be implemented.
This compiler is designed to be portable to a number of different machines,
to be correct and complete,
and to generate code compatible with calling sequences produced
by compilers for the C language [3].
Two families of C compilers are in use at Bell Laboratories,
those based on D. M. Ritchie's PDP-11 compiler[4]
and those based on S. C. Johnson's portable C compiler [5].
This Fortran compiler can drive the second passes of either family.
In this paper, we describe the language compiled,
interfaces between procedures,
and file formats assumed by the I/O system.
We will describe implementation details in companion papers.
At present, versions of the compiler run on and compile for the PDP-11,
The command to run the compiler is
f\|77 \fIflags file . . .\fR
is a general-purpose command for compiling and loading Fortran and Fortran-related files.
EFL [6] and Ratfor [7] source files will be preprocessed before being presented to the Fortran compiler.
C and assembler source files will be compiled by the appropriate programs.
Object files will be loaded.
commands cause slightly different loading sequences to be generated,
since Fortran programs need a few extra libraries and a different startup routine
The following file name suffixes are understood:
The following flags are understood:
Generate assembler output for each source file, but do not assemble it.
Assembler output for a source file
Apply the M4 macro preprocessor to each EFL or Ratfor source file before using the appropriate compiler.
Apply the EFL or Ratfor processor to all
relevant files, and leave the output from
Do not compile the resulting Fortran program.
Generate code to produce usage profiles.
Put executable module on file
Suppress all warning messages.
Suppress warnings about Fortran 66 features used.
Invoke the C object code optimizer.
Compile code the checks that subscripts are within array bounds.
Compile code that performs every
Do not convert upper case letters to lower case.
The default is to convert Fortran programs to lower case.
Make the default type of a variable
On machines which support short integers,
make the default integer constants and variables short.
(\fB\(miI4\fR is the standard value of this option). (see Section 2.14).
All logical quantities will be short.
The remaining characters in the argument are used as an EFL flag argument.
The remaining characters in the argument are used as a Ratfor flag argument.
Ratfor and and EFL source programs are pre-processed into Fortran files,
but those files are not compiled or removed.
all library names (arguments beginning \fB\(mil\fR),
and any names not ending with one of the understood suffixes are passed to the loader.
Documentation Conventions
In running text, we write Fortran keywords and other literal strings in boldface lower case.
Examples will be presented in lightface lower case.
Names representing a class of values will be printed in italics.
The compiler and library are written entirely in C.
The compiler generates C compiler intermediate code.
Since there are C compilers running on a variety of machines,
relatively small changes will make this Fortran compiler generate code for any of them.
Furthermore, this approach guarantees that the resulting programs are compatible with C usage.
The runtime computational library is complete.
The mathematical functions are computed to at least 63 bit precision.
The runtime I/O library makes use of D. M. Ritchie's Standard C I/O package [8]
With the few exceptions described below, only documented calls are used,
so it should be relatively easy to modify to run on other operating
Fortran 77 includes almost all of Fortran 66 as a subset.
We describe the differences briefly in the Appendix.
The most important additions are a character string data type,
file-oriented input/output statements, and random access I/O.
Also, the language has been cleaned up considerably.
In addition to implementing the language specified in the new Standard,
our compiler implements a few extensions described in this section.
Most are useful additions to the language.
The remainder are extensions
to make it easier to communicate with C procedures
or to permit compilation of
old (1966 Standard) programs.
Each datum is represented by a pair of double precision real variables.
A double complex version of every
built-in function is provided.
The specific function names begin with \fBz\fR instead of \fBc\fR.
The Fortran 77 standard introduces ``internal files'' (memory arrays), but
restricts their use to formatted sequential I/O statements.
Our I/O system also permits internal files to be used
in direct and unformatted reads and writes.
Implicit Undefined statement
Fortran 66 has a fixed rule that the type of a variable that does not appear in a type statement
\fBi, j, k, l, m\fR or \fBn\fR,
statement for overriding this rule.
As an aid to good programming practice, we permit an additional type,
turns off the automatic data typing mechanism,
and the compiler will issue a diagnostic for each variable that is used but does
not appear in a type statement.
compiler flag is equivalent to beginning each procedure with this statement.
Procedures may call themselves, directly or through a chain of other procedures.
Two new keywords are recognized,
These keywords may appear as ``types'' in type statements and in
Local variables are static by default;
there is exactly one copy of the datum, and its value is retained between calls.
There is one copy of each variable declared
for each invocation of the procedure.
Automatic variables may not appear in
The Standard expects input to the compiler to be in 72 column format:
the first five characters are the statement number, the next is the continuation character,
and the next sixty-six are the body of the line.
(If there are fewer than seventy-two characters on a line, the compiler pads it with blanks;
characters after the seventy-second are ignored).
In order to make it easier to type Fortran programs,
our compiler also accepts input in variable length lines.
An ampersand (``&'') in the first position of a line indicates a continuation
line; the remaining characters form the body of the line.
A tab character in one of the first six positions of a line signals the
end of the statement number and continuation part of the line;
the remaining characters form the body of the line.
A tab elsewhere on the line is treated as another kind of blank by the
In the Standard, there are only 26 letters \(em Fortran is a one-case language.
system usage, our compiler expects lower case input.
By default, the compiler converts all upper case characters to lower case except those inside character constants.
compiler flag is specified, upper case letters are not transformed.
In this mode, it is possible to specify external names with upper case letters in them,
and to have distinct variables differing only in case.
Regardless of the setting of the flag,
keywords will only be recognized in lower case.
is replaced by the contents of the file
\fBinclude\fRs may be nested to a reasonable depth, currently ten.
Binary Initialization Constants
variable may be initialized in a
by a binary constant, denoted by a letter followed by a quoted string.
If the letter is \fBb\fR, the string is binary, and only zeroes and ones are permitted.
If the letter is \fBo\fR, the string is octal, with digits \fB0\(mi7\fR.
If the letter is \fBz\fR or \fBx\fR, the string is hexadecimal, with digits \fB0\(mi9\fR, \fBa\(mif\fR.
data a / b\(fm1010\(fm, o\(fm12\(fm, z\(fma\(fm /
initialize all three elements of
For compatibility with C usage, the following backslash escapes are recognized:
\e\(fm apostrophe (does not terminate a string)
\e" quotation mark (does not terminate a string)
\e\fIx\fR \fIx\fR, where \fIx\fR is any other character
Fortran 77 only has one quoting character, the apostrophe.
Our compiler and I/O system recognize
both the apostrophe ( \(fm ) and the double-quote ( " ).
If a string begins with one variety of quote mark, the other may be embedded within it
without using the repeated quote or backslash escapes.
Every unequivalenced scalar local character variable and every character string constant is aligned
Each character string constant appearing outside a
statement is followed by a
null character to ease communication with C routines.
Fortran 77 does not have the old Hollerith (\fIn\|\fBh\fR)
though the new Standard recommends implementing the old Hollerith feature
in order to improve compatibility with old programs.
In our compiler, Hollerith data may be used in place of character string constants,
and may also be used to initialize non-character variables in
As a very special and peculiar case,
Fortran 66 permits an element of a multiply-dimensioned array to be represented by
a singly-subscripted reference in
Fortran 77 does not permit this usage, since
subscript lower bounds may now be different from 1.
Our compiler permits single subscripts in
under the interpretation that all missing subscripts are equal to 1.
A warning message is printed for each such incomplete subscript.
The Fortran 77 Standard requires that the range of a
if the initial value is already past the limit value,
The 1966 Standard stated that the effect of such a statement was undefined,
but it was common practice that the range of a
In order to accommodate old programs, though they were in violation of the 1966 Standard,
compiler flag causes non-standard loops to be generated.
Commas in Formatted Input
The I/O system attempts to be more lenient than the
Standard when it seems worthwhile.
When doing a formatted read of non-character variables,
commas may be used as value separators in the input record,
overriding the field lengths given in the format statement.
On machines that support halfword integers,
the compiler accepts declarations of type
(Ordinary integers follow the Fortran rules about occupying the same
space as a REAL variable; they are assumed to be of C type
halfword integers are of C type
An expression involving only objects of type
Generic functions return short or long integers depending on the actual types of their arguments.
If a procedure is compiled using the
flag, all small integer constants will be
If the precision of an integer-valued intrinsic function is not determined by the generic function rules,
one will be chosen that returns the prevailing length
(\fBinteger\(**2\fR when the \fB\(miI2\fR command flag is in effect).
option is in effect, all quantities of type
Note that these short integer and logical quantities do not obey the standard rules for storage association.
Additional Intrinsic Functions
This compiler supports all of the intrinsic functions specified in the Fortran 77 Standard.
In addition, there are functions for performing bitwise Boolean operations
VIOLATIONS OF THE STANDARD
We know only thre ways in which our Fortran system violates the new standard:
Double Precision Alignment
The Fortran standards (both 1966 and 1977)
statements to force a double precision quantity onto an odd word boundary,
as in the following example:
equivalence (a(1),b), (a(4),c)
Some machines (e.g., Honeywell 6000, IBM 360) require that double precision quantities be on double word boundaries;
other machines (e.g., IBM 370), run inefficiently if this alignment rule is not observed.
It is possible to tell which equivalenced and common variables suffer from a forced odd
alignment, but every double precision argument would have to be assumed on a bad boundary.
To load such a quantity on some machines,
it would be necessary to use separate operations to move the upper and lower halves
into the halves of an aligned temporary, then to load that double precision temporary; the reverse would be
needed to store a result.
We have chosen to require that all double precision real and complex quantities
fall on even word boundaries on machines with corresponding hardware requirements,
and to issue a diagnostic if the source code demands a violation of the rule.
Dummy Procedure Arguments
If any argument of a procedure is of type character,
all dummy procedure arguments of that procedure must be declared
This requirement arises as a subtle corollary of the way we represent character string arguments
and of the one-pass nature of the compiler.
A warning is printed if a dummy procedure is not declared
Code is correct if there are no
The implementation of the
These codes allow rereading or rewriting part of the
record which has already been processed.
(Section 6.3.2 in the Appendix.)
The implementation uses seeks,
so if the unit is not one which allows seeks,
(People who can make a case for using
A benefit of the implementation chosen is
that there is no upper limit on the length of
nor is it necessary to predeclare any record
lengths except where specifically required
by Fortran or the operating system.
INTER-PROCEDURE INTERFACE
To be able to write C procedures that call or are called by Fortran procedures,
it is necessary to know the conventions for procedure names,
and argument lists that the compiled code obeys.
the name of a common block or a Fortran procedure
has an underscore appended to it by the compiler
to distinguish it from a C procedure or external variable
with the same user-assigned name.
Fortran library procedure names have embedded underscores to avoid clashes
with user-assigned subroutine names.
The following is a table of corresponding Fortran and C declarations:
integer\(**2 x short int x;
double precision x double x;
complex x struct { float r, i; } x;
double complex x struct { double dr, di; } x;
character\(**6 x char x[6];
(By the rules of Fortran,
data occupy the same amount of memory).
declared as a C function that returns the corresponding type.
function is equivalent to a C routine
initial argument that points to the place where the return value is to be stored.
complex function f( . . . )
struct { float r, i; } \(**temp;
A character-valued function is equivalent to a C routine with
two extra initial arguments:
a data address and a length.
character\(**15 function g( . . . )
g_(result, length, . . .)
and could be invoked in C by
Subroutines are invoked as if they were \fBinteger\fR-valued functions
whose value specifies which alternate return to use.
Alternate return arguments (statement labels) are not passed to the function,
but are used to do an indexed branch in the calling procedure.
(If the subroutine has no entry points with alternate return arguments,
the returned value is undefined.)
call nret(\(**1, \(**2, \(**3)
is treated exactly as if it were the computed
All Fortran arguments are passed by address.
for every argument that is of type character or
that is a dummy procedure,
an argument giving the length of the value is passed.
quantities passed by value).
The order of arguments is then:
Extra arguments for complex and character functions
Address for each datum or function
A \fBlong int\fR for each character or procedure argument
sam_(f, &b[1], s, 0L, 7L);
Note that the first element of a C array always has subscript zero,
but Fortran arrays begin at 1 by default.
Fortran arrays are stored in column-major order, C arrays are stored in row-major order.
Structure of Fortran Files
Fortran requires four kinds of external files:
sequential formatted and unformatted,
and direct formatted and unformatted.
these are all implemented as ordinary files
which are assumed to have the proper
Fortran I/O is based on ``records''.
When a direct file is opened in a Fortran program,
the record length of the records must be given,
and this is used by the Fortran I/O system to
make the file look as if it is made up of records
In the special case that the record length is given
the files are not considered to be divided into records,
but are treated as byte-addressable byte strings;
(A read or write request on such a file keeps consuming bytes until
satisfied, rather than being restricted to a single record.)
The peculiar requirements on sequential unformatted files
make it unlikely that they will ever be read or written by any means except Fortran I/O statements.
Each record is preceded and followed by
an integer containing the record's length in bytes.
The Fortran I/O system breaks sequential formatted files
into records while reading by using each newline
The result of reading off the end of a record is undefined according to the Standard.
The I/O system is permissive and
treats the record as being extended by blanks.
the I/O system will write a newline at the end of each
It is also possible for programs to write newlines
but the only effect will be that the single record
the user thought he wrote will be treated as
more than one record when being read or
Portability Considerations
The Fortran I/O system uses only the facilities of the
a widely available and fairly portable package,
with the following two nonstandard features:
The I/O system needs to know whether a file
can be used for direct I/O,
and whether or not it is possible to backspace.
Both of these facilities are implemented
will have the desired effect.
statement provides the user
with the ability to find out if two files are the
and to get the name of an already opened file
in a form which would enable the program to reopen
operating system implementation attempts to determine the full pathname.)
Therefore there are two routines which
depend on facilities of the operating system
to provide these two services.
runs on the PDP-11, VAX-11/780, and Interdata 8/32
Pre-Connected Files and File Positions
Units 5, 6, and 0 are preconnected when the program starts.
Unit 5 is connected to the standard input,
unit 6 is connected to the standard output,
and unit 0 is connected to the standard error unit.
All are connected for sequential formatted I/O.
All the other units are also preconnected when execution
is connected to a file named \fBfort.\fIn\fR.
These files need not exist,
nor will they be created unless their units are used
without first executing an
The default connection is for sequential formatted I/O.
The Standard does not specify where a file which has been explicitly \fBopen\fRed
for sequential I/O is initially positioned.
the I/O system attempts to position the file at the end,
will append to the file and a
will result in an end-of-file indication.
To position a file to its beginning,
0, 5, and 6 are positioned as they come
from the program's parent process.
\fISigplan Notices \fB11\fR, No.3 (1976),
as amended in X3J3 internal documents through ``/90.1''.
\fIUSA Standard FORTRAN, USAS X3.9-1966\fR,
New York: United States of America Standards Institute, March 7, 1966.
\fIComm. ACM \fB12,\fR 289 (1969)
\fIComm. ACM \fB14, \fR 628 (1971).
B. W. Kernighan and D. M. Ritchie,
The C Programming Language,
Englewood Cliffs: Prentice-Hall (1978).
D. M. Ritchie, private communication.
``A Portable Compiler: Theory and Practice'',
Proc. 5th ACM Symp. on Principles of Programming Languages
``An Informal Description of EFL'',
``RATFOR \(em A Preprocessor for a Rational Fortran'',
Bell Laboratories Computing Science Technical Report #55,
D. M. Ritchie, private communication.
APPENDIX. Differences Between Fortran 66 and Fortran 77
The following is a very brief description of the differences
between the 1966 [2] and the 1977 [1] Standard languages.
We assume that the reader is familiar with Fortran 66.
We do not pretend to be complete, precise,
but plan to describe what we feel are the most important aspects of the new language.
At present the only current information on the 1977 Standard is in publications of the X3J3 Subcommittee
American National Standards Institute.
The following information is from the ``/92'' document.
This draft Standard is written in English rather than a meta-language, but it is forbidding
No tutorials or textbooks are available yet.
Features Deleted from Fortran 66
All notions of ``Hollerith''
have been officially removed, although our compiler, like almost all in the foreseeable future,
will continue to support this archaism.
In Fortran 66, under a set of very restrictive and rarely-understood conditions, it is permissible
to jump out of the range of a
loop, then jump back into it.
Extended range has been removed in the Fortran 77 language.
The restrictions are so special, and the implementation of extended range is so unreliable in many compilers,
that this change really counts as no loss.
Completely blank lines are now legal comment lines.
Program and Block Data Statements
A main program may now begin with a statement that gives that program an external name:
Block data procedures may also have names.
There is now a rule that only
block data procedure may appear in a program.
(This rule is not enforced by our system.)
The Standard does not specify the effect of the program and block data names,
but they are clearly intended to aid conventional loaders.
Multiple entry points are now legal.
Subroutine and function subprograms may have additional entry points,
statement with an optional argument list.
Execution begins at the first statement following the
All variable declarations must precede all executable statements in the procedure.
If the procedure begins with a
all entry points are subroutine names.
statement, each entry is a function entry point,
with type determined by the type declared for the entry name.
If any entry is a character-valued function,
then all entries must be.
In a function, an entry name of the same type as that where control entered
must be assigned a value.
Arguments do not retain their values between calls.
(The ancient trick of calling one entry point with a large number of arguments
to cause the procedure to ``remember'' the locations of those arguments,
then invoking an entry with just a few arguments for later calculation,
Furthermore, the trick doesn't work in our implementation,
since arguments are not kept in static storage.)
variables and range parameters may now be of integer, real, or double precision types.
(The use of floating point
variables is very dangerous
because of the possibility of unexpected roundoff,
and we strongly recommend against their use).
statement is now defined for all values of the
$ max (0^,^ left floor ( u - l ) / d^ right floor )$
variable has a predictable value when exiting a loop:
the value that failed the limit test.
some of the arguments may be noted by an asterisk, as in
subroutine s(a, \(**, b, \(**)
The meaning of the ``alternate returns'' is described in section 5.2 of the Appendix.
One of the biggest improvements to the language is the addition of a character-string data type.
common character variables must have a length denoted by a constant expression:
character\(**17 a, b(3,4)
If the length is omitted entirely, it is assumed equal to 1.
A character string argument may have a constant length,
or the length may be declared to be the same as that of the corresponding actual argument at run time
(There is an intrinsic function
that returns the actual length of a character string).
Character arrays and common blocks containing character variables must be packed:
in an array of character variables, the first character of one element must follow the last character of
the preceding element, without holes.
The traditional implied declaration rules still hold:
a variable whose name begins with
\fBi, j, k, l, m,\fR or \fBn\fR is of type
other variables are of type
unless otherwise declared.
This general rule may be overridden with an
implicit real(a-c,g), complex(w-z), character\(**(17) (s)
declares that variables whose name begins with an
It is still poor practice to depend on implicit typing, but this statement is an industry standard.
It is now possible to give a constant a symbolic name, as in
parameter (x=17, y=x/3, pi=3.14159d0, s=\(fmhello\(fm)
The type of each parameter name is governed by the same implicit and explicit rules as for a variable.
The right side of each equal sign must be a constant expression
(an expression made up of constants, operators, and already defined parameters).
Arrays may now have as many as seven dimensions.
(Only three were permitted in 1966).
The lower bound of each dimension may be declared
Furthermore, an adjustable array bound may be an integer expression involving constants,
arguments, and variables in
real a(\(mi5:3, 7, m:n), b(n+1:2\(**n)
The upper bound on the last dimension of an array argument may be denoted by an asterisk
to indicate that the upper bound is not specified:
integer a(5, \(**), b(\(**), c(0:1, \(mi2:\(**)
A poorly known rule of Fortran 66 is that local variables in a procedure do not necessarily retain their values between
invocations of that procedure.
At any instant in the execution of a program,
if a common block is declared neither in the currently executing procedure
nor in any of the procedures in the chain of callers,
all of the variables in that common block also become undefined.
(The only exceptions are variables that have been defined in a
statement and never changed).
These rules permit overlay and stack implementations for the affected variables.
Fortran 77 permits one to specify that certain variables and common blocks are to retain their
values between invocations.
leaves the values of the variables
and all of the contents of common block
has this effect on all variables and common blocks in the procedure.
A common block must be \fBsave\fRd in every procedure in which it is declared if the desired effect is to occur.
All of the functions specified in the Standard are in a single category,
``intrinsic functions'', rather than being divided into ``intrinsic'' and ``basic external'' functions.
If an intrinsic function is to be passed to another procedure, it must be declared
(as in Fortran 66) causes a function other than the built-in one to be passed.
Character string constants are marked by strings surrounded by apostrophes.
If an apostrophe is to be included in a constant, it is repeated:
There are no null (zero-length) character strings in Fortran 77.
Our compiler has two different quotation marks, `` \(fm ''' and `` " ''.
(See Section 2.9 in the main text.)
One new operator has been added, character string concatenation, marked by a double slash
The result of a concatenation is the string containing the characters of the left operand followed by the characters of
The strings being concatenated must be of constant length in all concatenations
that are not the right sides of assignments.
(The only concatenation expressions in which a
character string declared adjustable with a ``\(**(\(**)'' modifier
or a substring denotation with nonconstant position values may appear
are the right sides of assignments).
Character String Assignment
The left and right sides of a character assignment may not share storage.
(The assumed implementation of character assignment is to copy characters from the right to the left side.)
If the left side is longer than the right, it is padded with blanks.
If the left side is shorter than the right, trailing characters are discarded.
It is possible to extract a substring of a character variable or character array element, using the colon notation:
is the string of $(n-m+1)$ characters beginning at the
$m sup th$ character of the character array element $a sub ij$.
Results are undefined unless $m<=n$.
Substrings may be used on the left sides of assignments and as procedure actual arguments.
It is now permissible to raise real quantities to complex powers,
or complex quantities to real or complex powers.
(The principal part of the logarithm is used).
Also, multiple exponentiation is now defined:
a\(**\(**b\(**\(**c = a \(**\(** (b\(**\(**c)
Relaxation of Restrictions
Mixed mode expressions are now permitted.
it is permissible to combine integer and complex quantities in an expression.)
Constant expressions are permitted where a constant is allowed,
(A constant expression is made up of explicit constants and
and the Fortran operators,
except for exponentiation to a floating-point power).
An adjustable dimension may now be an integer expression involving constants,
arguments, and variables in
Subscripts may now be general integer expressions;
loop bounds may be general integer, real, or double precision expressions.
expressions and I/O unit numbers may be general integer expressions.
branching structure has been added to Fortran.
It is called a ``Block If''.
A Block If begins with a statement of the form
Two other new statements may appear in a Block If.
If the logical expression in the Block If statement is true, the statements following it up to the
statement in the group is executed.
conditions are true, control passes to the statements following the
must follow all \fBelseif\fRs in a Block If.
Of course, there may be Block Ifs embedded inside of other Block If structures).
construct may be rendered
if (s .eq. \(fmab\(fm) then
else if (s .eq. \(fmcd\(fm) then
Some of the arguments of a subroutine call may be statement labels preceded by an asterisk, as in
call joe(j, \(**10, m, \(**2)
statement may have an integer expression, such as
alternate return (asterisk) arguments
and if $1<=k<=n$, the return is followed by a branch to the corresponding statement label;
otherwise the usual return to the statement following the
A format may be the value of a character expression (constant or otherwise),
or be stored in a character array, as in
END=, ERR=, and IOSTAT= Clauses
write(6, 101, err=20, iostat=a(4))
read(5, 101, err=20, end=30, iostat=x)
on which the I/O is done,
101 is the statement number of the associated format,
20 and 30 are statement numbers,
If an error occurs during I/O,
control returns to the program at statement 20.
If the end of the file is reached,
control returns to the program at statement 30.
In any case, the variable referred to in
clause is given a value when
the I/O statement finishes.
(Yes, the value is assigned to the name on the right side of the equal sign.)
This value is zero if all went well,
negative for end of file,
and some positive value for errors.
Character constants in formats are copied literally to the output.
Character constants cannot be read into.
write(6,\(fm(i2,\(fm\(fm isn\(fm\(fm\(fm\(fmt \(fm\(fm,i1)\(fm) 7, 4
Here the format is the character constant
(i2,\(fm isn\(fm\(fmt \(fm,i1)
and the character constant
is copied into the output.
next character is in the record.
specifies that the next character is
$n$ to the right of the current position.
specifies that the next character is
$n$ to the left of the current position,
allowing parts of the record to be reconsidered.
says that the next character is to be character
number $n$ in the record.
(See section 3.4 in the main text.)
A colon in the format terminates the I/O operation
if there are no more data items in the I/O list,
otherwise it has no effect.
x=\(fm("hello", :, " there", i4)\(fm
while the second only prints
According to the Standard,
each implementation has the option of putting
plus signs in front of non-negative
format code may be used to make the optional plus
signs actually appear for all subsequent items
while the format is active.
format code guarantees that the I/O system will not
insert the optional plus signs,
format code restores the default behavior of
(Since we never put out optional plus signs,
codes have the same effect in our implementation.)
Blanks in numeric input fields,
other than leading blanks
will be ignored following a
and will be treated as zeros following a
code in a format statement.
The default for a unit may be changed by using
(Blanks are ignored by default.)
The Standard requires that if a numeric item
cannot be represented in the form required by a format code,
the output field must be filled with asterisks.
(We think this should have been an option.)
There is a new integer output code,
except that there will be at least $m$
digits in the output field,
The case \fBi\fR$w.0$ is special,
in that if the value being printed is 0,
On input, exponents may start with the letter
\fBE, D, e, \fRor \fBd.\fR
All have the same meaning.
On output we always use \fBe\fR.
format codes also have identical meanings.
A leading zero before the decimal point in
without a scale factor is optional with the
format code which is the same as
formats for output depending.
on the size of the number and of $d$.
A codes are used for character values.
use a field width of $w$,
uses the length of the character item.
There are default formatted input and output units.
reads from the standard unit using format statement 10.
The default unit may be explicitly specified by an asterisk, as in
Similarly, the standard output units is specified by a
statement or an asterisk unit:
kind of free form input for sequential I/O.
It is invoked by using an asterisk as the
values are separated by strings of blanks
except for character strings,
End of record counts as a blank,
except in character strings,
Complex constants are given as two real constants
separated by a comma and enclosed in parentheses.
such as between two consecutive commas,
means the corresponding variable in the
Values may be preceded by repetition counts,
4\(**(3.,2.) 2\(**, 4\(**\(fmhello\(fm
which stands for 4 complex constants, 2 null values,
For output, suitable formats are chosen for
The values of character strings are printed;
they are not enclosed in quotes, so they cannot be read back
using list-directed input.
A file connected for direct access consists of
a set of equal-sized records each of which is
uniquely identified by a positive integer.
The records may be written or read in any order,
using direct access I/O statements.
which gives the record number to be read or written.
read(2, rec=13, err=20) (a(i), i=1, 203)
reads the thirteenth record into the array
The size of the records must be given by an
Direct access files may be connected for either formatted
Internal files are character string objects,
such as variables or substrings,
or arrays of type character.
In the former cases there is only a single record
in the latter case each array element is a record.
The Standard includes only sequential
formatted I/O on internal files.
(I/O is not a very precise term to use here,
but internal files are dealt with using
There is no list-directed I/O on internal files.
Internal files are used by giving the name of the
character object in place of the unit number, as in
which reads a card image into
two integers from the front of it.
always starts at the beginning
(We also support a compatible extension, direct I/O on internal files.
This is like direct I/O on external files,
except that the number of records in the file cannot be
OPEN, CLOSE, and INQUIRE Statements
These statements are used to connect and disconnect
and to gather information about units and files.
statement is used to connect a file with a
or to alter some properties of the connection.
The following is a minimal example.
open(1, file=\(fmfort.junk\(fm)
takes a variety of arguments with meanings described below.
.ta .3i .6i .9i 1.2i 1.5i 1.8i
\fB\\$1\\$2\\$3\\$4\\$5\\$6\fR\ \c
a small non-negative integer which is the unit to
which the file is to be connected.
at the time of this writing,
If this parameter is the first one in the
which when stripped of trailing blanks,
is the name of the file to be connected to the unit.
The filename should not be given if the
If this parameter is not given,
a temporary file will be created.
Temporary files are destroyed at the end of execution.
the file will be created if it doesn't exist,
our system treats it as synonymous with
depending on whether the file is
to be opened for sequential or direct I/O.
a positive integer specifying the record length of
the direct access file being opened.
We measure all record lengths in bytes.
systems a record length of 1 has the special meaning explained
in section 5.1 of the text.
This parameter has meaning only for formatted I/O.
other than leading blanks,
in numeric input fields are to be treated as zeros.
Opening a new file on a unit which is already connected
has the effect of first closing the old file.
severs the connection between a unit and a file.
The unit number must be given.
The optional parameters are
Scratch files cannot be kept,
means the file will be removed.
statement gives information about
or a file (``inquire by file'').
inquire(file=\(fmjunk\(fm, number=n, exist=l)
a character variable specifies the file the
Trailing blanks in the file name are ignored.
an integer variable specifies the unit the
The logical variable is set to
The logical variable is set to
is connected to a unit or if the unit is connected
an integer variable to which is assigned the
number of the unit connected to the file,
a logical variable to which is assigned
a character variable to which is assigned the name
of the file (inquire by file) or the name of the
file connected to the unit (inquire by unit).
The name will be the full name of the file.
a character variable to which will be assigned
if the connection is for direct I/O.
The value becomes undefined if there is no connection.
a character variable to which is assigned the
if the file could be connected for
if the file could not be connected for sequential I/O,
a character variable to which is assigned the value
if the file could be connected for direct I/O,
if the file could not be connected for direct
a character variable to which is assigned the value
if the file is connected for formatted I/O,
if the file is connected for unformatted
a character variable to which is assigned the value
if the file could be connected for formatted I/O,
if the file could not be connected for formatted I/O,
a character variable to which is assigned the value
the file could be connected for unformatted I/O,
if the file could not be connected for unformatted I/O,
an integer variable to which is assigned the record length
of the records in the file if the file is connected
an integer variable to which is assigned one more
than the number of the the last record read from a file connected
a character variable to which is assigned the value
if null blank control is in effect for the file
connected for formatted I/O,
if blanks are being converted to zeros and
the file is connected for formatted I/O.
will remember that the people who wrote the standard
probably weren't thinking of his needs.
The declarations are omitted.
open(1, file="/dev/console")
system this statement opens the console for formatted sequential
statement for either unit 1 or file "/dev/console"
would reveal that the file exists, is connected to unit 1,
has a name, namely "/dev/console",
is opened for sequential I/O,
could be connected for sequential I/O,
could not be connected for direct I/O (can't seek),
is connected for formatted I/O,
could be connected for formatted I/O,
could not be connected for unformatted I/O
has neither a record length nor a next record number,
and is ignoring blanks in numeric fields.
the only way to discover what permissions you have
for a file is to open it and try to read and write it.
parameter will return system error numbers.
statement does not give a way of determining permissions.