TOPS-10: Algol 60

This week it's time to look at the Algol 60 compiler on TOPS-10. This was a supported product from DEC that integrates with the standard COMPILE/EXEC system. Files should have an extension of .ALG to be automatically recognised as Algol

As with every Algol compiler, there are several implementation dependent features to deal with issues like character set and for unspecified facilities like I/O.

Single pass compiler

The compiler needs only a single pass over the source code, which makes it fast, but does mean that functions used before they are defined are flagged as errors. A non-standard keyword FORWARD was added to work around this, so you can say FORWARD REAL PROCEDURE x; and then define x later in the program.

Source format and special characters

This version of Algol does not require keywords to be quoted (eg FOR vs 'FOR' ), but if you have programs already using quoted keywords you can add the /Q switch to the COMPILE command to accept this. Periods are allowed in identifiers to improve readability.

Some additional characters are used to represent language features which are implementation dependent

  • := for left arrow assignment
  • # for not equals to
  • ^ for exponentiation
  • @ or & for floating point exponents
  • ! for comments

There are two special forms for constants. Octal constants are introduced by a leading %, eg %770. ASCII constants - ie a single word of memory containing up to 5 ASCII characters - start with a $ and the constant surrounded by the user's choice of delimiter, for r example $/ABC/.

Strings

TOPS-10 Algol adds a string type, which is implemented as a pointer to a character array internally.

    STRING S, T;
    S := "HELLO WORLD";
    T := S;

Here S and T would point to the same byte array in memory. If instead the last line was T := COPY(S); then T would point to its own string.

Square brackets inside double quotes are used to incorporate special characters, for example "HELLO[N]" would print HELLO and a carriage return/new line.

Input/Output

I/O is not part of the Algol spec, so all this is implementation dependent. The basic output functions are WRITE for character data and PRINT for numeric data. READ is used to input data based on the type of parameter.

By default, I/O goes to the user's typewriter. You can select other places by using INPUT or OUTPUT to define a channel, eg INPUT(5, "CDR"); will define input channel 5 as going to the card reader. You then need to do SELECTINPUT(5) to direct all future input via READ to come from this channel. This facility also allows input and output for disk files.

Other language extensions

  • There is a LONG REAL type for additional floating point precision.
  • Procedures can be marked as EXTERNAL and linkage to other languages is allowed.
  • While loops, eg WHILE X < 10 DO X := X + 1;.
  • Variables can be declared as OWN, which has similar semantics to C's static variables, ie their lifetime continues when the block they are defined in is exited.

Running TPK

Let's use the compiler to run the TPK algorithm. The source code can be found here. This can be loaded onto the disk using the techniques described in this article.

.type tpk.alg
BEGIN
    COMMENT TPK ALGORITHM IN ALGOL 60;

    REAL PROCEDURE FN(X);
    VALUE X;
    REAL X;
    BEGIN
        FN := SQRT(ABS(X)) + 5*X^3
    END PROCEDURE;

    COMMENT Main program;
    INTEGER N, J;
    REAL ARRAY A[1:11];
    N := 11;
    COMMENT Read numbers;
    FOR J := 1 STEP 1 UNTIL N DO
        READ(A[J]);
    WRITE("RESULTS ARE[N]");
    FOR J := N STEP -1 UNTIL 1 DO
    BEGIN
        REAL RESULT;
        RESULT := FN(A[J]);
        IF RESULT > 400.0 THEN
            WRITE("TOO LARGE")
        ELSE
            PRINT(RESULT);
        WRITE("[N]");
    END LOOP;
END PROGRAM

.exec tpk.alg
ALGOL: TPK
12  NO DECLARATION SHOULD FOLLOW PROCEDURE OR SWITCH DECLARATION
LINK:	Loading
[LNKXCT TPK Execution]
10
-1
1
2
3
4
4.3
4.305
4.303
4.302
4.301
RESULTS ARE
 3.9988630&  2
TOO LARGE
TOO LARGE
TOO LARGE
 3.9960864&  2
 3.2200000&  2
 1.3673205&  2
 4.1414214&  1
 6.0000000
-4.0000000
TOO LARGE


End of execution.

Note the warning that the declaration of INTEGER N, J; should not follow the procedure declaration. This is not something that other Algol compilers have picked up and it may be due to the single pass nature of the compiler mentioned earlier.

In the output section, numbers are printed with the mantissa and exponent separated by a space, eg 3.9960864& 2 means 399.60864.

Further information

On Bitsavers there's an Algol manual from 1974. The tape image from 1978 that was the source of this compiler has a readme on trailing-edge.

Questions, corrections, comments

I welcome any questions or comments, and also especially any corrections if I have got something wrong. Please email me at rupert@timereshared.com and I will add it here and update the main text.