2 |
7u83 |
1 |
<!-- Crown Copyright (c) 1998 -->
|
|
|
2 |
<HTML>
|
|
|
3 |
<HEAD>
|
|
|
4 |
<TITLE>Values, variables and assignments.</TITLE>
|
|
|
5 |
</HEAD>
|
|
|
6 |
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#400080" ALINK="#FF0000">
|
|
|
7 |
<A NAME=S61>
|
|
|
8 |
<H1>TDF Guide, Issue 4.0 </H1>
|
|
|
9 |
<A HREF="guide10.html">
|
|
|
10 |
<H3>January 1998</H3>
|
|
|
11 |
<IMG SRC="../images/next.gif" ALT="next section"></A>
|
|
|
12 |
<A HREF="guide8.html">
|
|
|
13 |
<IMG SRC="../images/prev.gif" ALT="previous section"></A>
|
|
|
14 |
<A HREF="guide1.html"><IMG SRC="../images/top.gif" ALT="current document"></A>
|
|
|
15 |
<A HREF="../index.html"><IMG SRC="../images/home.gif" ALT="TenDRA home page">
|
|
|
16 |
</A>
|
|
|
17 |
<IMG SRC="../images/no_index.gif" ALT="document index"><P>
|
|
|
18 |
<HR>
|
|
|
19 |
<DL>
|
|
|
20 |
<DT><A HREF="#S62"><B>7.1 </B> - contents</A><DD>
|
|
|
21 |
<DT><A HREF="#S63"><B>7.2 </B> - assign</A><DD>
|
|
|
22 |
<DT><A HREF="#S64"><B>7.3 </B> - TRANSFER_MODE operations</A>
|
|
|
23 |
<DD>
|
|
|
24 |
<DT><A HREF="#S65"><B>7.4 </B> - Assigning and extracting bitfields</A><DD>
|
|
|
25 |
</DL>
|
|
|
26 |
<HR>
|
|
|
27 |
<H1>7 Values, variables and assignments.</H1>
|
|
|
28 |
TAGs in TDF fulfil the role played by identifiers in most programming
|
|
|
29 |
languages. One can apply obtain_tag to find the value bound to the
|
|
|
30 |
TAG. This value is always a constant over the scope of a particular
|
|
|
31 |
definition of the TAG. This may sound rather strange to those used
|
|
|
32 |
to the concepts of left-hand and right-hand values in C, for example,
|
|
|
33 |
but is quite easily explained as follows. <P>
|
|
|
34 |
If a TAG, id, is introduced by an identify, then the value bound is
|
|
|
35 |
fixed by its <I>definition</I> argument. If, on the other hand, v
|
|
|
36 |
was a TAG introduced by a variable definition, then the value bound
|
|
|
37 |
to v is a pointer to fixed space in the procedure frame (i.e. the
|
|
|
38 |
left-hand value in C). <P>
|
|
|
39 |
<A NAME=S62>
|
|
|
40 |
<HR><H2>7.1. contents</H2>
|
|
|
41 |
In order to get the contents of this space (the right-hand value in
|
|
|
42 |
C), one must apply the contents operator to the pointer:<P>
|
|
|
43 |
<PRE>
|
|
|
44 |
contents(shape(v), obtain_tag(v))
|
|
|
45 |
</PRE>
|
|
|
46 |
In general, the contents constructor takes a SHAPE and an expression
|
|
|
47 |
delivering pointer:<P>
|
|
|
48 |
<PRE>
|
|
|
49 |
<I> s</I>: SHAPE
|
|
|
50 |
<I> arg1</I>: EXP POINTER(<I>x</I>)
|
|
|
51 |
-> EXP <I>s</I>
|
|
|
52 |
</PRE>
|
|
|
53 |
It delivers the value of SHAPE <I>s</I>, pointed at by the evaluation
|
|
|
54 |
of <I>arg1</I>. The alignment of <I>s</I> need not be identical to
|
|
|
55 |
<I>x</I>. It only needs to be included in it; this would allow one,
|
|
|
56 |
for example, to pick out the first field of a structure from a pointer
|
|
|
57 |
to it.<P>
|
|
|
58 |
<A NAME=S63>
|
|
|
59 |
<HR><H2>7.2. assign</H2>
|
|
|
60 |
A simple assignment in TDF is done using assign:<P>
|
|
|
61 |
<PRE>
|
|
|
62 |
<I> arg1</I>: EXP POINTER(<I>x</I>)
|
|
|
63 |
<I> arg2</I>: EXP <I>y</I>
|
|
|
64 |
-> EXP TOP
|
|
|
65 |
</PRE>
|
|
|
66 |
The EXPs <I>arg1</I> and <I>arg2</I> are evaluated (no ordering implied)
|
|
|
67 |
and the value of SHAPE <I>y</I> given by <I>arg2</I> is put into the
|
|
|
68 |
space pointed at by <I>arg1</I>. Once again, the alignment of <I>y</I>
|
|
|
69 |
need only be included in <I>x</I>, allowing the assignment to the
|
|
|
70 |
first field of a structure using a pointer to the structure. An assignment
|
|
|
71 |
has no obvious result so its SHAPE is TOP. <P>
|
|
|
72 |
Some languages give results to assignments. For example, C defines
|
|
|
73 |
the result of an assignment to be its right-hand expression, so that
|
|
|
74 |
if the result of (v = exp) was required, it would probably be expressed
|
|
|
75 |
as:<P>
|
|
|
76 |
<PRE>
|
|
|
77 |
identify(empty, newtag, exp,
|
|
|
78 |
sequence((assign(obtain_tag(v), obtain_tag(newtag))), obtain_tag(newtag)))
|
|
|
79 |
|
|
|
80 |
</PRE>
|
|
|
81 |
From the definition of assign, the destination argument, <I>arg1</I>,
|
|
|
82 |
must have a POINTER shape. This means that given the TAG id above,
|
|
|
83 |
assign(obtain_tag(id), lhs) is only legal if the <I>definition</I>
|
|
|
84 |
of its identify had a POINTER SHAPE. A trivial example would be if
|
|
|
85 |
id was defined: <P>
|
|
|
86 |
<PRE>
|
|
|
87 |
identify(empty, id, obtain_tag(v), assign(obtain_tag(id), lhs))
|
|
|
88 |
</PRE>
|
|
|
89 |
This identifies id with the variable v which has a POINTER SHAPE,
|
|
|
90 |
and assigns lhs to this pointer. Given that id does not occur in lhs,
|
|
|
91 |
this is identical to:<P>
|
|
|
92 |
<PRE>
|
|
|
93 |
assign(obtain_tag(v), lhs).
|
|
|
94 |
</PRE>
|
|
|
95 |
Equivalences like this are widely used for transforming TDF in translators
|
|
|
96 |
and other tools (see <A HREF="guide13.html#0">section 11 on page 48</A>).<P>
|
|
|
97 |
<A NAME=S64>
|
|
|
98 |
<HR><H2>7.3. <A NAME=8>TRANSFER_MODE operations</H2>
|
|
|
99 |
The TRANSFER_MODE operations allow one to do assignment and contents
|
|
|
100 |
operations with various qualifiers to control how the access is done
|
|
|
101 |
in a more detailed manner than the standard contents and assign operations.<P>
|
|
|
102 |
For example, the value assigned in assign has some fixed SHAPE; its
|
|
|
103 |
size is known at translate-time. Variable sized objects can be moved
|
|
|
104 |
by move_some:<P>
|
|
|
105 |
<PRE>
|
|
|
106 |
<I>md</I>: TRANSFER_MODE
|
|
|
107 |
<I>arg1</I>: EXP POINTER <I>x</I>
|
|
|
108 |
<I>arg2</I>: EXP POINTER y
|
|
|
109 |
<I>arg3</I>: EXP OFFSET(z, t)
|
|
|
110 |
-> EXP TOP
|
|
|
111 |
</PRE>
|
|
|
112 |
The EXP <I>arg1</I> is the destination pointer, and <I>arg2</I> is
|
|
|
113 |
a source pointer. The amount moved is given by the OFFSET <I>arg3</I>.
|
|
|
114 |
<P>
|
|
|
115 |
The TRANSFER_MODE<I> md</I> parameter controls the way that the move
|
|
|
116 |
will be performed. If overlap is present, then the translator will
|
|
|
117 |
ensure that the move is equivalent to moving the source into new space
|
|
|
118 |
and then copying it to the destination; it would probably do this
|
|
|
119 |
by choosing a good direction in which to step through the value. The
|
|
|
120 |
alternative, standard_transfer_mode, indicates that it does not matter.<P>
|
|
|
121 |
If the TRANSFER_MODE trap_on_nil is present and
|
|
|
122 |
<I>arg1</I> is a nil pointer, a TDF exception with ERROR_CODE nil_access
|
|
|
123 |
is raised.<P>
|
|
|
124 |
There are variants of both the contents and assign constructors. The
|
|
|
125 |
signature of contents_with_mode is:<P>
|
|
|
126 |
<PRE>
|
|
|
127 |
<I>md</I>: TRANSFER_MODE
|
|
|
128 |
<I>s</I>: SHAPE
|
|
|
129 |
<I>arg1</I>: EXP POINTER(<I>x</I>)
|
|
|
130 |
-> EXP s
|
|
|
131 |
</PRE>
|
|
|
132 |
Here, the only significant TRANSFER_MODE constructors <I>md</I> are
|
|
|
133 |
trap_on_nil and volatile. The latter is principally intended to implement
|
|
|
134 |
the C volatile construction; it certainly means that the contents_with_mode
|
|
|
135 |
operation will never be "optimised" away.<P>
|
|
|
136 |
Similar considerations apply to assign_with_mode; here the overlap
|
|
|
137 |
TRANSFER_MODE is also possible with the same meaning as in move_some.<P>
|
|
|
138 |
<A NAME=S65>
|
|
|
139 |
<HR><H2>7.4. <A NAME=16>Assigning and extracting bitfields</H2>
|
|
|
140 |
Since pointers to bits are forbidden, two special operations are provided
|
|
|
141 |
to extract and assign bitfields. These require the use of a pointer
|
|
|
142 |
value and a bitfield offset from the pointer. The signature of bitfield_contents
|
|
|
143 |
which extracts a bitfield in this manner is:<P>
|
|
|
144 |
<PRE>
|
|
|
145 |
<I>v</I>: BITFIELD_VARIETY
|
|
|
146 |
<I>arg1</I>: EXP POINTER(<I>x</I>)
|
|
|
147 |
<I>arg2</I>: EXP OFFSET(<I>y,z</I>)
|
|
|
148 |
-> EXP bitfield(<I>v</I>)
|
|
|
149 |
</PRE>
|
|
|
150 |
Here <I>arg1</I> is a pointer to an alignment <I>x</I> which includes
|
|
|
151 |
<I>v</I>, the required bitfield alignment. In practice, <I>x</I> must
|
|
|
152 |
include an INTEGER VARIETY whose representation can contain the entire
|
|
|
153 |
bitfield. Thus on a standard architecture, if v is a 15 bit bitfield,
|
|
|
154 |
x must include at least a 16 bit integer variety; a 27 bitfield would
|
|
|
155 |
require a 32 bit integer variety and so on. Indeed the constraint
|
|
|
156 |
is stronger than this since there must be an integer variety, accessible
|
|
|
157 |
from arg1, which entirely contains the bitfield. <P>
|
|
|
158 |
This constraint means that producers cannot expect that arbitrary
|
|
|
159 |
bitfield lengths can be accomodated without extra padding; clearly
|
|
|
160 |
it also means that the maximum bitfield length possible is the maximum
|
|
|
161 |
size of integer variety that can be implemented on the translator
|
|
|
162 |
concerned (this is defined to be at least 32). On standard architectures,
|
|
|
163 |
the producer can expect that an array of bitfields of lenth 2<I>n
|
|
|
164 |
</I>will be packed without padding; this, of course, includes arrays
|
|
|
165 |
of booleans. For structures of several different bitfields, he can
|
|
|
166 |
be sure of no extra padding bits if the total number of bits involved
|
|
|
167 |
is less than or equal to 32; similarly if he can subdivide the bitfields
|
|
|
168 |
so that each of the subdivisions (except the last) is exactly equal
|
|
|
169 |
to 32 and the last is less than or equal to 32. This could be relaxed
|
|
|
170 |
to 64 bits if the translator deals with 64 bit integer varieties,
|
|
|
171 |
but would require that conditional TDF is produced to maintain portability
|
|
|
172 |
to 32 bit platforms - and on these platforms the assurance of close
|
|
|
173 |
packing would be lost.<P>
|
|
|
174 |
Since a producer is ignorant of the exact representational varieties
|
|
|
175 |
used by a translator, the onus is on the translator writer to provide
|
|
|
176 |
standard tokens which can be used by a producer to achieve both optimum
|
|
|
177 |
packing of bitfields and minimum alignments for COMPOUNDs containing
|
|
|
178 |
them(see <A HREF="guide14.html#12">Bitfield offsets on page 54</A>).
|
|
|
179 |
These tokens would allow one to construct an offset of the form OFFSET(x,
|
|
|
180 |
b) (where b is some bitfield alignment and x is the `minimum' alignment
|
|
|
181 |
which could contain it) in a manner analogous to the normal padding
|
|
|
182 |
operations for offsets. This offset could then used both in the construction
|
|
|
183 |
of a compound shape and in the extraction and assignment constructors.<P>
|
|
|
184 |
The assignment of bitfields follows the same pattern with the same
|
|
|
185 |
constraints using bitfield_assign:<P>
|
|
|
186 |
<PRE>
|
|
|
187 |
<I>arg1</I>: EXP POINTER(<I>x</I>)
|
|
|
188 |
<I>arg2</I>: EXP OFFSET(<I>y,z</I>)
|
|
|
189 |
<I>arg3</I>: EXP BITFIELD_VARIETY(<I>v</I>)
|
|
|
190 |
-> EXP TOP
|
|
|
191 |
</PRE>
|
|
|
192 |
<P>
|
|
|
193 |
<HR>
|
|
|
194 |
<P><I>Part of the <A HREF="../index.html">TenDRA Web</A>.<BR>Crown
|
|
|
195 |
Copyright © 1998.</I></P>
|
|
|
196 |
</BODY>
|
|
|
197 |
</HTML>
|