An identity declaration with the form:
c part 1 c amode defining_identifier = unit; c part 2 c
Introduces the identifier defining_identifier in the current
range and ascribes a copy of the value yielded by unit to it.
Once established, the relationship between an identifier and the value
ascribed to it is constant and it cannot change during the reach of
the identifier. The ascribed unit can be any unitary clause, and its
elaboration can be arbitrarily complicated. In particular, it is not
required to be a compile-time constant. amode determines
the mode of the value yielded by the unit, and the unit is elaborated
in a strong context.
An identity declaration like the above, where amode is not
a procedure mode (See Procedure Identity Declarations) is lowered
into:
VAR_DECL with name defining_identifier, type
CTYPE (amode) and initial value amode(skip)
that gets chained into the declarations list of the current block.
DECL_EXPR that gets prepended in the current statement’s list.
MODIFY_EXPR setting the VAR_DECL to a copy of the
lowering of unit, a68_low_dup (unit).
Schematically:
BIND_EXPR (BLOCK (DECLS: ... -> VAR_DECL (defining_identifier, INITIAL=SKIP)))
STMT_LIST
|
+-- DECL_EXPR (defining_identifier)
|
| c part 1 c
|
+-- MODIFY_EXPR (defining_identifier, unit)
|
| c part 2 c
|
The reason why the VAR_DECL is initialized to skip
and then set to the initial unit specified in the source line
is that the Report specifies that Algol 68 identifiers can be used
before they are defined provided we are in the right range, but in
that case the value ascribed to the identifier is “undefined”.
Accessing an “undefined” value in traditional Algol 68
implementations would lead to a run-time error (these implementations
used a special value to denote undefined, such as F00L) but in
GNU Algol 68 the “undefined” value is always skip which,
if not terribly useful in most cases, is at least well defined in this
implementation and doesn’t lead to an error.
Identity declarations are the Algol 68 way of defining constants, and
one may wonder why we are not using CONST_DECL instead of
VAR_DECL. The reason is that CONST_DECL is really only
intended for integral values in C enums, and the amode in
the identity declaration can really be any mode, from simple integers
or characters to fairly complicated structured modes, which may
involve also rows and united modes. Whether the VAR_DECL will
lead to allocating storage on the stack depends on the nature of the
mode and the way the identifier is used in the program: whether its
address is taken, etc.