To specify the typechecking of assignment statements we need to define ``assignable'', which is a relation between types and types, between expressions and variables, and between expressions and types.
A type T is assignable to a type U if:
T <: U, or
U <: T and T is an array or a reference type other than
ADDRESS (This restriction is lifted in unsafe modules.), or
T and U are ordinal types with at least one member in
common.
An expression e is assignable to a variable v if:
e is assignable to the type of v, and
e is a member of the type of v, is not a
local procedure, and if it is an array, then it has the same shape as
v.
The first point can be checked statically; the others generally require runtime checks. Since there is no way to determine statically whether the value of a procedure parameter is local or global, assigning a local procedure is a runtime rather than a static error.
An expression e is assignable to a type T if e is assignable to
some variable of type T. (If T is not an open array type, this
is the same as saying that e is assignable to any variable of type
T.)
An assignment statement has the form:
v := e
where v is a writable designator and e is an expression
assignable to the variable designated by v. The statement sets
v to the value of e. The order of evaluation of v and
e is undefined, but e will be evaluated before v is
updated. In particular, if v and e are overlapping subarrays,
the assignment is performed in such a way that no element is used as a target
before it is used as a source.
Examples of assignments:
VAR
x: REFANY;
a: REF INTEGER;
b: REF BOOLEAN;
a := b; (* static error *)
x := a; (* no possible error *)
a := x (* possible checked runtime error *)
The same comments would apply if x had an ordinal type with
non-overlapping subranges a and b, or if x had an object
type and a and b had incompatible subtypes. The type
ADDRESS is treated differently from other reference types, since a
runtime check cannot be performed on the assignment of raw addresses. For
example:
VAR
x: ADDRESS;
a: UNTRACED REF INTEGER;
b: UNTRACED REF BOOLEAN;
a := b; (* static error *)
x := a; (* no possible error *)
a := x (* static error in safe modules *)
m3-support@elego.de