From: burley@geech.gnu.ai.mit.edu (Craig Burley)
Newsgroups: comp.lang.fortran
Subject: Re: Variable repeat count specifier for FORMAT statments
Date: 24 Jul 92 16:55:01 GMT
Distribution: na
Organization: Free Software Foundation 545 Tech Square Cambridge, MA 02139
In-reply-to: psun@jhunix.hcf.jhu.edu's message of 23 Jul 92 21:51:13 GMT

In article <1992Jul23.215113.16531@jhunix.hcf.jhu.edu> psun@jhunix.hcf.jhu.edu (Peter Sun) writes:

   My apologies if this questions seems trivial, but I've tried to find the
   answer in so many places.  I need to know how to give a variable as the
   number of repeat counts to a format field descriptor statement.  For
   example I know on VAX/VMS this can be done with something like:

		      write (*, '(<n>(I8))')

   which will repeat the format descriptor I8 n number of times, but I haven't
   found this portable to other compilers.  Namely, the MIPS Fortran 77
   compiler for the SGI IRIS system.  Is there a standard for this?  Or is it
   just compiler dependent.

What you show is nonstandard and probably doesn't work on VAX/VMS either.
Perhaps what you mean is _this_ nonstandard construct:

      WRITE (*,10)
10    FORMAT (<N>(I8))

(where N is an integer variable that has the repeat count at the time of the
WRITE statement's execution)

It is possible VAX/VMS FORTRAN has been further extended to support the
example you show, because your example has a _constant_ FORMAT expression,
but it wouldn't support a variable FORMAT, as in "WRITE (*,A(1:20))",
containing the "<expr>" construct.

To do this sort of thing in ANSI FORTRAN 77 is a real pain.  You have
to convert the expression (the value of N in the example above) to a
character string and insert that string in a character variable containing
the desired format.  Then use the character variable as the run-time format
string for the operation.  And even this isn't really enough to handle the
full capabilities of the VAX/VMS feature -- consider:

      READ (*,10) I,J,K
10    FORMAT (I8,I8,<K-J+1>I8)

I'm quite sure (having seen how the compiled code works) that VMS FORTRAN will
compile this so that I and J are read _first_, then K-J+1 is evaluated to
determine the repeat count for the final I8.  You can't possibly do this,
as far as I know, by encoding a single format string for a single I/O
operation -- and as far as I remember in FORTRAN 77 there are indeed I/O
operations that cannot be split into multiple I/O operations (since things
like '$' are nonstandard), though I might be wrong about that.

How does VMS FORTRAN handle the construct, asks the curious person?

Well, the compiler produces a structure containing the encoded info on the
compile-time FORMAT statement for use by the run-time library when the
I/O statement is encountered.  The structure has basically a list of items
specifying things like repeat counts, and each place where it needs to
represent an integer, it can do so in a variety of ways -- in a compact
form for a short-enough integer, a less-compact form(s) for (a) larger
integer(s), and, interestingly, a pointer to a function for a run-time
evaluation.  (The choice is signaled in the structure itself, of course.)

So, when the FORMAT evaluator in the run-time library is called to evaluate
one of these precompiled structures (as vs. a run-time FORMAT evaluator,
which evaluates a character string), it pulls out the necessary values
either by a "load" kind of machine operation or, where appropriate, a
procedure call to the function, which is expected to return the correct
integer value.

Thus, the compiler has already made a little internal statement function that
might look like

      __FMT1() = N

or

      __FMT2() = K-J+1

that is purely internal (and I'm just showing the Fortran-like representation
of it, since I'm writing this for Fortran people, not C or VAX assembler
people).

And the compiler has placed a pointer to the appropriate internal function
in the precompiled structure containing the FORMAT info.

Clearly a run-time version of this cannot easily be done, since the expression
can be fairly arbitrary and would have to be evaluated at run time, along with
having available a list of all known variable, array, and function names and
their locations in memory -- and if the run-time expression contained the
only reference in a program to a particular intrinsic or procedure, "selective"
linking would be impossible for the program (since _any_ procedure accessible
to the program would have to be linked in case a run-time format referenced
it).  (Maybe the VMS FORTRAN spec disallows such references anyway; I don't
want to run down to the basement to find out.)

A smart compiler (like GNU Fortran might become someday :-) could, if unable
to do the internal-procedure trickier used by VMS FORTRAN, translate many
of the instances of the VMS-supported compile-time FORMAT having a run-time
expression to code that ran on any machine (by compiling direct-evaluation
code in with each I/O statement to take place before the I/O).  Such an
approach wouldn't be able to handle the READ... I,J,K example I gave earlier,
but the compiler should be able to complain about any such failures as being
unsupportable.  But GNU Fortran's front end already supports the syntax
of this feature, and perhaps we might be able to get it to do the right thing
for most or all of the machines to which it ports (which would require using
a run-time library other than f2c or equivalent, since it uses purely
character-string-based FORMAT evaluation at run time).

Funny, this question ultimately is much like the question of how to do
run-time evaluation of expressions, which also is fairly easy once you know
what you're doing, and tricky otherwise.  Perhaps the best answer to all
such questions is: use Lisp, Smalltalk, or Prolog instead.  :-)
(REALLY, I'M KIDDING, SEE THE SMILEY, FORTRAN'S FINE! :-)
--

James Craig Burley, Software Craftsperson    burley@gnu.ai.mit.edu
Member of the League for Programming Freedom (LPF)
From: kauth@hpfcso.FC.HP.COM (Joan Kauth)
Date: Fri, 24 Jul 1992 16:24:45 GMT
Subject: Re: 64-bit integers from Sun f77
Organization: Hewlett-Packard, Fort Collins, CO, USA