Subsections

The value NIL

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
In a soft context, these modes become:
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.


Exercises

11.14
Given the declarations
   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[*]
(a)
cur file:=f2

(b)
cur file :/=: stand in

(c)
p:=f1

(d)
p:=:f1

11.15
Given the declarations of exercise 1, what is the mode of NIL in Ans[*]
(a)
cur file:=NIL

(b)
REF REF FILE ff:=NIL


Sian Mountbatten 2012-01-19