The Oak Ridge ALGOL Compiler for the Control Data Corporation 1604 Preliminary Programmer's Manual
Part 1
ORNL-3460 UC-32—Mathematics and Computers TID-4500 (23rd ed.)
THE OAK RIDGE ALGOL COMPILER FOR THE CONTROL DATA CORPORATION 1604 PRELIMINARY PROGRAMMER'S MANUAL
L. L. Bumgarner
OAK RIDGE NATIONAL LABORATORY operated by UNION CARBIDE CORPORATION for the U.S. ATOMIC ENERGY COMMISSION
Printed in USA. Price: $1.25 Available from the Office of Technical Services U. S. Department of Commerce Washington 25, D. C.
LEGAL NOTICE
This report was prepared as an account of Government sponsored work. Neither the United States, nor the Commission, nor any person acting on behalf of the Commission:
A. Makes any warranty or representation, expressed or implied, with respect to the accuracy, completeness, or usefulness of the information contained in this report, or that the use of any information, apparatus, method, or process disclosed in this report may not infringe privately owned rights; or
B. Assumes any liabilities with respect to the use of, or for damages resulting from the use of any information, apparatus, method, or process disclosed in this report.
As used in the above, “person acting on behalf of the Commission” includes any employee or contractor of the Commission, or employee of such contractor, to the extent that such employee or contractor of the Commission, or employee of such contractor prepares, disseminates, or provides access to, any information pursuant to his employment or contract with the Commission, or his employment with such contractor.
ORNL-3460
Contract No. W-7405-eng-26
Mathematics Division
THE OAK RIDGE ALGOL COMPILER FOR THE CONTROL DATA CORPORATION 1604—PRELIMINARY PROGRAMMER’S MANUAL
L. L. Bumgarner
DATE ISSUED JAN 30 1964
OAK RIDGE NATIONAL LABORATORY Oak Ridge, Tennessee operated by UNION CARBIDE CORPORATION for the U.S. ATOMIC ENERGY COMMISSION
CONTENTS
I. Introduction 1 II. Language Restrictions 2 III. Modes of Operation of the Compiler 4 IV. Input-Output and Intermediate Tape 5 Input-Output 5 READ 5 PAGE 7 Lists and the List Declaration 7 PRINT 9 WRITE 9 PUNCH 10 Formats and the Format Declaration 10 INPUT 11 OUTPUT 12 Intermediate Tape Procedures 13 BINREAD 13 BINWRITE 14 ENDFILE 14 REWIND 14 BACKUP 14 Tape-Checking Procedures 14 EOF 15 READERR 15 WRITERR 15 V. The External Declaration 16 VI. Standard Procedures 16 VII. Error Checking and Diagnostics 17 VIII. Running Programs 19 ALGOL Control System 20 EOP Card 20 Compile and Execute: ALGO 21 PROGRAM Card 22 Compile/Execute: ALDAP 22 ALDAP Control Statement 22 Job Deck: ALDAP Compilation/Execution 23 Examples 25
APPENDICES A. Adjuncts to Algol 60 30 B. Hardware Representation 32 C. Structure of Procedure Calling Sequence 35 D. Internal Representation of Strings 37 E. Program Efficiency 38 F. Controversial Features of Algol 60 40 G. Fortran Subprograms in an Algol Program 41
THE OAK RIDGE ALGOL COMPILER FOR THE CONTROL DATA CORPORATION 1604—PRELIMINARY PROGRAMMER’S MANUAL
L. L. Bumgarner
ABSTRACT
This document is a preliminary programmer’s manual for use of the Control Data 1604 Algol Compiler. The compiler was constructed by the Programming Research Group of the Mathematics Division in cooperation with Control Data Corporation. A knowledge of Algol 60 is assumed. Included are descriptions of input-output facilities and details for operation under the monitor system.
I. Introduction
This document is to serve as a programmer’s manual for the Algol compiler constructed as a cooperative project by Control Data Corporation and the Mathematics Division of Oak Ridge National Laboratory. The compiler is designed for the Control Data 1604 and 1604-A computers. The document is preliminary in that the compiler is not thoroughly tested and may undergo further development.
The reader is assumed to be familiar with Algol 60. The defining descriptions are the two reports on Algol 60 available in the following references:
1. P. Naur et al, “Report on the Algorithmic Language Algol 60,” Comm. Assoc. Comp. Mach., 3 (1960), No. 5, 299-314.
2. P. Naur et al, “Revised Report on the Algorithmic Language Algol 60,” Comm. Assoc. Comp. Mach., 6 (1963), No. 1, 1-17.
The second report clears up certain ambiguities that appeared in the first report. The reports are not easy reading for the novice. The following expositions are more readable:
1. Baumann, Bauer, Feliciano and Samelson, Introduction to Algol, Prentice-Hall, Inc. (to be published in late 1963).
2. Bottenbruch, H., “Structure and Use of Algol 60,” Jour. Assoc. Comp. Mach., 9 (1962), No. 2, 161-221, and ORNL-3148.
The Baumann publication also contains the revised Algol 60 report.
Throughout this document various examples of statements and declarations appear without the semicolon which is always required for separating them. This is to avoid the implication that the semicolon is part of the statement or the declaration. In sentences, a comma or period may appear where a semicolon or other delimiter would be indicated in the context of a program.
Word delimiters rendered in bold-face type in the Algol report are herein indicated by underlining.
II. Language Restrictions
The compiler correctly handles programs written in Algol 60 subject to the following restrictions.
1. The use of an integer label as an actual parameter will cause an incorrect program to be compiled.
2. A GO TO statement with an undefined switch designator as the designational expression will cause incorrect operation of the final program.
3. Type restrictions:
(a) The exponentiation expression x ↑ y will have type real unless x is of type integer and y is a non-negative integer constant. This differs slightly from the definition in the Algol report but will generally cause no difficulty.
(b) In the construction
else
the arithmetic expressions must have the same type, or else an incorrect program will be compiled. For example, in the statement
x := if a < b then z else w
z and w should both be declared real or both integer.
(c) In a procedure call (procedure statement or function call) each actual parameter having an arithmetic value must have the same type as the corresponding formal parameter in the procedure declaration. The type of the formal parameter is that designated in the specification part if it appears there. If a formal parameter representing an arithmetic quantity does not appear in the specification part, it is assumed to be specified real. Full use of specifications is desirable for descriptive purposes and for optimization.
Caution. Restriction (c) is more likely to cause errors than the other restrictions. It is very easy to write P(1,2) when the parameters of P are specified real, but incorrect coding will result. The call P(1.0,2.0) works correctly.
4. Standard procedure names (see section VI) used as parameters in procedure calls will cause an incorrect program to be compiled. A call, therefore, such as
P(sin)
is incorrect. Note, however, that a call of the type
Q(sin(x))
causes no trouble. The case P(sin) can be programmed in another way. Make the declaration
real procedure sin 1 (t); real t; sin 1 := sin(t).
The call
P(sin 1)
is then correct.
5. Arrays called by value are not handled. If an array identifier appears in the value part, an incorrect program will be compiled.
6. “Dynamic” own arrays are not handled. This means that all own arrays are treated as having constant subscript bounds; this constitutes one possible interpretation of the Algol 60 report. An own array may be declared with variable subscript bounds, but only one allocation of storage will be made, and if the bounds change, this will be ignored.
7. Recursive procedures are not handled. This restriction encompasses all cases of a function designator appearing in the actual parameter part of a call of the same function, unless that function is a standard function. Thus f(f(x)) is not permitted in general, but sin(sin(x)) is allowed.
III. Modes of Operation of the Compiler
There are two distinct modes of operation: ALGO and ALDAP.
ALGO is a compile-and-execute mode in which the two phases cannot be separated. The Algol program is translated into a machine language program in core memory, and execution of the program immediately and automatically follows. There is no assembly program phase.
ALDAP makes use of the CODAP assembly program facilities. It is possible to compile procedures separately and reference them from an Algol program. The procedures may be written in Algol, CODAP or Fortran. This provision is made possible with the aid of the external declaration discussed in section V.
The ALGO mode provides significantly faster compilation than the ALDAP mode for most programs. The target programs produced in the two modes are essentially the same. In the ALGO mode, program checkout may be done at the Algol language level. In the ALDAP mode, checkout may also be done at the machine and assembly language levels, and modifications may be made at these levels.
IV. Input-Output and Intermediate Tape
There are seven standard procedures for input-output, five for intermediate tape, and three for checking tape conditions. Two declarations, format and list, are additions to the language.
Input-Output
The input-output procedures are: READ, PAGE, PRINT, WRITE, PUNCH, INPUT, and OUTPUT.
READ
The READ procedure is used to input numbers and Boolean values. A READ statement has the form
READ (V1, V2, ..., Vn)
where n is any positive integer and each Vk is a variable. For example, the statement
READ (X, Y, A[1], B[1])
will input values into the four variables listed. For inputing values into an array, a statement such as the following might be used:
for I := 1 step 1 until 100 do READ (A[I]) .
The READ procedure inputs numbers and truth values. A number must be a legal Algol number (although an E may be substituted for the symbol ₁₀). For input into a Boolean variable, the truth values true and false are accepted; also, a non-negative number or a plus sign is interpreted as false and a negative number or a minus sign is interpreted as true. A blank is read as zero.
With the READ procedure, the type of a number on a data card does not have to be the same as the type of the variable to which it is assigned. Any necessary type conversions are done automatically. If N is the next number in the data, the statement
READ (V)
is equivalent to the statement
V := N .
The data cards are free field. The number of values per card, the length of numbers, and the number of spaces are arbitrary. A comma, however, must follow each number, including the last one on the last data card.
In reading a value into a subscripted variable, the current value of the subscript expression is not affected by that READ statement. For example, in the statement
READ (I, A[I])
the old value of I is used in A[I].
The READ procedure will input data from the standard input medium only.
PAGE
The PAGE procedure is used to cause a page ejection on the standard output medium. PAGE has no parameters. It is called by simply writing
PAGE .
Lists and the List Declaration
The input and output procedures described in the rest of this section, as well as the binary read and write procedures, make use of the concept of a list. A list[1] is a sequence of expressions. An example is
U + V, C[0], if B then X else Y .
It may be inconvenient in some cases to write down all of the expressions explicitly. The loop expression[1] may be used as a shorthand device in a list. It is an Algol-like construction of which the following is an example:
for I := 1 step 1 until 1000 do A[I] .
This is equivalent to the list
A[1], A[2], ..., A[1000] .
The entity following do in a loop expression may itself be a list, but this list must be enclosed in parentheses if it contains more than one member.
The loop expression
for I := 1 step 1 until 1000 do (A[I], B[I])
is equivalent to the list
A[1], B[1], A[2], B[2], ..., A[1000], B[1000] .
The loop expression
for I := 1 step 1 until 10 do (A[I], for J := 1 step 1 until 20 do B[I,J])
is equivalent to the list
A[1], B[1,1], B[1,2], ..., B[1,20], A[2], B[2,1], B[2,2], ..., B[2,20], .................................... A[10], B[10,1], B[10,2], ..., B[10,20] .
A list may be given a name through a list declaration. A list declaration has the form
list identifier := list .
Examples are:
list L := X, A + B
list M := for I := 1 step 1 until N do A[I] .
A list identifier may itself appear in a list. One of the above examples might be written with the aid of the following declaration:
list L := for J := 1 step 1 until 20 do B[I,J] .
The loop expression is then
for I:= 1 step 1 until 10 do (A[I], L) .
A list declaration obeys the same rules of syntax and scope as do other declarations.
A list identifier may be used as an actual parameter of a procedure call, with the requirement that the corresponding formal parameter be specified list. However, an actual list may appear as a parameter only in calls of the standard procedures, as described.
The PRINT procedure is used to output numbers in a simple, rigid manner. A PRINT statement has the form
PRINT (list),
where list is described above. An example of a PRINT statement is
PRINT (A, if N = 0 then S else T).
A PRINT statement always puts out at least one line printer image. A line may contain up to 6 numbers, each of which is in scientific notation with 10 decimal places. Each number is right-justified in a field of 20 columns. (The format is 6E20.10.) The above PRINT statement will output two numbers in the first forty spaces, and the rest of the line will be blank. A PRINT statement such as
PRINT (for I := 1 step 1 until 10 do A[I])
will output one line of 6 numbers followed by one line of 4 numbers. Single spacing between lines is automatic.
The PRINT procedure always outputs on the standard output medium.
WRITE
The WRITE procedure is used to output strings. Examples of WRITE statements are:
WRITE ('TABLE')
WRITE (if D < 0 then 'TRUE' else 'FALSE') .
Each parameter must be a string expression (see Appendix A for definition of string expression). There may be any number of parameters, but each string will appear on a separate line. If a string is too long to go on one line, it will be continued on the next line. A string should not contain another string. Lines are single spaced. Each WRITE statement causes at least one line printer image to be put out.
The WRITE procedure always outputs on the standard output medium.
PUNCH
The PUNCH procedure is used to output numbers on punched cards in a form which can be input by the READ procedure. Each number punched will be followed by a comma. Each card punched may contain up to four numbers. Each number will be of type real, but since the READ procedure makes any necessary type conversions this is unimportant. A PUNCH statement has the same form as a PRINT statement. Each PUNCH statement causes at least one card image to be put out.
The PUNCH procedure always outputs on the standard punch medium.
Formats and the Format Declaration
The two input and output procedures remaining to be described make use of formats. The formats are exactly those used in Fortran, and readers unfamiliar with Fortran will find it necessary to refer to the Control Data Fortran-62 Reference Manual for details on the use of formats.
A format is treated as a string. Formats will be written, for example, as follows:
'(6E20.10)'
'(1H0, 9X, 5HTABLE, I3)' .
Note that the parentheses are part of the format, and both parentheses and string quotes are required.
As will be indicated below, a format string may appear explicitly in an INPUT or OUTPUT statement. If the same format string is used more than once, however, it may be convenient to give it a name through a format declaration. A format declaration has the form
format Identifier := '(Fortran format)' .
Examples are:
format F := '(6E20.10)'
format G := '(1H0, 9X, 5HTABLE, I3)' .
A format declaration obeys the same rules of syntax and scope as do other declarations.
Format identifiers may be used as parameters, and format is a specifier.
INPUT
The INPUT procedure is used to input numbers and Hollerith information in accordance with Fortran-type formats. An INPUT statement has one of the forms
INPUT (M,F,list)
INPUT (M,F)
where:
(1) M is the logical unit designation. M may be any arithmetic expression. If it is not integral-valued, the action
M := entier (M + 0.5)
will take place. The standard input unit is 50.
(2) F is a format expression. It may be an actual format string, a format identifier, a conditional format expression, or any variable which contains the starting address of a format string. Caution. In the case of a conditional format expression, format strings and format identifiers should not be mixed. For example, (a) and (b) below are permitted, but (c) will cause an incorrect program to be compiled:
(a) if B then '(E20.7)' else '(E20.6)' (b) if B then F1 else F2 (c) if B then F1 else '(E20.6)' .
(3) list is as defined previously. Of course, for INPUT all expressions must be variables.
The following are examples of an INPUT statement:
INPUT (50, '(4E20.8)', N, for I := 1 step 1 until N do A[I]).
INPUT (if A < B then M else N, F, X, Y, Z) .
Each INPUT statement causes at least one card image to be read.
Note that the INPUT procedure does not make type checks between the data and the program variables. A floating point number, for example, is stored as such regardless of the type of the variable to which it is assigned.
Caution. It is strongly recommended that not both READ and INPUT be used in the same program. Each buffers ahead one card image. Furthermore, each INPUT statement causes at least one card image to be read while a READ statement may not cause a new card image to be read. Mixing the two statements will require quite careful use of blank cards in the data to allow for the buffering.
OUTPUT
The OUTPUT procedure is used to output numbers and Hollerith information in accordance with Fortran-type formats. An OUTPUT statement has one of the forms
OUTPUT (M,F) OUTPUT (M,F,list)
where M, F, and list are as indicated above. The following are examples of OUTPUT statements:
OUTPUT (51, '(5HTABLE)')
OUTPUT (51, '(1H0,9X,10E10.2)', for I := 1 step 1 until 100 do A[I]) .
Each OUTPUT statement causes at least one line printer image to be put out. The standard output unit is 51, and the standard punch unit is 52.
Intermediate Tape Procedures
There are five standard procedures for making use of magnetic tape for auxiliary storage:
BINREAD, BINWRITE, ENDFILE, REWIND and BACKUP.
BINREAD
A BINREAD statement has the form
BINREAD (M, list)
where M and list are the same as for INPUT. Each BINREAD statement causes the designated unit to move forward one logical record, reading in binary format into the variables of the list. If fewer variables appear in the list than are on the record, only those values are read and the tape moves on to the end of the record. If more variables appear in the list than are on the record, this is treated as an error and the program is terminated.
The following is an example of a BINREAD statement:
BINREAD (6, for I := 1 step 1 until 1000 do A[I]) .
BINWRITE
A BINWRITE statement has the form
BINWRITE (M, list)
where M and list are the same as for OUTPUT. Each BINWRITE statement causes the values of the list expressions to be written in one logical record in binary format on the designated unit.
ENDFILE
An ENDFILE statement has the form
ENDFILE (M)
where M is a unit designation as before. The statement causes an end-of-file record to be written on the designated unit.
REWIND
A REWIND statement has the form
REWIND (M)
where M is a unit designation as before. The statement causes the designated unit to be rewound to the load point.
BACKUP
A BACKUP statement has the form
BACKUP (M)
where M is a unit designation as before. The statement causes the designated unit to be backspaced one logical record of binary information or one physical record of BCD information.
Tape-Checking Procedures
The checking procedures are: EOF, READERR, and WRITERR. These are Boolean procedures.
EOF
An EOF call has the form
EOF (M)
where M is a logical unit designation as before. It yields the value true if the previous read operation encountered an end-of-file or the previous write operation encountered an end-of-tape; otherwise it yields the value false.
An example of the use of an EOF call is:
if EOF(6) then goto ALARM .
READERR
A READERR call has the form
READERR (M)
where M is a logical unit designation as before. It yields the value true if the previous read operation produced a parity error; otherwise it yields the value false.
READERR should not be used for testing the operation of a READ statement. The READ procedure has its own facilities for checking, making multiple attempts in case of errors, and terminating the program if necessary.
WRITERR
A WRITERR call has the form
WRITERR (M)
where M is a logical unit designation as before. It yields the value true if the previous write operation produced a parity error; otherwise it yields the value false.
V. The External Declaration