Ex
11.1
PROGRAM ex11 1 CONTEXT VOID
USE standard
BEGIN
[]CHAR digits =
"0123456789abcdef"[@0];
PROC itostr = (INT n,r#adix#)STRING:
IF n<r
THEN digits[n]
ELSE itostr(n%r,r)+digits[n%*r]
FI;
print(("Table of numbers 0--15",
newline,newline,
"Dec. Hex. Binary",newline));
FOR i FROM 0 TO 15
DO
STRING bin = itostr(i,2),
dec = itostr(i,10),
hex = digits[i];
#only one digit#
print(((4-UPB dec)*blank,
dec,3*blank,hex,
4*blank,(4-UPB bin)*"0",
bin,newline))
OD
END
FINISH
Ex
11.2
| 9410 | =5×161+14×160 |
| =5e16 |
| 1310 | =1×23+×22+0×21+1×20 |
| =11012 |
| 1111 10012 | = | f916 |
| 3e116 | = | 3×162 + e×161 +1×160 | |
| = | 3×256 + 14×16 + 1 | ||
| = | 768 + 224 + 1 | ||
| = | 99310 |
| 101012 | = | 1×24 +1×22 +1×20 | |
| = | 16 + 4 + 1 | ||
| = | 2110 |
Ex
11.3
Ex
11.4
16r 0101 0101
16r 99bb ddff
16r 6745 2301
FALSE
Ex
11.5
16r 558
16r 17
Ex
11.6
PROC transpose=(REF[,]INT m)VOID:
IF 1 UPB m - 1 LWB m
=
2 UPB m - 2 LWB m
THEN #m is square#
REF[,]INT mm=m[@1,@1]; #a precaution#
FOR i TO 1 UPB mm - 1
DO
REF[]INT mr=mm[i,i+1:],
mc=mm[i+1:,i];
[]INT temp=mr;
mr:=mc; mc:=temp
OD
FI
Ex
11.7REF REAL(xx):=120.5
Ex
11.8REF REF[]CHAR rrq; []CHAR m = "ABCDEFGHIJ"; rrq:=LOC REF[]CHAR:=LOC[10]CHAR:=m[@1];
Ex
11.9REF FLEX[]INT rfi; rfi:=FLEX[1:0]INT:=(3,-2,4)
Ex
11.10f has the
mode REF STRING and ss has the mode
REF REF STRING.
Ex
11.11STRING whose value is "Joan of Arc".
Ex
11.12f[3:4]=s[7:8]. The modes are both STRING.
Ex
11.13REF STRING(ff) IS ss ff IS REF STRING(ss) REF STRING(ff) IS REF STRING(ss)You could also use
ISNT, :=: or :/=:.
Ex
11.14
REF REF FILE.
TRUE BOOL.
REF FILE.
FALSE BOOL.
Ex
11.15
REF FILE
REF REF FILE
Ex
11.16
REF REF QUEUE(tail):=
LOC QUEUE:=(("Barbara",3),nilq)
Ex
11.17tail:=next OF tail
Ex
11.18
Ex
11.19
PROC add fan=(REF REF REF QUEUE
head,tail,
REF FAN fan)VOID:
tail:=next OF (REF REF QUEUE
(head IS nilq|head|tail):=
HEAP QUEUE:=(fan,nilq))
Ex
11.20
PROGRAM ex11 20 CONTEXT VOID
USE standard
BEGIN
MODE FAN = STRUCT(STRING name,
INT ticket),
QUEUE = STRUCT(FAN fan,
REF QUEUE next);
REF QUEUE nilq = NIL;
PROC add fan=(REF REF REF QUEUE
head,tail,
REF FAN fan)VOID:
tail:=next OF
(REF REF QUEUE
(head IS nilq|head|tail)
:=HEAP QUEUE
:=(fan,nilq);
REF REF QUEUE head,tail;
head:=tail:=LOC REF QUEUE:=nilq;
FOR q TO 1000
DO
add fan(head,tail,
LOC FAN:=(IF ODD q
THEN "Iain"
ELSE "Fiona"
FI,
q))
OD
END
FINISH
The generator LOC FAN is used because add fan
requires a parameter of mode REF FAN. The scope of the
generated name is from the declarations of head and
tail to the end of the program because there are no identity
declarations in the FOR loop clause (therefore it is not a
range).
Ex
11.21marker has mode
REF REF QUEUE, it is made to refer to each REF QUEUE
name in the linked-list. The condition
next OF marker ISNT nilqensures that
marker is not currently referring to the last
REF QUEUE in the list. The loop will terminate when
marker refers to the last REF QUEUE in the list or the
number of the ticket of the fan to be inserted in the queue does not
exceed the number of the ticket of the fan referred to by
marker.
If the operator AND had been used, both operands would have been
elaborated before the operator; in which case, if the left operand
had yielded FALSE, elaboration of the right operand would have
caused the run-time error "Selection from NIL".
Ex
11.22
PROGRAM ex11 22 CONTEXT VOID
USE standard
BEGIN
MODE FAN = STRUCT(STRING name,
INT ticket),
QUEUE = STRUCT(FAN fan,
REF QUEUE next);
REF QUEUE nilq = NIL;
PROC insert fan = . . .
. . .
PROC print queue = . . .
. . .
REF REF QUEUE head,tail;
head:=tail:=LOC REF QUEUE:=nilq;
INT max ticket = 1000;
INT tickets issued:=0;
[max ticket]BOOL ticket issued;
FOR i
FROM LWB ticket issued
TO UPB ticket issued
DO FALSE OD;
WHILE tickets issued < max ticket
DO
INT i=random int(max ticket);
IF REF BOOL ti=ticket issued[i];
NOT ti
THEN
ti:=TRUE;
insert fan(head,tail,HEAP FAN:=
((ODD i
|"Iain"
|"Fiona"
),i));
tickets issued+:=1
FI
OD #fans added to the queue#;
print queue(head)
END FINISH
Instead of sending the output to stand out, it would be
better to direct it to an output book so that the results could be
examined at leisure. Alternatively, command line redirection could
be used. The use of ticket issued ensures that unique ticket
numbers are added to the queue since insert fan does not cater
explicitly for duplicate ticket numbers.
Ex
11.23
PROC delete fan=(REF REF QUEUE q,
INT t#icket#
)UNION(REF FAN,BOOL):
IF q IS nilq
THEN FALSE #empty queue#
ELIF next OF q IS nilq
THEN #last fan in the queue#
IF ticket OF q = t
THEN REF FAN rf = q;
q:=nilq; #delete last fan#
rf
ELSE FALSE
FI
ELIF ticket OF next OF q < t
THEN delete fan(next OF q,t)
ELIF ticket OF next OF q > t
THEN #not found# FALSE
ELSE REF FAN rf = next OF q;
next OF q:=next OF next OF q;
rf
FI #delete fan#;
In the assignment, the mode of next OF q is REF
REF QUEUE, so the mode of next OF next OF q must
be REF QUEUE. Look at the required dereferencing to see
what is assigned to next OF q.
Ex
11.24
PROGRAM ex11 24 CONTEXT VOID
USE standard
BEGIN
MODE
LETTER=STRUCT(CHAR c,INT o),
TREE=STRUCT(REF LETTER l,
REF TREE left,right);
REF TREE leaf=NIL;
REF TREE root:=leaf;
PROC get letter=(REF FILE f)
REF LETTER:
IF CHAR ch; get(f,ch);
ch>="A" & ch<="Z"
OR
ch>="a" & ch<="z"
THEN HEAP LETTER:=(ch,1)
ELSE get letter(f) #skip non-letters#
FI #get letter#;
PROC add letter=
(REF REF TREE root,
REF LETTER let)VOID:
IF root IS leaf
THEN root:=HEAP TREE:=(let,leaf,leaf)
ELIF c OF l OF root > c OF let
THEN add letter(left OF root,let)
ELIF c OF l OF root < c OF let
THEN add letter(right OF root,let)
ELSE o OF l OF root+:=1
FI #add letter#;
FILE inf, arg;
STRING in bk;
INT max row=13;
[max row,81]CHAR out page;
INT row:=max row, col:=0;
FOR i TO max row
DO
out page[i,:80]:=80*blank;
out page[i,81]:=lf
OD #initialise out page#;
INT num letters:=0;
PROC put letter=(REF LETTER let)VOID:
BEGIN
IF row=max row
THEN col+:=1; row:=1
ELSE row+:=1
FI;
FILE f;
establish(f,
"",
mem channel,
1,1,20);
put(f,(c OF let,
fixed(o OF let/
num letters*100,
-7,2),blank*12));
out page[row,(col-1)*20+1:col*20]
:=file buffer(f);
close(f)
END #put letter#;
PROC print tree=
(REF REF TREE root)VOID:
IF root ISNT leaf
THEN
print tree(left OF root);
IF o OF l OF root > 0
THEN put letter(l OF root)
FI;
print tree(right OF root)
FI #print tree#;
IF open(arg,"",arg channel)/=0
THEN
put(stand error,
("Cannot access arguments",
newline));
stop
ELIF
on logical file end(arg,
(REF FILE f)BOOL:
(put(stand error,
("Usage: tt in-book",
newline)); stop; SKIP));
get(arg,(LOC STRING,
LOC CHAR,
in bk));
open(inf,
in bk,
stand in channel)/=0
THEN
put(stand error,
("Cannot open book ",in bk,
newline));
stop
ELSE
on logical file end(inf,
(REF FILE f)BOOL:
(
print tree(root);
print((
"Frequency of occurrence ",
"of letters in the book ",
idf(f),newline,
newline,out page,newline,
"Total letters read: ",
whole(num letters,0),
newline));
stop; SKIP
))
FI;
FOR i TO 26 #letters in the alphabet#
DO
add letter(
root,
HEAP LETTER:=
(REPR(ABS("A")-1+i),0));
add letter(
root,
HEAP LETTER:=
(REPR(ABS("a")-1+i),0))
OD #all letters are now in the tree#;
DO
add letter(root,get letter(inf));
num letters+:=1
OD
END
FINISH