Let's look at ALGOL W in more detail, focusing on the differences compared to ALGOL 60.
ALGOL W is free format and case insensitive, though the convention was to have keywords in lower case and identifiers
Like_This. Identifiers can be up to 255 characters long.
Keywords are reserved words so no stropping is required. A standard EBCDIC character set is used so there is no need for a different reference and hardware representation.
As well as the comment syntax from ALGOL 60, comments can be started with
% and then terminated with either
The final statement in a program or separately compiled unit (ie the last
end) should end with a period.
% This is an ALGOL W program % begin integer Population_Count; end.
New data types
As well as the existing types from ALGOL 60 such as real and integer, ALGOL W provides long real, complex, bit and proper string types:
begin complex C; bits B; string(50) S; c := 1 + 2I; b := #0000010F; s := "Hello, world"; end.
Bit values are padded to 32 bits. String variables have to be declared with their length, such as 50 above; if the length is not provided the default is 16.
div does integer division and
rem yields the remainder after division. As well as the logical operators like
and, there are also
shr for bitwise left and right shifts.
begin write(#1 shl 2); write(42 rem 20); end.
The above will print #00000004 and 2.
Records and references
Records group together simple variables like a struct in C. References can point to records but not fundamental types. A reference can be initialised, at which point memory for the record is allocated. After initialisation, fields can be accessed by field(variable).
begin record Person(integer Age; real Height; string(40) Name); reference(Person) P, Q; P := Person(30,, "N Wirth"); Q := Person; Age(Q) := 42; write(Name(P)); write(Age(Q)); end.
Note for the initialisation of
P we leave
Height uninitialised, and although memory for Q is allocated it is not initialised at all. This example will print "N Wirth" and 42.
References can be used to point at records but not fundamental types.
null can be used to refer to an non-existent record. So a simple linked list could be defined as below, which will print 20.
begin record List(integer Data; reference(List) Next); reference(List) L; L := List(10, null); Next(L) := List(20, null); write(Data(Next(L))); end.
A reference can point to more than one type of record; which one can be determined at run time with the
begin record A(real Aa); record B(integer Bb); reference(A, B) R, S; R := A(3.0); S := B(4); S := R; if S is A then write("Got an A") else write("Got a B"); end.
The above will print "Got an A". I think there is no garbage collector, so the memory allocated for the B is leaked.
As well as the three types of
for statements from ALGOL 60, ALGOL W has a
while statement. The below will print 256.0
begin real X; X := 2.0; while X < 100 do begin X := X * X; end; write(X); end.
case allows switching by integer value; the below will print "Two". Note there is no default case, so if J < 1 or > 4 there will be a runtime error.
begin integer J; string(10) Word; J := 2; Word := case J of ("One", "Two", "Three", "Four"); write(Word); end.
The syntax for procedures differs from ALGOL 60 as types and calling conventions are specified in the function header:
begin real procedure Fn(real X; integer value Y); begin X * Y end; write(Fn(3.0, 2)); end.
The default calling convention, as used in the above, is by name, but
*ALGOLW will give you a warning suggesting you use another convention instead.
value after the type means pass by value. There is a new calling convention,
result, which is for pass-out variables.
value results allows both pass-in and pass-out without the side effects of pass by name.
begin procedure P1(integer value A; integer result B; real value result C); begin A := 10; B := A; C := C + A end; integer A, B; real C; A := 1; B := 2; C := 3.0; P1(A, B, C); write(A, B, C); end.
The above will display 1, 10, 13.
Input/Output and library
There's an extensive input/output library that has been customised for MTS.
Basic input/output allows reading and writing each from a single channel. The below program will expect input formatted like this:
1001 "Niklaus" "Wirth" Inventor of ALGOL W
begin integer ID; string(20) First, Last; string(80) Description; read(ID); readon(First, Last); readcard(Description); end.
More complex formatting and carriage control can be specified. There is also support for reading/writing to more than one channel, and indexed access.
The standard library contains mathematical functions and access to operating system information like time and date.
MTS volume 16 describes the language and the MTS extensions in detail.
Another introduction to the language can be found at everything2.