Subsections

Quaternaries

Quaternaries are assignments, routine denotations, identity relations and SKIP. Of the four, the assignment is the most common. An assignment consists of three parts. The left-hand side must be a tertiary. It is usually an applied identifier or, less commonly, an enclosed clause. Its value must be a name. Its context is soft, so no dereferencing is allowed unless a cast is used (see the next chapter), but deproceduring is allowed. The second part is the assignment token. The right-hand side (the third part) can be any quaternary (including, of course, another assignment). Its context is strong so any coercion is permitted. The mode of its value must contain one less REF than the mode of the left-hand side.

The right-hand side of an assignment is, most commonly, a formula which is a tertiary (all tertiaries are quaternaries, but not vice-versa). The left-hand side can also be a formula provided that the value yielded is a name (which is the case with the assigning operators--see section 5.1.2). If an assignment is to be used as a primary, a secondary or a tertiary, then it must be enclosed in parentheses(or BEGIN and END). The value of an assignment is the value of the left-hand side: that is, it is a name. Assignments were discussed in chapter 5.

Routine denotations were discussed in chapter 6.

SKIP yields an undefined value of any mode and can only occur in a strong context. It is particularly useful in the following case. Consider the procedure

   PROC p=(REAL a,b)REAL:
   IF b=0
   THEN print(("Division by zero",newline)):
      stop;  SKIP
   ELSE a/b
   FI

Because the yield has mode REAL, and the ELSE part of the conditional clause yields a value of mode REAL, by the principle of balancing (see below) the THEN part also must yield a value of mode REAL. Now the construct stop yields a value of mode VOID which cannot be coerced to REAL in any context. If the procedure is going to compile successfully, the THEN part must yield REAL (or, at least, a value which can be coerced to REAL in the context of the body of the procedure which is strong) even though the value yielded will never be used (because the stop will terminate the program). The SKIP will yield an undefined value of mode REAL. Although SKIP must occur in a strong context, it cannot be coerced.

Another use for SKIP is in row- or structure-displays where not all the units are known at the time of a declaration. For example:

   [3]INT ii:=(4,?,5)

Before the multiple ii is used, the second element should be given a value. If no such value is assigned, and you try to print the value of ii[2] the a68toc compiler will generate code which will print whatever value was there at the time the multiple was generated, which may well be rubbish.

The identity relation is discussed in the next chapter, but its grammar has important consequences. The identity relation consists of two tertiaries separated by an identity relator (one of :=: or :/=:). Since a formula is a tertiary, it can safely be included in an identity relation. For example, given the declarations

   INT x:=3, y:=1;
   PROC x or y = (REAL r)REF INT: (r<0.5|x|y)

the identity relation

   x or y(random) :=: x

is legal. However, if you want to include an identity relation in a formula then you must surround it with parentheses to make it into a tertiary, as in

   IF (x or y(random) :=: x) AND x*y > 0
   THEN

Since one side of an identity relation is in a soft context while the other is in a strong context, only one side of an identity relation can be strongly-dereferenced. The soft side can be weakly-dereferenced which means that one REF will always be left on that side. Balancing applies to identity relations (see the discussion in section 11.6).

This completes the general discussion of units.


Exercises

10.10
What kind of units are each of the following: Ans[*]
(a)
A cast.

(b)
An applied-identifier.

(c)
A selection.

(d)
A multiple.

(e)
A name.

(f)
A formula.

(g)
A loop clause.

(h)
An assignment.

(i)
A declaration.

(j)
A procedure denotation.

10.11
Which units are to be found in each of the following: Ans[*]
(a)
3.5 * (a - 2 * x)

(b)
p OR q AND a = 4

(c)
sin(x)

(d)
a[3,2:4]

(e)
x:=(c<"e"|2.4|-y)

(f)
(i|x,y,z):=(p|2|-4)

(g)
PAR(x:=1.2,y:=3.6)


Sian Mountbatten 2012-01-19