IBM 360 ALGOL 60

This example is the IBM 360 version of ALGOL 60. This implementation of ALGOL 60 is much harder to read than the other example on this site. All keywords must be enclosed in single quotes, and all comparison operators must be specified as keywords as in the line:

'IF' I 'LESS' 1000 'THEN'

Strings must be surrounded by the character sequences '(' and ')'. Square brackets are replaced with (/ and /).

The I/O implementation is one of the worst I have ever seen. There are input and output functions for the different types of data which are reasonably understandable, but there are also the INLABEL and the OUTLABEL functions that I can't figure out at all. The documentation and examples of these functions are more or less incomprehensible. I think you have to run them to figure them out.

The SYSACT function must be used for many different things. The second operand determines its function. 6 is "Assign record length to an unopened dataset," 8 is "Assign a page length to an unopened dataset," 12 is "Open" (not really needed) and 14 is "Skip to a new line." (And you thought that \n was cryptic!) The first operand of SYSACT determines the dataset to which the action applies. These numbers range from 0-15 and must correspond to JCL DD statements named ALGLDD01 through ALGLDD15, except for 0 which corresponds to SYSIN. The third operand should be self-evident, except for action 14, in which the operand is the number of extra blank lines plus 1. So to leave zero blank lines you use 1, to leave 1 blank line you use 2, and so forth.

The canned JCL for the ALGOL compiler is incorrect. It assigns ALGLDD01 to SYSOUT, but the run-time code attempts to open ALGLDD01 for both input and output, which is an error for SYSOUT data sets. The work datasets for the compiler are assigned to tape drives (I didn't correct this) and the SYS1.ALGLIB is incomplete on the turnkey MVS 3.8j system. In particular the load module IHIERROR is missing, so when you have a run-time error you get an 809 abend and have to guess what the error is.

Note that ALGOL 60 does not have a WHILE statement. The WHILE keyword exists, but is used differently. A correct use of the while keyword can be seen in the following statement.

'FOR' K := K 'WHILE' K 'LESS' 1000 'DO'

This corresponds to the while statement "while (k<1000)" the value preceding the 'WHILE' keyword is an expression that is assigned to the control variable K each time the loop iterates. A self-assignment was used here to make the FOR loop act like a typical while statement. Another way to do the same thing is to use a dummy variable like this.

'FOR' DUMMY := 1 'WHILE' <condition> 'DO'

I have included the JCL in the example because this program will not run with the default JCL. This code runs correctly on the Hercules emulator running the MVS 3.8j Turnkey system.

//ALGOL601 JOB //JOBLIB DD DSN=SYS1.ALGLIB,DISP=SHR //SALGOL EXEC ALGOFCLG //ALGOL.SYSIN DD * 'BEGIN' 'COMMENT' ////////////////////////////////////////////////////////// // NAME: PETER M. MAURER // PROGRAM: SIEVE OF ERATOSTHENES // DUE: NEVER // LANGUAGE: ALGOL 60 ALA IBM 360 ////////////////////////////////////////////////////////// ; 'COMMENT' DEFINE THE SIEVE DATA STRUCTURE ; 'INTEGER' 'ARRAY' CANDIDATES(/0..1000/); 'INTEGER' I,J,K; 'COMMENT' SET LINE-LENGTH=120,SET LINES-PER-PAGE=62,OPEN SYSACT(1,6,120); SYSACT(1,8,62); SYSACT(1,12,1); 'COMMENT' 1000 TO PROTECT AGAINST STRICT EVALUATION OF AND ; 'FOR' I := 0 'STEP' 1 'UNTIL' 1000 'DO' 'BEGIN' 'COMMENT' EVERYTHING IS POTENTIALLY PRIME UNTIL PROVEN OTHERWISE ; CANDIDATES(/I/) := 1; 'END'; 'COMMENT' NEITHER 1 NOR 0 IS PRIME, SO FLAG THEM OFF ; CANDIDATES(/0/) := 0; CANDIDATES(/1/) := 0; 'COMMENT' START THE SIEVE WITH THE INTEGER 0 ; I := 0; 'FOR' I := I 'WHILE' I 'LESS' 1000 'DO' 'BEGIN' 'COMMENT' ADVANCE TO THE NEXT UN-CROSSED OUT. ; 'COMMENT' THIS NUMBER MUST BE A PRIME; 'FOR' I := I 'WHILE' I 'LESS' 1000 'AND' CANDIDATES(/I/) 'EQUAL' 0 'DO' 'BEGIN' I := I+1; 'END'; 'COMMENT' INSURE AGAINST RUNNING OFF THE END; 'IF' I 'LESS' 1000 'THEN' 'BEGIN' 'COMMENT' CROSS OUT ALL MULTIPLES OF THE PRIME.; J := 2; K := J*I; 'FOR' K := K 'WHILE' K 'LESS' 1000 'DO' 'BEGIN' CANDIDATES(/K/) := 0; J := J + 1; K := J*I; 'END'; 'COMMENT' ADVANCE TO THE NEXT CANDIDATE ; I := I+1; 'END' 'END'; 'COMMENT' ALL UNCROSSED OUT NUMBERS ARE PRIME; 'COMMENT' PRINT ALL PRIMES ; 'FOR' I := 0 'STEP' 1 'UNTIL' 999 'DO' 'BEGIN' 'IF' CANDIDATES(/I/) 'NOTEQUAL' 0 'THEN' 'BEGIN' OUTINTEGER(1,I); OUTSTRING(1,'(' IS PRIME')'); SYSACT(1,14,1) 'END' 'END' 'END' /* //GO.ALGLDD01 DD DSN=&&DD01,UNIT=SYSDA,DISP=(,PASS),SPACE=(CYL,20), 00200000 // DCB=(RECFM=FBA,LRECL=121,BLKSIZE=605) 00210000 //GO.SYSPRINT DD DSN=&&SYSP,UNIT=SYSDA,DISP=(,PASS),SPACE=(CYL,20), 00220000 // DCB=(RECFM=FBA,LRECL=121,BLKSIZE=605) 00230000 //PTPCH01 EXEC PGM=IEBPTPCH,COND=(0,NE,SALGOL.GO) 00240000 //SYSPRINT DD DUMMY 00250000 //SYSIN DD * 00260000 PRINT PREFORM=A 00270000 /* 00280000 //SYSUT1 DD DSN=&&SYSP,DISP=(OLD,PASS) 00290000 //SYSUT2 DD SYSOUT=A 00300000 //PTPCH02 EXEC PGM=IEBPTPCH,COND=(0,NE,SALGOL.GO) 00310000 //SYSPRINT DD DUMMY 00320000 //SYSIN DD * 00330000 PRINT PREFORM=A 00340000 /* 00350000 //SYSUT1 DD DSN=&&DD01,DISP=(OLD,PASS) 00360000 //SYSUT2 DD SYSOUT=A 00370000 //

Click Here for the actual code.