The Oak Ridge ALGOL Compiler for the Control Data Corporation 1604 Preliminary Programmer's Manual
Part 2
An external declaration is required for each nonstandard library procedure or procedure compiled separately from the calling program, whether in Algol, Fortran or CODAP. Standard Algol procedures are described in Section VI. Note that a CODAP subroutine must take account of the special structure of the Algol calling sequence as described in Appendix C or be treated as a Fortran subprogram. The use of Fortran subprograms is described in Appendix G.
The external declaration has one of the following forms:
external I1, ..., In real external I1, ..., In integer external I1, ..., In Boolean external I1, ..., In
where each Ik is an identifier and n is any positive integer. A type declarator preceding the declarator external signifies a function procedure having that type. Note that no information about parameters appears in an external declaration. See Appendix A for syntactical definition.
In the ALGO mode, LIB cards must be included in the job deck for nonstandard library routines, in addition to the external declarations. Details are found in Section VIII.
VI. Standard Procedures
Certain procedures are used without being declared. These include the standard functions listed in the Algol 60 report and the input-output and intermediate tape procedures. The complete list is as follows:
ABS SIGN SQRT SIN COS ARCTAN LN EXP ENTIER EOF READERR WRITERR FORTRANF FTNF READ PAGE PRINT WRITE PUNCH INPUT OUTPUT BINREAD BINWRITE ENDFILE REWIND BACKUP FORTRAN FTN
These procedures are global to the program. They behave as though declared in a fictitious block surrounding the entire program.
VII. Error Checking and Diagnostics
In a complete compilation the compiler makes two passes on the Algol source program. If errors which the compiler cannot correct are detected in the first pass, then the second, or translation, pass will not be made. The following types of errors are detected:
1. syntactical error 2. undeclared identifier 3. identifier declared twice in the same block head 4. misspelled delimiter (corrected in many cases) 5. missing escape symbol (corrected unless both are missing for the same delimiter, in which case the delimiter is treated as an identifier).
The program listing and any diagnostics always appear on the standard output medium. In the case of a syntactical error, a message will appear in the program listing one or several lines below the error. The location of the error in the program will be further pinpointed in the line of symbols immediately below the error message. This line will be a short portion of the program with the last symbol in the line being the one which indicates the error. For example, a declaration might be out of place as follows:
. . . x := a + b; 'INTEGER' K;
**** LAST CHARACTER INDICATES SYNTACTICAL ERROR.
x := a + b; INTEGER . . .
In some cases the line below the message may differ slightly from the corresponding string of symbols above; for example, an identifier might be rendered by Ident. It is possible for a single syntactical error to cause more than one diagnostic.
A few syntactical errors are corrected by the compiler, and a message is put out to this effect. An example is a semicolon immediately preceding else.
According to the comment conventions of Algol, any string of symbols following end and not containing end, else or a semicolon is treated as comment. As a result, the omission of one of these symbols following end does not always cause an error in compilation but will cause a portion of the program to be skipped over by the compiler. Thus for example, in
... x := a + b end for i := 1 step 1 ...
the FOR statement will be skipped at least in part. The compiler will put out a caution message in this and some other cases, but it will not change the program.
If an identifier is not declared (or possibly declared in the wrong place), a message is put out below the program listing together with the undeclared identifier.
The compiler does not check the type of identifiers. Therefore, such errors as a Boolean variable in an arithmetic expression, or the brackets of a subscripted variable replaced by parentheses, are not detected, and an incorrect program may be compiled.
VIII. Running Programs
The Algol program is punched on cards in the hardware representation described in Appendix B. The format is essentially free field: spaces have no significance except within escape symbols and string quotes. Only the first 72 columns, however, are interpreted by the compiler. The remaining columns may be used for identification purposes. Care must be taken when a string is continued onto the next card, as the continuation will begin in column 1. The program listing will have the same format as the cards.
In the following discussion the symbol Ø signifies the letter O where necessary for emphasis, and the symbol Δ signifies a 7-9 punch in card column 1.
ALGOL Control System
The compiler operates under the ALGOL Control System. This system is a subordinate control routine of the Master Control System of the CO-OP Monitor Programming System. ALGOL is quite similar to the subordinate control routine COOP.
ALGOL is called with an MCS (Master Control System) card having ALGOL punched beginning in column 2. Other details of this card are available in descriptions of the CO-OP Monitor. It should be noted in selecting a standard recovery procedure that the concept of COMMON is not used in Algol.
Following the MCS card will be a control card giving instructions to the control routine ALGOL. It will name one of the following routines: ALGO, ALDAP, EXECUTE, BINARY, FORTRAN, REWIND or DEFINE. These will be discussed below.
EOP Card
The EOP (end-of-program) card has the characters 'EØP' punched in columns 10-14.
In the ALGO mode, one EOP card must be used to terminate the program.
In the ALDAP mode, one EOP card must be used to terminate each Algol program or Algol procedure being compiled separately.
Compile and Execute: ALGO
The ALGO mode of running an Algol program is the simplest and the fastest. It will be the more suitable for a large number of programs. Unless the programmer has special reasons for using the ALDAP mode, the ALGO mode is recommended.
The Algol program must be self-contained except for standard procedures and library procedures on the library-systems tape. The job deck must have the following cards in the specified order:
1. MCS control card.
The subordinate control routine name must be ALGØL. 2. ALGOL control card.
This will appear as
ΔALGØ. or ΔALGØ,t. where t is an integer specifying a time limit in minutes for compilation and execution.
(The period is required on every control card.) 3. LIB cards.
If necessary. One LIB card is required for each non-standard library procedure called in the program, namely those declared external. The format of a LIB card is as follows: the characters LIB punched in columns 10-12 and the name of a library entry point beginning in column 20. There may be no more than 20 LIB cards. 4. PROGRAM card.
If desired. This may be used to identify the program. Its format is described in the next paragraph. 5. Algol program deck. 6. EOP card. 7. Data.
If required.
PROGRAM Card
The PROGRAM card is optional. It is useful for identification purposes, and in the ALDAP mode it serves to name the program entry point.
The format of the card is free field. The characters PRØGRAM must appear followed by the program name, which must be alphanumeric.
Compile/Execute: ALDAP
The ALDAP mode is used to compile an Algol program or procedure to a relocatable binary or a CODAP format. Execution is optional. For compilation only, the program deck may consist of any mixture of Algol programs and procedures, any number of which may be in CODAP. If execution is desired, part or all of the program deck may have been previously compiled, so that the deck may have Algol, CODAP and relocatable binary cards.
ALDAP Control Statement
The format of the ALDAP statement is:
ΔALDAP,L,B,n.
where
L is a program listing key,
B is a punched card output key,
n is a logical unit number.
A period may terminate the statement at any point, with remaining fields treated as zero.
If the program listing key (L) is a 1, an assembled listing of the CODAP object code will be produced on the standard output medium. If the key is zero or blank, no such listing will be produced. A listing of the Algol program and any diagnostics will always be produced on the standard output medium.
If the punched card output key (B) is a 1, a relocatable binary deck will be produced on the standard punch medium. If the key is a 2, a CODAP symbolic deck will be produced on the standard punch medium. If the key is a 3, both a symbolic deck and a relocatable binary deck will be produced on the standard punch medium, with the symbolic deck appearing first. If the key is zero or blank, no deck will be produced.
The logical unit number (n) specifies the unit which is to be the load-and-go tape if it is one of the integers 1-49 or 56. If n is some other integer or blank, no load-and-go tape will be written. The load-and-go tape is required when execution of the program is to follow.
Examples:
(a) ΔALDAP, 1, 1, 56.
This statement will cause the Algol/CODAP deck to be compiled, an assembled listing to be produced on the standard output medium, a relocatable binary deck to be produced on the standard punch medium, and a load-and-go tape written on logical unit 56.
(b) ΔALDAP, 1.
This statement will cause the Algol/CODAP deck to be compiled, and an assembled listing to be produced on the standard output medium.
Job Deck: ALDAP Compilation/Execution
For compilation only of an Algol/CODAP program deck, the job deck should contain the following cards in the specified order:
1. MCS control card.
With ALGØL as the subordinate control routine name. 2. ALGOL control card.
With the appropriate ALDAP control statement. 3. PROGRAM card.
If desired. 4. Program deck.
Any mixture of Algol and CODAP programs and procedures, with all their subroutines except the standard procedures and those on the library-systems tape. Each Algol program or procedure must be terminated by an EOP card. 5. FINIS card.
This card contains the characters FINIS punched in columns 10-14. It signals the end of all compilations.
For compilation and execution of an Algol/CODAP program deck, a load-and-go tape must be requested in the ALDAP control statement. If no relocatable binary cards follow the last subprogram to be compiled, then the program deck must be terminated by an EOP card which is in addition to the EOP card or END card (the latter for a CODAP subprogram) which terminates the last program or procedure. The FINIS card then follows this additional EOP card. An EOP card always causes a TRA card image to be written on the load-and-go tape.
The control statements EXECUTE, BINARY, FORTRAN, REWIND and DEFINE may be used as described in the “CO-OP Monitor Programmer’s Guide”. BINARY is useful for loading a relocatable binary deck onto the load-and-go tape prior to compilation of an Algol calling program, where the subprogram in relocatable form might have the same name as a library routine. If the Algol program preceded the relocatable deck, the library routine would be fetched by the loader and an error indication given.
The CO-OP control statements LOAD and EXECUTER are not used by ALGOL.
Examples
Each of the following examples describes a job deck which illustrates a different way of compiling and executing the same Algol program. The program calls a library procedure with entry point named BESSEL, and the program contains at least one other procedure. On the MCS card only the first field is indicated, as the others may vary from one installation to another.
Example 1
This job uses the ALGØ mode.
ΔALGØL, ... .
ΔALGØ.
LIB BESSEL
PRØGRAM SAMPLE
Algol Program (with external declaration of BESSEL)
'EØP'
Data
Example 2
This job uses the ALDAP mode, compiling the entire program at once. The ALDAP control statement calls for an assembled listing, a binary deck, and a load-and-go tape on logical unit 56. The execute card gives a two minute time limit on the execution.
ΔALGØL, ... .
ΔALDAP,1,1,56.
PRØGRAM SAMPLE
Algol Program (with external declaration of BESSEL)
'EØP'
'EØP'
FINIS
ΔEXECUTE,2.
Data
Example 3
This job consists simply of the execution of the relocatable program deck obtained in example 2.
ΔALGØL, ... .
ΔEXECUTE,2.
Relocatable Deck
Data
Example 4
This example is similar to example 2. Here the main program and one of its procedures are to be compiled separately.
ΔALGØL, ... .
ΔALDAP,1,1,56.
PRØGRAM SAMPLE
Algol Program (with external declaration of both BESSEL and the procedure being compiled separately)
'EØP'
Algol Procedure
'EØP'
'EØP'
FINIS
ΔEXECUTE,2.
Data
Example 5
In this example the procedure which was compiled separately in example 4 is being compiled by itself, i.e., the calling program is not in the deck at all. Of course there is no execution in this case. Note that no load-and-go tape is requested and only one EOP card is used. There cannot be a PROGRAM card.
ΔALGØL, ... .
ΔALDAP,1,1.
Algol Procedure
'EØP'
FINIS
Example 6
Here the procedure compiled by itself in example 5 appears in the program deck in relocatable binary form, while the calling program is in the Algol language.
ΔALGØL, ... .
ΔALDAP,1,1,56.
PRØGRAM SAMPLE
Algol Program (with external declaration of both BESSEL and the procedure in relocatable form)
'EØP'
FINIS
ΔEXECUTE,2.
Relocatable Deck
Data
The relocatable deck here must be terminated by two TRA cards. One of these is generated by the compiler when it processes the EOP card which must terminate the procedure for compilation, as in example 5. The second TRA card can be obtained by using a second EOP card, as in example 2. Alternatively, the second TRA card can be added to the relocatable deck before execution. Note that this second TRA card must not be used when the relocatable deck is loaded by a BINARY control statement. This is illustrated in the next example.
Example 7
In this case the previously compiled procedure has the same name as a routine on the library-systems tape.
ΔALGØL, ... .
ΔBINARY,56.
Relocatable Deck (terminated by one TRA card)
ΔALDAP,1,1,56.
PRØGRAM SAMPLE
Algol Program (with external declaration of both BESSEL and the procedure in relocatable form)
'EØP'
'EØP'
FINIS
ΔEXECUTE, 2.
Data
The logical unit number on the BINARY control statement must agree with that which specifies the load-and-go tape in the ALDAP control statement.
APPENDIX A Adjuncts to Algol 60
List Entities
The delimiter list is a declarator and a specifier.
::=
::= | | ( )
::= | |
::= | ,
::= list :=
Format Entities
The delimiter format is a declarator and a specifier.
::=
::='( [2])' |
::= | else
::= format :=
String Expression
::= | else
External Declaration
The delimiter external is a declarator.
::=
::= | ,
::= external | external
APPENDIX B Hardware Representation
One keypunch character is reserved as an “escape symbol”, which we shall here suppose is the apostrophe. This symbol is used to delineate word delimiters and truth values, which are written in boldface type in Algol reference language and publication language and indicated by underlining in this manual. The hardware representation of a word delimiter such as begin is therefore 'BEGIN'. No distinction is made between upper and lower case letters in the hardware language.
The transliteration rules for the non-word delimiters are comprised in the following table. This assumes a 48 character hardware set and is consistent with the usage in the ALCOR group. For some basic symbols alternatives are tolerated, as indicated.
Reference Hardware Tolerated Hardware < 'LS' 'LESS' ≤ 'LQ' 'LSEQ', 'NOTGREATER', 'NOT GREATER' = 'EQ' 'EQUAL' ≥ 'GQ' 'GREQ', 'NOTLESS', 'NOT LESS' > 'GR' 'GREATER' ≠ 'NQ' 'NTEQ', 'NOTEQUAL', 'NOT EQUAL' ¬ 'NOT' ∧ 'AND' ∨ 'OR' ⊃ 'IMP' 'IMPLIES', 'IMPL' ≡ 'EQV' 'EQUIV' ₁₀ ' 'E','T' × * ↑ ** 'POWER' ÷ // 'DIV' : .. ; $ ., := = .=, ..= [ (/ ] /) ‘ " '(' ’ " ')'
In the case of the string quotes, the tolerated symbols are required for the inner strings of a nest of strings.
Actually, the compiler can tolerate many other spellings of word delimiters because of its facility for correcting misspellings.
The delimiter go to is accepted with or without the space between the two words, but it is treated as a single delimiter: 'GOTO' or 'GO TO'.
The compiler can also accept a 64 character hardware representation: the full set available on the line printer. In preparing programs, overpunching is used on the 48 character keypunch in this case. The table below indicates the keypunching rules in use at Oak Ridge National Laboratory.
Reference Hardware < 1-8 punch ≤ 1-5 punch ≥ 1-9 punch > 2-7 punch ≠ 2-6 punch ∧ 3-7 punch ∨ 2-4 punch ₁₀ 1-6 punch ↑ 2-5 punch ÷ 3-5 punch : 2-8 punch ; 2-9 punch [ 3-6 punch ] 3-4 punch
The other basic symbols are either in the 48 character set or are replaced by word delimiters as above. The symbol := is treated as two symbols in the 64 character set, and = is punched as such.
APPENDIX C Structure of Procedure Calling Sequence
The following information is necessary for the user writing a non-Algol procedure to be called from an Algol program. The calling sequence differs from that found in many other languages.
The first word of the non-Algol procedure must have a simple jump instruction in its upper half, and the exit line is provided by a jump to this first word. The entry automatically causes the proper return address to be placed in the address portion of the first half-word.
Upon entry to the procedure, index register six contains an address which is used to reference each parameter. To establish linkage with the first parameter, the instruction
LDA 6 0
is performed. This brings into the accumulator a word of one of the following types:
1. SLJ 0 ENA V 2. SLJ 0 RTJ L
In case (1), V is the address of the parameter. In case (2), L is the starting address of a piece of coding for computing the address of the parameter and leaving it in the accumulator (if the parameter is an expression, the address in the accumulator will be that of a temporary containing its value). Case (1) always holds if the parameter is a simple variable, string, array identifier, switch identifier, or procedure identifier. In case (2) the same temporary will be used for all the expressions.
Both cases can be provided for by setting aside two locations for each parameter in the procedure body and placing the instruction
SLJ *-1
in the upper half of each second location. Then after
LDA 6 0
mentioned above,
STA RES1,
where RES1 is the first reserved location for the first parameter, makes the two locations into a closed subroutine. After this, the instruction
RTJ RES1
causes the address of the first parameter to be placed in the accumulator anytime it is performed. This accommodates expressions called by name.
In general, the K^th parameter is referenced as above, but beginning with
LDA 6 (K - 1).
This description does not apply to the standard procedures, each of which has its own special calling sequence.
APPENDIX D Internal Representation of Strings
The address representing a string is that of the first word of string characters. Each left string quote is represented internally by the word
00 ... 03454 ,
and each right string quote by
00 ... 05474 .
The characters of the string which are not string quotes are packed in BCD eight characters per word. These words are in the natural order, the first immediately following the left string quote and the last immediately followed by the right string quote. If the last word before a right quote is not full, the rest of that word is filled out with zeros (not BCD blanks).
APPENDIX E Program Efficiency
The following information may be of interest to programmers desiring an efficient program:
1. The FOR statement is defined with more generality than is useful in most programs. In particular, the arithmetic expressions in the FOR clause are allowed to change in value during execution of the FOR statement. The compiler does not attempt to determine which FOR statements make use of this flexibility and treats all of them in the most general way. Therefore, in a statement such as
for I := 1 step M + N until abs(A - B) do ... ,
the expression M + N is evaluated twice for each iteration, and the expression abs(A - B) is evaluated once for each iteration. If M, N, A , and B do not change in the loop, this is unnecessary. Such inefficiency can be avoided by programming in a slightly different way. The above example can be written as follows:
T1 := M + N; T2 := abs(A - B) ; for I := 1 step T1 until T2 do ... .
2. The concept of call by value is a device applied to procedures to eliminate unneeded flexibility in procedure calls. If a parameter having a value is referenced more than once in the procedure body and the flexibility of call by name is not needed, then the program is more efficient if the parameter is included in the value part of the procedure heading. If such a parameter is referenced only once, it is more efficient if it is not included in the value part.
3. Array identifiers which are parameters should be specified.
APPENDIX F Controversial Features of Algol 60