Sometimes it is desirable that a name of mode REF
REF whatever should not refer to a definite
name (see, for example, the discussion of queues below). This can be
arranged by making it refer to NIL which
is the only denotation of a name. The mode of NIL is
REF whatever. For example, consider
REF[]CHAR rc=NIL; REF INT ri=NIL
The first NIL has the mode REF[]CHAR and the second has
the mode REF INT.
Given the declaration
REF INT xx:=NIL
the mode of NIL is REF INT. However, although
NIL is a name, you cannot assign to it. That is, the
assignment
REF INT(xx):=4
would cause the run-time error
Segmentation fault
and, possibly, a memory dump, when using the a68toc compiler.
Nor can you use NIL in a formula if that would involve
dereferencing. The only use of NIL is for determining,
by using an identity relation, that a name refers to it. However, we
shall see in the sections on queues and trees that this is a vital
function.
Now consider the declaration
REF REF INT rrri;
where the mode of rrri is REF REF REF INT. We could make
rrri refer to NIL directly using the
assignment
rrri:=NIL
whence the mode of NIL is REF REF INT. Or
we could use a NIL of mode REF INT by using
an anonymous name:
rrri:=LOC REF INT:=NIL
whence the mode of the anonymous name is REF REF INT.
In the identity relation
rrri IS NIL
how can we tell which NIL is in use? Of course, we
could use a cast for rrri, but there is a simpler and
more useful way. Firstly we declare
REF INT nil ri = NIL
then balancing will ensure that the identity relation
rrri IS nil ri
gives the required answer with rrri being dereferenced
twice. Alternatively, with the declaration
REF REF INT nil rri = NIL
we can ensure that the identity relation
rrri IS nil rri
will also be elaborated correctly. We shall see in the sections on
queues and trees that the declaration of nil ri is more
useful.
Now consider the declarations
INT x:=ENTIER(random * 6), y; REF INT xx,yy; PROC x or y = REF INT: (random>0.8|x|y)
and the identity relation
CASE randint(3) IN xx,x or y, NIL ESAC
IS
CASE y IN x, SKIP, yy ESAC
The balancing of the identity relation includes balancing of the case clauses. The modes yielded are
xx |
REF REF INT |
|
x or y |
PROC REF INT |
|
NIL |
REF whatever |
|
x |
REF INT |
|
SKIP |
who knows? | |
yy |
REF REF INT
|
REF REF INT |
|
REF INT |
|
REF whatever |
|
REF INT |
|
| who knows? | |
REF REF INT
|
Thus the left-hand side is the soft context and the right-hand side
(of the identity relation) is the strong context (remember that
SKIP is only allowed in a strong context), and the final
modes are all REF INT. In practice, it is rare that
identity relations are so complicated.
FILE f1:=stand in, f2;
REF FILE cur file:=f2;
PROC p = REF FILE:
(cur file IS f1|f1|f2)
what is the value of Ans
cur file:=f2
cur file :/=: stand in
p:=f1
p:=:f1
NIL in Ans
cur file:=NIL
REF REF FILE ff:=NIL
Sian Mountbatten 2012-01-19