Primaries are denotations, applied identifiers, casts, calls and
slices. We have met denotations in chapters
1, 4 and 6. Only plain values, routines
and a special name (NIL
) have a denotation.
NIL
is dealt with in the section on tertiaries and the
mode BITS
is covered in chapter 11.
Applied-identifiers means identifiers being used in a context, rather
than in their declarations. We have met numerous examples of these.
Routine denotations are not primaries.
A cast consists of a mode indicant followed by an enclosed clause, usually a closed clause. Here is a formula with a cast:
3.4 * REAL (i)
where i
has mode INT
. The cast puts the
enclosed clause in a strong context. Thus, in the above formula, the
normal context of an operand is firm (see chapter 2), but the
cast causes the value of i
to be widened to a
REAL
. Casts are usually used in formulæ and identity
relations (see sections
10.8 and
11.6). Casts are sometimes used
to coerce a conditional or case clause where
balancing is insufficient to provide the mode
required (see section 10.9
later in this chapter). The mode indicant can be any mode and can
contain any of the mode-constructors such as REF
or
PROC
or []
(but it should not be a
generator, which is not a mode indicant). Care
should be taken when using a structured mode. For example, in this
formula,
3 * STRUCT(INT k)(4)
assuming that the operator has been declared for operands of modes
INT
and STRUCT(INT k)
, the cast must include the
field selector because it is part of the mode.
Calls were discussed in sections 6.3.1 and 6.3.2. Here is a simple example:
sqrt(0.7)
In this call, sqrt
is itself a primary (it is an
applied-identifier). In
section 10.2, it was
mentioned that the primary of a call is in a meek
context. This applies even if the call itself (as a
whole) is in a strong context. The primary of a call can be an
enclosed clause. For example,
(a>4|sqrt|sin)(x)
which yields sqrt(x)
if a > 4
and
sin(x)
otherwise. In this case, the primary is
(a>4|sqrt|sin)
We discussed slices in section 3.2. They include simple subscripting. For example, given the declaration
[,]INT r = ((1,2,3),(4,5,6))
the units r[1,]
and r[2,3]
are both
slices. Whatever the context of the slice, the context of the primary
of the slice (r
in these examples) is always
weak. This means that only weak-dereferencing is
allowed. Thus, given the phrases
[2,3]INT s:=r; INT p:=s[2,1]
the slice s[2,1]
is in a strong
context, but the s
is in a weak
context, so the name that s
identifies, which has the
mode REF[,]INT
will not be dereferenced, though the
slice, which has mode REF INT
, will be.
There is another consequence of the weak context of the primary of a slice: row-displays can only be used in a strong context. So if you want to change the bounds of a row-display, because the slicer will produce a weak context, the row-display must be enclosed in a cast.
The context of subscripts and bounds in trimmers is meek and they must be units.
All enclosed clauses are primaries, but not all primaries are enclosed clauses.
p
(mode REF[]REAL
) in []REAL (p[3])
q
(mode PROC(REAL)INT
) in REAL(q(0.5))
3 * (1.4 + r)/2**6
p:=sqrt(r) - 6
num:=x[3,ENTIER r]
i * []CHAR("e")
Sian Mountbatten 2012-01-19