Identity Declarations (GNU Algol 68 Compiler Internals)

### 3.1 Identity Declarations ¶

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:

- A `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.
- A `DECL_EXPR` that gets prepended in the current statement’s list.
- A `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.