If a TAG, id, is introduced by an identify, then the value bound is fixed by its definition argument. If, on the other hand, v was a TAG introduced by a variable definition, then the value bound to v is a pointer to fixed space in the procedure frame (i.e. the left-hand value in C).
Some languages give results to assignments. For example, C defines
the result of an assignment to be its right-hand expression, so that
if the result of (v = exp) was required, it would probably be expressed
as:
For example, the value assigned in assign has some fixed SHAPE; its
size is known at translate-time. Variable sized objects can be moved
by move_some:
The TRANSFER_MODE md parameter controls the way that the move
will be performed. If overlap is present, then the translator will
ensure that the move is equivalent to moving the source into new space
and then copying it to the destination; it would probably do this
by choosing a good direction in which to step through the value. The
alternative, standard_transfer_mode, indicates that it does not matter.
If the TRANSFER_MODE trap_on_nil is present and
arg1 is a nil pointer, a TDF exception with ERROR_CODE nil_access
is raised.
There are variants of both the contents and assign constructors. The
signature of contents_with_mode is:
Similar considerations apply to assign_with_mode; here the overlap
TRANSFER_MODE is also possible with the same meaning as in move_some.
This constraint means that producers cannot expect that arbitrary
bitfield lengths can be accomodated without extra padding; clearly
it also means that the maximum bitfield length possible is the maximum
size of integer variety that can be implemented on the translator
concerned (this is defined to be at least 32). On standard architectures,
the producer can expect that an array of bitfields of lenth 2n
will be packed without padding; this, of course, includes arrays
of booleans. For structures of several different bitfields, he can
be sure of no extra padding bits if the total number of bits involved
is less than or equal to 32; similarly if he can subdivide the bitfields
so that each of the subdivisions (except the last) is exactly equal
to 32 and the last is less than or equal to 32. This could be relaxed
to 64 bits if the translator deals with 64 bit integer varieties,
but would require that conditional TDF is produced to maintain portability
to 32 bit platforms - and on these platforms the assurance of close
packing would be lost.
Since a producer is ignorant of the exact representational varieties
used by a translator, the onus is on the translator writer to provide
standard tokens which can be used by a producer to achieve both optimum
packing of bitfields and minimum alignments for COMPOUNDs containing
them(see Bitfield offsets on page 54).
These tokens would allow one to construct an offset of the form OFFSET(x,
b) (where b is some bitfield alignment and x is the `minimum' alignment
which could contain it) in a manner analogous to the normal padding
operations for offsets. This offset could then used both in the construction
of a compound shape and in the extraction and assignment constructors.
The assignment of bitfields follows the same pattern with the same
constraints using bitfield_assign:
Part of the TenDRA Web.7.1. contents
In order to get the contents of this space (the right-hand value in
C), one must apply the contents operator to the pointer:
contents(shape(v), obtain_tag(v))
In general, the contents constructor takes a SHAPE and an expression
delivering pointer:
s: SHAPE
arg1: EXP POINTER(x)
-> EXP s
It delivers the value of SHAPE s, pointed at by the evaluation
of arg1. The alignment of s need not be identical to
x. It only needs to be included in it; this would allow one,
for example, to pick out the first field of a structure from a pointer
to it.7.2. assign
A simple assignment in TDF is done using assign:
arg1: EXP POINTER(x)
arg2: EXP y
-> EXP TOP
The EXPs arg1 and arg2 are evaluated (no ordering implied)
and the value of SHAPE y given by arg2 is put into the
space pointed at by arg1. Once again, the alignment of y
need only be included in x, allowing the assignment to the
first field of a structure using a pointer to the structure. An assignment
has no obvious result so its SHAPE is TOP.
identify(empty, newtag, exp,
sequence((assign(obtain_tag(v), obtain_tag(newtag))), obtain_tag(newtag)))
From the definition of assign, the destination argument, arg1,
must have a POINTER shape. This means that given the TAG id above,
assign(obtain_tag(id), lhs) is only legal if the definition
of its identify had a POINTER SHAPE. A trivial example would be if
id was defined:
identify(empty, id, obtain_tag(v), assign(obtain_tag(id), lhs))
This identifies id with the variable v which has a POINTER SHAPE,
and assigns lhs to this pointer. Given that id does not occur in lhs,
this is identical to:
assign(obtain_tag(v), lhs).
Equivalences like this are widely used for transforming TDF in translators
and other tools (see section 11 on page 48).7.3. TRANSFER_MODE operations
The TRANSFER_MODE operations allow one to do assignment and contents
operations with various qualifiers to control how the access is done
in a more detailed manner than the standard contents and assign operations.
md: TRANSFER_MODE
arg1: EXP POINTER x
arg2: EXP POINTER y
arg3: EXP OFFSET(z, t)
-> EXP TOP
The EXP arg1 is the destination pointer, and arg2 is
a source pointer. The amount moved is given by the OFFSET arg3.
md: TRANSFER_MODE
s: SHAPE
arg1: EXP POINTER(x)
-> EXP s
Here, the only significant TRANSFER_MODE constructors md are
trap_on_nil and volatile. The latter is principally intended to implement
the C volatile construction; it certainly means that the contents_with_mode
operation will never be "optimised" away.7.4. Assigning and extracting bitfields
Since pointers to bits are forbidden, two special operations are provided
to extract and assign bitfields. These require the use of a pointer
value and a bitfield offset from the pointer. The signature of bitfield_contents
which extracts a bitfield in this manner is:
v: BITFIELD_VARIETY
arg1: EXP POINTER(x)
arg2: EXP OFFSET(y,z)
-> EXP bitfield(v)
Here arg1 is a pointer to an alignment x which includes
v, the required bitfield alignment. In practice, x must
include an INTEGER VARIETY whose representation can contain the entire
bitfield. Thus on a standard architecture, if v is a 15 bit bitfield,
x must include at least a 16 bit integer variety; a 27 bitfield would
require a 32 bit integer variety and so on. Indeed the constraint
is stronger than this since there must be an integer variety, accessible
from arg1, which entirely contains the bitfield.
arg1: EXP POINTER(x)
arg2: EXP OFFSET(y,z)
arg3: EXP BITFIELD_VARIETY(v)
-> EXP TOP
Crown
Copyright © 1998.