The statement list was not optional in the "original" FORTRANs (I and II). Here is a listing of the routine used to read GO TO
statements:
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
REM
REM C0200/ CALLS=GETIFN,DIAG,TEST..,C0190,C0180,TET00,C0160,
REM CIT00,SS000(CSA000).
REM C0200 PROCESSES GO TO STATEMENTS.
C0200 TSX GETIFN,4 * GET INTERNAL FORMULA NUMBER IN 1C
STO 1C+2 AND IN 1C+2.
TSX C0190,4 * OBTAIN IN ACC NEXT NB CHARACTER
CAS L(9) AND COMPARE IT WITH 9.
TXI C0205,0 IF NON-NUMERIC, GO COMPARE WITH (.
NOP IF NUMERIC, THEN
TSX C0180,2 * OBTAIN IN 1G THE BINARY EQUV BETA.
TSX TESTD0,4 * THE AC SHOULD CONTAIN AN ENDMARK.
CLA 1G STORE BETA IN 1C+1 TO CONSTRUCT
STO 1C+1 THE 2ND WORD OF TIFGO TABLE ENTRY.
TXI C0202,0 GO TO ENTER 1C,1C+1 INTO TIFGO.
C0205 CAS ALPAR TEST CHARACTER FOR ALPHABETIC.
TXI C0210,0 IF NOT ALPHABETIC, THEN
TXI C0212,0 THIS IS TYPE= GO TO ( ), I.
C0210 TSX C0160,2 * TYPE= GO TO N,(),SO OBTAIN IN 1G N
TSX TESTG0,4 * WHICH SHOULD BE FOLLOWED BY COMMA.
CLA 1G SAVE THE SYMBOL N IN 1C+3
STO 1C+3 FOR COMPILED INSTRUCTION.
TSX C0190,4 * OBTAIN IN ACC NEXT NB CHARACTER,
TSX TESTE0,4 * WHICH SHOULD BE A LPARAN.
CLA L(1) PREPARE TO SET ADDRESS PART OF 1C
TRA C0213 TO 1 TO INDICATE CLASS OF TRANSFER.
C0212 CLA L(2) PREPARE TO SET ADDR OF 1C TO 2.
C0213 STA 1C STORE 1 OR 2 IN ADDR OF 1C.
LXD CTRAD,2 OBTAIN 250-(NO. TRAD ENTRIES), AND
PXD ,2 PLACE IN THE DECREMENT OF THE AC
STO 1C+1 AND STORE IN 1C+1.
C0215 TSX C0190,4 * OBTAIN IN ACC NEXT NB CHAR.
TSX C0180,2 * OBTAIN IN 1G THE BIN EQU OF BETA.
STO 2G SAVE CHAR IN ACC.
TSX TET00,1 * GO TO ENTER 1G
PZE 3 INTO TRAD TABLE (TABLE 3).
LXD CTRAD,2 REDUCE COUNTER
TIX C0216,2,1 CTRAD
C0216 SXD CTRAD,2 BY 1.
CLA 2G RESTORE CHAR TO ACC.
TSX TESTB0,4 * TEST FOR COMMA OR RPAREN.
TNZ C0215 IF RIGHT PARENTHESIS, THEN
CLA CTRAD OBTAIN IN ADDR OF ACC 250-NO. OF
ARS 18 ENTRIES IN TRAD TABLE,AND STORE
STA 1C+1 IN ADDR OF 1C+1.
CLA 1C OBTAIN 1C IN ACC
LBT AND TEST LOW ORDER BIT.
TRA C0220 THIS IS A TYPE GO TO (),I FORMULA.
TSX C0190,4 * OBTAIN NEXT NB CHAR AND
TSX TESTD0,4 * TEST FOR ENDMK.
TSX CIT00,4 * GO MAKE THE FOLLOWING CIT ENTRY=
PZE 1C+2 WORD 1--DECR= INTFORMNN (LOCATION)
PZE L(TRA) WORD 2--TRA00P (OP AND DECR)
PZE 1C+3 WORD 3--VARIABLE N (ADDRESS)
PZE L(0) WORD 4--00000 (REL ADDR AND TAG).
TRA C0202 GO TO ENTER 1C,1C+1 INTO TIFGO.
C0220 TSX C0190,4 * EXAMINE NEXT NB CHARACTER,
TSX TESTG0,4 * WHICH SHOULD BE A COMMA.
TSX C0190,4 * OBTAIN IN ACC NEXT NB CHAR, AND
TSX C0160,2 * OBTAIN IN 1G THE FXF-PT. VARIABLE.
TSX TESTD0,4 * WHICH SHOULD BE FOLLOWED BY ENDMK.
CLA L(1) PREPARE PROPER FORM OF SUBSCRIPT
STO E+3 COMBINATION AS
STO DIMCTR INPUT TO SUBSCRIPT ANALYSIS=
CLA 1G E+3 = 1ST COEFFICIENT.
STO E+4 E+4 = 1ST SUBSCRIPT VARIABLE,
STZ E+9 E+9 = ADDEND OF SUBSCRIPT,
TSX CSA000,4 * DIMCTR = DIMENSION OF VARIABLE.
CLA E OUTPUT FROM CSA IS FOUND IN
ARS 24 E = I--TAUTAG (GENERAL TAG) 1-11.
STO 2G ADJUST AND SAVE FOR COMP. INSTR.
TSX CIT00,4 * GO MAKE THE FOLLOWING CIT ENTRY=
PZE 1C+2 WORD 1--DECR-INTFORMNO(LOCATION)
PZE L(TRA) WORD 2--TRA000(OP AND DECR)
PZE L(0) WORD 3--000000(ADDRESS)
PZE 2G WORD 4--ADDR = TAUTAG FOR I
REM C0200= ENTRY POINT USED BY C0400,C1000.
C0202 TSX TET00,1 * GO TO TET TO ENTER 1C AND 1C+1
PZE 2 INTO TIFGO TABLE (TABLE 2).
CTRAD TXI CA010,0,250 * EXIT TO PROCESS NEXT STATEMENT.
REM END OF PROGRAM C0200.
(See the end of this answer for the source of the code.)
Clearly a comma and a statement list is expected when GO TO
is not followed by a number.
But why was it required? Well, the reason is a little complicated. It certainly wasn't
for the benefit the programmer or for safety. The concept of a run-time error check
generated by a compiler was, after all, a silly idea at the time. The following discussion
pertains to IBM's FORTRAN I and II for the 704/709/7090/7094.
In actuality, the list was necessary for the compiler. During the flow analysis phase, the
user's program is divided into basic blocks, and control transfers between the blocks are
recorded. Then a simulation of the program is carried out to determine the relative
frequency of execution of blocks. (Naturally, any information provided in FREQUENCY
specifications is taken into account here.) The knowledge gained in this process is used
by the register allocation algorithm, which tries to minimize the use of load/store
operations in "hot" portions of the user's code.
Because ASSIGN
statements can occur anywhere in a FORTRAN program, the compiler couldn't
know where control might be sent by a GO TO
statement with a non-numeric operand unless
the entire program has been read and all ASSIGN
s have been seen. Upon seeing GO TO N, (...)
, the compiler makes a table entry saying "at this point, we might transfer to any
one of these statements"; a similar thing happens for computed GO TO
statements as well.
The determination of basic blocks is based on these table entries, and not on accumulated
constants in ASSIGN
statements, since this way is more straightforward and avoids
creating a symbol table exclusively for ASSIGN
ed variables. Also, the list of targets
lets the compiler produce a diagnostic if an illegal transfer (e.g., one leading into the
range of a DO
loop that has not yet been entered) might happen.
Consider also how the form of computed and ASSIGN
ed GO TO
allows for a
micro-optimization. Here are excerpts from a real FORTRAN program (from 1965, but these
parts use nothing that wasn't available in FORTRAN II; regardless, this is just an example
for illustration, and the source is linked at the end of this answer):
216 ASSIGN 224 TO KADD1
ASSIGN 250 TO KADD2
...
ASSIGN 240 TO KADD2
...
ASSIGN 223 TO KADD1
...
ASSIGN 223 TO KADD1
...
GO TO KADD2,(240,250)
240 PRINT 1017
1017 FORMAT(1H0,10X,84H** INDICATES THAT THIS VALUE IS TOO HIGH DUE TO
XSAMPLING ERROR. IT WILL BE SET EQUAL/14X,71HTO THE MAXIMUM VALUE O
XF THE REMAINING COHERENCES FOR PLOTTING PURPOSES.)
250 GO TO KADD1,(223,224)
223 PRINT 1018
1018 FORMAT(1H0,10X,91HX INDICATES THIS VALUE IS NOT COMPUTABLE DUE TO
XA NEGATIVE OR ZERO POWER SPECTRAL ESTIMATE./13X,82HIT WILL BE SET
XEQUAL TO THE MAXIMUM OF THE REMAINING VALUES FOR PLOTTING PURPOSES
X.)
224 IF(IPRNT3(KIT+1)-IB)231,232,231
and later
ASSIGN 442 TO KADD1
ASSIGN 433 TO KADD2
...
432 GO TO KADD2,(433,434)
433 SPMAX=-9999999.0
...
ASSIGN 440 TO KADD1
ASSIGN 434 TO KADD2
434 SPX(I)=SPMAX
...
GO TO KADD1,(440,442)
440 PRINT 1405
If the analysis were based on ASSIGN
statements, then the compiler would have to treat a
GO TO KADD1
as potentially transferring to any of the statements 223, 224, 440, and 442,
even though such a four-way transfer isn't actually possible. A "sufficiently smart
compiler" could determine this itself, but this was 1958.
Note that the LLVM indirectbr
instruction, which performs an indirect transfer of control much like FORTRAN's assigned GO TO
, also requires a list of potential locations "so that dataflow analysis has an accurate understanding of the CFG [control-flow graph]".
The level of optimization achieved by IBM's FORTRAN I and FORTRAN II was not matched by
another FORTRAN compiler for quite a long time, according to what I've read. Compilers
that didn't do sophisticated flow analysis did not have the same need for the target list
in ASSIGN
ed GO TO
statements. Therefore it became optional.
Sources (credit for most of them goes to the Software Preservation Group's fantastic
History of FORTRAN and FORTRAN II
page):
The main source is the Systems Manual for 704 FORTRAN and 709 FORTRAN. Applied
Programming Department, International Business Machines Corporation, April
1960.
This is a must-read if you're interested in FORTRAN I/II's internals.
The next source is a listing of FORTRAN II's source
code. The
GO TO
processing routine C0200
begins at sequence number 4F11844, which is on page 70
of the PDF of Volume
I
(according to the handwritten page number in the bottom right, this is logically page 66). You can also browse this code in hypertext form.
The FORTRAN example came from the fabulous B5500 Software
repository. The specific source was
file
BMD02T/T800016,
which is headed "AUTOCOVARIANCE AND POWER SPECTRAL ANALYSIS". The dialect of FORTRAN here
is B5500 FORTRAN IV; a manual for it from 1968 (three years after the quoted code was
written) is available
here.
Jack Harper's website on the IBM 7090/7094 computers
is a great resource when studying old programs like FORTRAN II and the LISP 1.5
interpreter.
L
? Like in your example, could youASSIGN 11 TO L
and then execute theGOTO L
statement with 11 not being in the list? That would at least give the poor reader some clue where the jump might go, rather than just anywhere.