home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!olivea!mintaka.lcs.mit.edu!ai-lab!life.ai.mit.edu!burley
- From: burley@geech.gnu.ai.mit.edu (Craig Burley)
- Newsgroups: comp.lang.fortran
- Subject: Re: Variable repeat count specifier for FORMAT statments
- Message-ID: <BURLEY.92Jul24125501@geech.gnu.ai.mit.edu>
- Date: 24 Jul 92 16:55:01 GMT
- References: <1992Jul23.215113.16531@jhunix.hcf.jhu.edu>
- Sender: news@ai.mit.edu
- Distribution: na
- Organization: Free Software Foundation 545 Tech Square Cambridge, MA 02139
- Lines: 112
- 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)
-