# Designators

An identifier is a writable designator if it is declared as a variable, is a `VAR` or `VALUE` parameter, is a local of a `TYPECASE` or `TRY EXCEPT` statement, or is a `WITH` local that is bound to a writable designator. An identifier is a readonly designator if it is a `READONLY` parameter, a local of a `FOR` statement, or a `WITH` local bound to a non-designator or readonly designator.

The only operations that produce designators are dereferencing, subscripting, selection, and `SUBARRAY`. This section defines these operations and specifies the conditions under which they produce designators. In unsafe modules, `LOOPHOLE` can also produce a designator.

`r^`

> denotes the the referent of `r`; this operation is called dereferencing. The expression `r^` is always a writable designator. It is a static error if the type of `r` is `REFANY`, `ADDRESS`, `NULL`, an object type, or an opaque type, and a checked runtime error if `r` is `NIL`. The type of `r^` is the referent type of `r`.

`a[i]`

> denotes the `(i + 1 - FIRST(a))`-th element of the array `a`. The expression `a[i]` is a designator if `a` is, and is writable if `a` is. The expression `i` must be assignable to the index type of `a`. The type of `a[i]` is the element type of `a`.

> An expression of the form `a[i_1, ..., i_n]` is shorthand for `a[i_1]...[i_n]`. If `a` is a reference to an array, then `a[i]` is shorthand for `a^[i]`.

`r.f, o.f, I.x, T.m, E.id`

> If `r` denotes a record, `r.f` denotes its `f` field. In this case `r.f` is a designator if `r` is, and is writable if `r` is. The type of `r.f` is the declared type of the field.

> If `r` is a reference to a record, then `r.f` is shorthand for `r^.f`.

> If `o` denotes an object and `f` names a data field specified in the type of `o`, then `o.f` denotes that data field of `o`. In this case `o.f` is a writable designator whose type is the declared type of the field.

> If `I` denotes an imported interface, then `I.x` denotes the entity named `x` in the interface `I`. In this case `I.x` is a designator if `x` is declared as a variable; such a designator is always writable.

> If `T` is an object type and `m` is the name of one of `T`'s methods, then `T.m` denotes the `m` method of type `T`. In this case `T.m` is not a designator. Its type is the procedure type whose first argument has mode `VALUE` and type `T`, and whose remaining arguments are determined by the method declaration for `m` in `T`. The name of the first argument is unspecified; thus in calls to `T.m`, this argument must be given positionally, not by keyword. `T.m` is a procedure constant.

> If `E` is an enumerated type, then `E.id` denotes its value named `id`. In this case `E.id` is not a designator. The type of `E.id` is `E`.

`SUBARRAY(a: Array; from, for: CARDINAL): ARRAY OF ElemType(a)`

> `SUBARRAY` produces a subarray of `a`. It does not copy the array; it is a designator if `a` is, and is writable if `a` is. If `a` is a multi-dimensional array, `SUBARRAY` applies only to the top-level array.

> The operation returns the subarray that skips the first `from` elements of `a` and contains the next `for` elements. Note that if `from` is zero, the subarray is a prefix of `a`, whether the type of `a` is zero-based or not. It is a checked runtime error if `from+for` exceeds `NUMBER(a)`.

> Implementations may restrict or prohibit the `SUBARRAY` operation for arrays with packed element types.

    Last modified on Wed Apr  3 09:39:09 PST 1996 by heydon
         modified on Mon Apr 18 14:02:39 PDT 1994 by kalsow