
Enumerations, subranges, sets, arrays of arrays, records and WITH - all of the Turbo course's S17 to S20 is here, and most of it works as you learned it. This section is the differences: one rule stricter than you are used to, one check that is on where Turbo's was off, one that is off altogether, and one thing missing.
An enumerated type works with ORD, SUCC, PRED, comparisons and FOR, and - as in Turbo - it cannot be written: WRITE of one is an error (19 here). SUCC of the last value is not caught, as in Turbo without {$R+}.
Sets are the same shape as Turbo's: at most 256 values, IN, +, -, <=, =, and [] for the empty set. A set of 0..300 is refused.
Arrays of arrays accept both G[2,3] and G[2][3]. Records, WITH, and assigning one record to another all work.
In Turbo you could assign one array to another of the same type. HiSoft Pascal is particular about what "the same type" means. Two arrays are the same type only if they come from the same declaration. These cannot be assigned to each other:
VAR A:ARRAY[1..3] OF INTEGER;
B:ARRAY[1..3] OF INTEGER;
A:=B is error 10, though they look identical. These can:VAR A,B:ARRAY[1..3] OF INTEGER;
and so can any two variables declared with the same named type, even in separate declarations. The habit that keeps you out of trouble is the one S8 started: give every array and record type a name under TYPE, and declare everything with the name.
Array indexes are checked, without being asked. An index past either end stops the program with Index too High or Index too Low - where Turbo, without {$R+}, let the write land on whatever was next in memory. The check can be turned off with (*$A-*). Leave it on: without it, one write past the end of an array can throw the whole program out into the Einstein's monitor - a line of register values and a > prompt - and the only way back is to restart the Einstein.
Subranges are not checked at all. A field declared 1..99 will take 100 without a murmur - from a constant or a variable. Keep your own eye on them, as you did in Turbo without {$R+}.
Records with variants - the CASE inside a RECORD - are refused.
A shelf of three items, each a record with a name, a set of colours and a count:
10 PROGRAM SHELF;
20 TYPE COLOUR=(RED,GREEN,BLUE);
30 ITEM=RECORD
40 NAME:ARRAY[1..5] OF CHAR;
50 HUES:SET OF COLOUR;
60 COUNT:1..99
70 END;
80 SHELVES=ARRAY[1..3] OF ITEM;
90 VAR S,T:SHELVES; I:INTEGER; C:COLOUR;
100 BEGIN
110 S[1].NAME:='PAINT'; S[1].HUES:=[RED,BLUE];
120 S[1].COUNT:=4;
130 S[2].NAME:='CHALK'; S[2].HUES:=[GREEN];
140 S[2].COUNT:=12;
150 S[3].NAME:='INK '; S[3].HUES:=[];
160 S[3].COUNT:=1;
170 T:=S;
180 S[1].COUNT:=9;
190 FOR I:=1 TO 3 DO WITH T[I] DO
200 BEGIN
210 WRITE(NAME,COUNT:3,' ');
220 FOR C:=RED TO BLUE DO
230 IF C IN HUES THEN WRITE(ORD(C));
240 WRITELN
250 END
260 END.
Line 170 copies the whole shelf in one go; line 180 then changes the original, not the copy.
Starting from
SHELF.ASC saved from XBAS; HPEIN SHELF.
What you should see
PAINT 4 0 2
CHALK 12 1
INK 1
The paint's count is still 4: T is a copy. The numbers after each count are the colours in its set - 0 for red, 2 for blue.
90 VAR S:SHELVES; T:ARRAY[1..3] OF ITEM; and add 95 I:INTEGER; C:COLOUR;. Where does the compiler object?3 to 4. What happens after the third line?S[1].COUNT:=100;. COUNT only goes to 99. Is anything said?WRITE(ORD(C)) to WRITE(C). Will it compile?11.1 Add a fourth colour, WHITE, and give the ink a set with it in. What else in the program must change?
11.2 Write a procedure that takes a SHELVES and prints how many items have blue in their set.
Worked solutions are in Appendix II.
| Symptom | Cause |
|---|---|
*ERROR* 10 assigning one array to another that looks the same | They were declared separately. Give the type a name and use it for both. |
Index too High or Index too Low | An index past the end of an array - caught, where Turbo would have let it through. |
| A value outside its subrange | Subranges are not checked. Check it yourself. |
*ERROR* 19 | An enumerated value was written. Write ORD of it, or a CASE of names. |
Errors from a CASE inside a RECORD | Variant records are not available. |
Enumerations, sets, arrays and records work as in Turbo. Two arrays can be assigned only if they share a declaration or a type name - so name your types. Array indexes are checked without asking; subranges are not checked at all. There are no variant records.
S12, Files - text files only, named when they are opened, with no Close - and one thing that goes wrong when you read them.