Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<!-- Crown Copyright (c) 1998 -->
<HTML>
<HEAD>
<TITLE>TDF Token Register</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#400080" ALINK="#FF0000">
<H1>TDF Token Register</H1>
<H3>January 1998</H3>
<IMG SRC="../images/no_next.gif" ALT="next section">
<IMG SRC="../images/no_prev.gif" ALT="previous section">
<IMG SRC="../images/no_top.gif" ALT="current document">
<A HREF="../index.html"><IMG SRC="../images/home.gif" ALT="TenDRA home page">
</A>
<IMG SRC="../images/no_index.gif" ALT="document index"><P>
<HR>
<DL>
<DT><A HREF="#S2"><B>1</B> - Introduction</A><DD>
<DL>
<DT><A HREF="#S3"><B>1.1</B> - Background</A><DD>
<DT><A HREF="#S4"><B>1.2</B> - Token Register Objectives</A><DD>
</DL>
<DT><A HREF="#S5"><B>2</B> - Naming scheme</A><DD>
<DT><A HREF="#S6"><B>3</B> - Target dependency tokens</A><DD>
<DL>
<DT><A HREF="#S7"><B>3.1</B> - Integer variety representations</A><DD>
<DT><A HREF="#S8"><B>3.2</B> - Floating variety representations</A><DD>
<DT><A HREF="#S9"><B>3.3</B> - Non-numeric representations</A><DD>
<DT><A HREF="#S10"><B>3.4</B> - Common conversion routines</A><DD>
</DL>
<DT><A HREF="#S11"><B>4</B> - Basic mapping tokens</A><DD>
<DL>
<DT><A HREF="#S12"><B>4.1</B> - C mapping tokens</A><DD>
<DT><A HREF="#S13"><B>4.2</B> - Fortran mapping tokens</A><DD>
</DL>
<DT><A HREF="#S14"><B>5</B> - TDF Interface tokens</A><DD>
<DL>
<DT><A HREF="#S15"><B>5.1</B> - Exception handling</A><DD>
<DT><A HREF="#S16"><B>5.2</B> - TDF Diagnostic Specification</A><DD>
<DT><A HREF="#S17"><B>5.3</B> - Accessing variable parameter lists</A><DD>
</DL>
<DT><A HREF="#S18"><B>6</B> - Language Programming Interfaces</A><DD>
<DL>
<DT><A HREF="#S19"><B>6.1</B> - The DRA C LPI</A><DD>
<DT><A HREF="#S191"><B>6.2</B> - The DRA C++ LPI</A><DD>
<DT><A HREF="#S20"><B>6.3</B> - The Etnoteam Fortran LPI</A><DD>
</DL>
<DT><A HREF="#S21"><B>7</B> - Application Programming Interfaces</A><DD>
<DL>
<DT><A HREF="#S22"><B>7.1</B> - ANSI C standard functions</A><DD>
<DT><A HREF="#S23"><B>7.2</B> - Common exceptional cases</A><DD>
</DL>
</DL>
<HR>
<H2><A NAME=S2>1. Introduction</A></H2>
<H3><A NAME=S3>1.1. Background</A></H3>
TDF is an interface used for architecture neutral and programming
language neutral representation of program. It is used both within
portable language specific compilation systems, and for architecture
neutral distribution of compiled programs. For full details see
<A HREF="spec1.html">TDF Specification, Issue 4.0 (Revision 1)</A>.
<P>
TDF tokens offer a general encapsulation and expansion mechanism which
allows any implementation detail to be delayed to the most appropriate
stage of program translation. This provides a means for encapsulating
any target dependencies in a neutral form, with specific implementations
defined through standard TDF features. This raises a natural opportunity
for well understood sets of TDF tokens to be included along with TDF
itself as interface between TDF tools.
<P>
This first revision includes additional tokens for accessing variable
parameter lists (see <A HREF="#S17">section 5.3</A>), and a C mapping
token to support the optional type <I>long long int</I>.
<P>
<H3><A NAME=S4>1.2. Token Register Objectives</A></H3>
As TDF tokens may be used to represent any piece of TDF, they may
be used to supplement any TDF interface between software tools. However,
that raises the issue of control authority for such an interface.
In many cases, the interfaces may be considered to `belong' to a particular
tool. In other cases, the names and specifications of tokens need
to be recorded for common use.
<P>
This token register is used to record the names and specifications
of tokens which may need to be assumed by more than one software tool.
It also defines a naming scheme which should be used consistently
to avoid ambiguity between tokens.
<P>
Five classes of tokens are identified:
<P>
<OL>
<LI>target dependency tokens, which are concerned with describing
target architecture or translator detail;
<P>
<LI>basic mapping tokens, which relate general language features to
architecture detail;
<P>
<LI>TDF interface tokens, which may be required to complete the specification
of some TDF constructs;
<P>
<LI>language programming interfaces (LPI) which may be specific to
a particular producer;
<P>
<LI>application programming interfaces (API).
</OL>
These classes are discussed separately, in sections <A HREF="#S6">3</A>
to <A HREF="#S21">7</A> below.
<P>
<HR>
<H2><A NAME=S5>2. Naming scheme</A></H2>
A flat name space will suffice for TDF token names if producer writers
adopt the simple constraints described here. TDF has separate provision
for a hierarchic unique naming scheme, but that was intended for a
specific purpose that has not yet been realised.
<P>
External names for program or application specific tokens should be
confined to `simple names', which we define to mean that they consist
only of letters, digits and underscore, the characters allowed in
C identifiers. Normally there will be very few such external names,
as tokens internal to a single capsule do not require to be named.
All other token names will consist of some controlled prefix followed
by a simple name, with the prefix identifying the control authority.
<P>
For API tokens, the prefix will consist of a sequence of simple names,
each followed by a dot, where the first simple name is the name of
the API as listed or referred to in section <A HREF="#S21">7</A>.
<P>
The prefix for producer specific and target dependency tokens will
begin and end with characters that distinguish them from the above
cases. However, common tools such as DISP, TNC and PL-TDF assume that
token names contain only letters, digits, underscore, dot, and/or
twiddle.
<P>
The following prefixes are currently reserved:
<P>
<DL>
<DT><CODE>~</CODE><DD>TDF interface tokens as specified in section
<A HREF="#S14">5</A> below, and also LPI tokens specific to DRA's
C producer.
<DT><CODE>.~</CODE><DD>Registered target dependency tokens as specified
in section <A HREF="#S6">3</A> below, and basic mapping tokens specified
in section <A HREF="#S11">4</A>.
<DT><CODE>~cpp.</CODE><DD>LPI tokens specific to DRA's C++ producer,
other than those it shares with the C producer.
<DT>.Et~<DD>LPI tokens specific to Etnoteam's Fortran77 producer.
</DL>
<P>
<HR>
<H2><A NAME=S6>3. Target dependency tokens</A></H2>
Target dependency tokens provide a common interface to simple constructs
where the required detail for any specific architecture can be expressed
within TDF, but the detail will be architecture specific. Every installer
should have associated with it, a capsule containing the installer
specific definitions of all the tokens specificed within this section
<A HREF="#S6">3</A>.
<P>
Some of these tokens provide information about the integer and floating
point variety representations supported by an installer, in a form
that may be used by TDF analysis tools for architecture specific analysis,
or by library generation tools when generating an architecture specific
version of a library. Other target dependency tokens provide commonly
required conversion routines.
<P>
It is recommended that these tokens should not be used directly within
application programs. They are designed for use within LPI definitions,
which can provide a more appropriate interface for applications.
<P>
<H3><A NAME=S7>3.1. Integer variety representations</A></H3>
Since TDF specifies integer representations to be twos-complement,
the number of bits required to store an integer variety representation
fully specifies that representation. The minimum or maximum signed
or unsigned integer that can be represented within any variety representation
can easily be determined from the number of bits.
<P>
<B>3.1.1.</B> <CODE>.~rep_var_width</CODE>
<P>
<PRE>
<I>w</I>: NAT
-> NAT
</PRE>
If <I>w </I>lies within the range of <CODE>VARIETY</CODE> sizes supported
by the associated installer, <I>rep_var_width</I>(<I>w</I>) will be
the number of bits required to store values of <CODE>VARIETY</CODE>
<I>var_width</I>(
<I>b</I>,<I>w</I>), for any <CODE>BOOL</CODE> <I>b</I>.
<P>
If <I>w </I>is outside the range of <CODE>VARIETY</CODE> sizes supported
by the associated installer, <I>rep_var_width</I>(<I>w</I>) will be
0.
<P>
<B>3.1.2.</B> <CODE>.~rep_atomic_width</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~rep_atomic_width</I> will be the number of bits required to store
values of some <CODE>VARIETY</CODE> <I>v </I>such that <I>assign</I>
and <I>assign_with_mode</I> are atomic operations if the value assigned
has <CODE>SHAPE</CODE> <I>integer</I>(<I>v</I>). The TDF specification
guarantees existence of such a number.
<P>
<H3><A NAME=S8>3.2. Floating variety representations</A></H3>
Floating point representations are much more diverse than integers,
but we may assume that each installer will support a finite set of
distinct representations. For convenience in distinguishing between
these representations within architecture specific TDF, the set of
distinct representations supported by any specific installer are stated
to be ordered into a sequence of non-decreasing memory size. An analysis
tool can easily count through this sequence to determine the properties
of all supported representations, starting at 1 and using <I>.~rep_fv_width
</I> to test for the sequence end.
<P>
<B>3.2.1.</B> <CODE>.~rep_fv</CODE>
<P>
<PRE>
<I>n</I>: NAT
-> FLOATING_VARIETY
</PRE>
<I>.~rep_fv</I>(<I>n</I>) will be the <CODE>FLOATING_VARIETY</CODE>
whose representation is the <I>n</I>th of the sequence of supported
floating point representations.
<I>n</I> will lie within this range.
<P>
<B>3.2.2.</B> <CODE>.~rep_fv_width</CODE>
<P>
<PRE>
<I>n</I>: NAT
-> NAT
</PRE>
If <I>n</I> lies within the sequence range of supported floating point
representations, <I>.~rep_fv_width</I>(<I>n</I>) will be the number
of bits required to store values of <CODE>FLOATING_VARIETY</CODE>
<I>.~rep_fv</I>(<I>n</I>).
<P>
If <I>n</I> is outside the sequence range of supported floating point
representations, <I>.~rep_fv_width</I>(<I>n</I>) will be 0.
<P>
<B>3.2.3.</B> <CODE>.~rep_fv_radix</CODE>
<P>
<PRE>
<I>n</I>: NAT
-> NAT
</PRE>
<I>.~rep_fv_radix</I>(<I>n</I>) will be the radix used in the representation
of values of <CODE>FLOATING_VARIETY</CODE> <I>.~rep_fv</I>(<I>n</I>).
<P>
<I>n</I> will lie within the sequence range of supported floating
point representations.
<P>
<B>3.2.4.</B> <CODE>.~rep_fv_mantissa</CODE>
<P>
<PRE>
<I>n</I>: NAT
-> NAT
</PRE>
<I>.~rep_fv_mantissa</I>(<I>n</I>) will be the number of base
<I>.~rep_fv_radix</I>(<I>n</I>) digits in the mantissa representation
of values of <CODE>FLOATING_VARIETY</CODE> <I>.~rep_fv</I>(<I>n</I>).
<P>
<I>n</I> will lie within the sequence range of supported floating
point representations.
<P>
<B>3.2.5.</B> <CODE>.~rep_fv_min_exp</CODE>
<P>
<PRE>
<I>n</I>: NAT
-> NAT
</PRE>
<I>.~rep_fv_min_exp</I>(<I>n</I>) will be the maximum integer
<I>m</I> such that (<I>.~rep_fv_radix</I>(<I>n</I>))<I>-m</I>
is exactly representable (though not necessarily normalised) by the
<CODE>FLOATING_VARIETY</CODE> <I>.~rep_fv</I>(<I>n</I>).
<P>
<I>n</I> will lie within the sequence range of supported floating
point representations.
<P>
<B>3.2.6.</B> <CODE>.~rep_fv_max_exp</CODE>
<P>
<PRE>
<I>n</I>: NAT
-> NAT
</PRE>
<I>.~rep_fv_max_exp</I>(<I>n</I>) will be the maximum integer
<I>m</I> such that (<I>.~rep_fv_radix</I>(<I>n</I>))<I>m</I>
is exactly representable by the <CODE>FLOATING_VARIETY</CODE> <I>.~rep_fv</I>(
<I>n</I>).
<P>
<I>n</I> will lie within the sequence range of supported floating
point representations.
<P>
<B>3.2.7.</B> <CODE>.~rep_fv_epsilon</CODE>
<P>
<PRE>
<I>n</I>: NAT
-> EXP FLOATING .~rep_fv(<I>n</I>)
</PRE>
<I>.~rep_fv_epsilon</I>(<I>n</I>) will be the smallest strictly positive
real <I>x </I>such that (1.0 + <I>x</I>) is exactly representable
by the <CODE>FLOATING_VARIETY</CODE> <I>.~rep_fv(n)</I>.
<P>
<I>n</I> will lie within the sequence range of supported floating
point representations.
<P>
<B>3.2.8.</B> <CODE>.~rep_fv_min_val</CODE>
<P>
<PRE>
<I>n</I>: NAT
-> EXP FLOATING .~rep_fv(<I>n</I>)
</PRE>
<I>.~rep_fv_min_val</I>(<I>n</I>) will be the smallest strictly positive
real number that is exactly representable (though not necessarily
normalised)) by the <CODE>FLOATING_VARIETY</CODE> <I>.~rep_fv(n)</I>.
<P>
<I>n</I> will lie within the sequence range of supported floating
point representations.
<P>
<B>3.2.9.</B> <CODE>.~rep_fv_max_val</CODE>
<P>
<PRE>
<I>n</I>: NAT
-> EXP FLOATING .~rep_fv(<I>n</I>)
</PRE>
<I>.~rep_fv_max_val</I>(<I>n</I>) will be the largest real number
that is exactly representable by the <CODE>FLOATING_VARIETY</CODE>
<I>.~rep_fv(n)</I>.
<P>
<I>n</I> will lie within the sequence range of supported floating
point representations.
<P>
<H3><A NAME=S9>3.3. Non-numeric representations</A></H3>
<B>3.3.1.</B> <CODE>.~ptr_width</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~ptr_width</I> will be the minimum <I>.~rep_var_width</I>(<I>w</I>)
for any <I>w </I>such that any pointer to any alignment may be converted
to an integer of <CODE>VARIETY</CODE> <I>var_width</I>(<I>b</I>,<I>w</I>),
for some <CODE>BOOL</CODE> <I>b</I>, and back again without loss of
information, using the conversions <I>.~ptr_to_int</I> and <I>.~int_to_ptr</I>
(q.v.).
<P>
<B>3.3.2.</B> <CODE>.~best_div</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~best_div</I> is 1 or 2 to indicate preference for class 1 or
class 2 division and modulus (as defined in the TDF Specification).
This token would be used in situations where either class is valid
but must be used consistently.
<P>
<B>3.3.3.</B> <CODE>.~little_endian</CODE>
<P>
<PRE>
-> BOOL
</PRE>
<I>.~little_endian</I> is a property of the relationship between different
variety representations and arrays. If an array of a smaller variety
can be mapped onto a larger variety, and <I>.~little_endian</I>
is true, then smaller indices of the smaller variety array map onto
smaller ranges of the larger variety. If <I>.~little_endian</I>
is false, no such assertion can be made.
<P>
<H3><A NAME=S10>3.4. Common conversion routines</A></H3>
This subsection contains a set of conversion routines between values
of different shapes, that are not required to have any specific meaning
apart from reversability. If the storage space requirements for the
two shapes are identical, the conversion can usually be achieved without
change of representation. When that is the case, and if the two shapes
can be stored at a common alignment, the conversion can simply be
achieved by assignment via a common union, which will ensure the required
alignment consistency.
<P>
<B>3.4.1.</B> <CODE>.~ptr_to_ptr</CODE>
<P>
<PRE>
<I>a1</I>: ALIGNMENT
<I>a2</I>: ALIGNMENT
<I>p</I>: EXP POINTER(<I>a1</I>)
-> EXP POINTER(<I>a2</I>)
</PRE>
<I>.~ptr_to_ptr</I> converts pointers from one pointer shape to another.
<P>
If <I>p</I> is any pointer with alignment <I>a1</I>, then <I>.~ptr_to_ptr
</I>(<I>a2</I>, <I>a1</I>, <I>.~ptr_to_ptr</I>(<I>a1</I>,
<I>a2</I>, <I>p</I>)) shall result in the same pointer <I>p</I>, provided
that the number of bits required to store a pointer with alignment
<I>a2</I> is not less than that required to store a pointer with alignment
<I>a1</I>.
<P>
<B>3.4.2.</B> <CODE>.~ptr_to_int</CODE>
<P>
<PRE>
<I>a</I>: ALIGNMENT
<I>v</I>: VARIETY
<I>p</I>: EXP POINTER(<I>a</I>)
-> EXP INTEGER(<I>v</I>)
</PRE>
<I>.~ptr_to_int</I> converts a pointer to an integer. The result is
undefined if the <CODE>VARIETY</CODE> v is insufficient to distinguish
between all possible distinct pointers <I>p</I> of alignment <I>a</I>.
<P>
<B>3.4.3.</B> <CODE>.~int_to_ptr</CODE>
<P>
<PRE>
<I>v</I>: VARIETY
<I>a</I>: ALIGNMENT
<I>i</I>: EXP INTEGER(<I>v</I>)
-> EXP POINTER(<I>a</I>)
</PRE>
<I>.~int_to_ptr</I> converts an integer to a pointer. The result is
undefined unless the integer i was obtained without modification from
some pointer using <I>.~ptr_to_int</I> with the same variety and alignment
arguments.
<P>
If <I>p</I> is any pointer with alignment <I>a</I>, and <I>v</I>
is <I>var_width</I>(<I>b</I>, <I>.~ptr_width</I>) for some <CODE>BOOL</CODE>
<I>b</I>, then <I>.~int_to_ptr</I>(<I>v</I>, <I>a</I>, <I>.~ptr_to_int
</I>(<I>a</I>, <I>v</I>, <I>p</I>)) shall result in the same pointer
<I>p</I>.
<P>
<B>3.4.4.</B> <CODE>.~f_to_ptr</CODE>
<P>
<PRE>
<I>a</I>: ALIGNMENT
<I>fn</I>: EXP PROC
-> EXP POINTER(<I>a</I>)
</PRE>
<I>.~f_to_ptr</I> converts a procedure to a pointer. The result is
undefined except as required for consistency with <I>.~ptr_to_f</I>.
<P>
<B>3.4.5.</B> <CODE>.~ptr_to_f</CODE>
<P>
<PRE>
<I>a</I>: ALIGNMENT
<I>p</I>: EXP POINTER(<I>a</I>)
-> EXP PROC
</PRE>
<I>.~ptr_to_f</I> converts a pointer to a procedure. The result is
undefined unless the pointer p was obtained without modification from
some procedure <I>f</I> using <I>.~f_to_ptr</I>(<I>a</I>,
<I>f</I>). The same procedure <I>f</I> is delivered.
<P>
<HR>
<H2><A NAME=S11>4. Basic mapping tokens</A></H2>
Basic mapping tokens provide target specific detail for specific language
features that are defined to be target dependent. This detail need
not be fixed for a particular target architecture, but needs to provide
compatibility with any external library with which an application
program is to be linked.
<P>
Tokens specific to the C and Fortran language families are included.
Like the target dependency tokens, it is again recommended that these
tokens should not be used directly within application programs. They
are designed for use within LPI definitions, which can provide a more
appropriate interface for applications.
<P>
Every operating system variant of an installer should have associated
with it, a capsule containing the definitions of all the tokens specificed
within this section <A HREF="#S11">4</A>.
<P>
<H3><A NAME=S12>4.1. C mapping tokens</A></H3>
<B>4.1.1.</B> <CODE>.~char_width</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~char_width</I> is the number of bits required to store values
of the representation <CODE>VARIETY</CODE> that corresponds to the
C type <I>char</I>.
<P>
<B>4.1.2.</B> <CODE>.~short_width</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~short_width</I> is the number of bits required to store values
of the representation <CODE>VARIETY</CODE> that corresponds to the
C type <I>short int</I>.
<P>
<B>4.1.3.</B> <CODE>.~int_width</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~int_width</I> is the number of bits required to store values
of the representation <CODE>VARIETY</CODE> that corresponds to the
C type <I>int</I>.
<P>
<B>4.1.4.</B> <CODE>.~long_width</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~long_width</I> is the number of bits required to store values
of the representation <CODE>VARIETY</CODE> that corresponds to the
C type <I>long int</I>.
<P>
<B>4.1.5.</B> <CODE>.~longlong_width</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~longlong_width</I> is the number of bits required to store values
of the representation <CODE>VARIETY</CODE> that corresponds to the
C type <I>long long int</I>.
<P>
<B>4.1.6.</B> <CODE>.~size_t_width</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~size_t_width</I> is the number of bits required to store values
of the representation <CODE>VARIETY</CODE> that corresponds to the
C type <I>size_t</I>. It will be the same as one of <I>.~short_width</I>,
<I>.~int_width</I>, or <I>.~long_width</I>.
<P>
<B>4.1.7.</B> <CODE>.~fl_rep</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~fl_rep</I> is the sequence number (see subsection <A HREF="#S8">3.2</A>)
of the floating point representation to be used for values of C type
<I>float</I>.
<P>
<B>4.1.8.</B> <CODE>.~dbl_rep</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~dbl_rep</I> is the sequence number (see subsection 3.2) of the
floating point representation to be used for values of C type
<I>double</I>.
<P>
<B>4.1.9.</B> <CODE>.~ldbl_rep</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~ldbl_rep</I> is the sequence number (see subsection 3.2) of the
floating point representation to be used for values of C type
<I>long double</I>.
<P>
<B>4.1.10.</B> <CODE>.~pv_align</CODE>
<P>
<PRE>
-> ALIGNMENT
</PRE>
<I>.~pv_align</I> is the common alignment for all pointers that can
be represented by the C generic pointer type <I>void*</I>. For architecture
independence, this would have to be a union of several alignments,
but for many installers it can be simplified to
<I>alignment</I>(<I>integer</I>(<I>var_width</I>(<I>false</I>,
<I>.~char_width</I>))).
<P>
<B>4.1.11.</B> <CODE>.~min_struct_rep</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~min_struct_rep</I> is the number of bits required to store values
of the smallest C integral type which share the same alignment properties
as a structured value whose members are all of that same integral
type. It will be the same as one of <I>.~char_width</I>,
<I>.~short_width</I>, <I>.~int_width</I>, or <I>.~long_width</I>.
<P>
<B>4.1.12.</B> <CODE>.~char_is_signed</CODE>
<P>
<PRE>
-> BOOL
</PRE>
<I>.~char_is_signed</I> is <I>true</I> if the C type <I>char</I>
is treated as signed, or <I>false</I> if it is unsigned.
<P>
<B>4.1.13.</B> <CODE>.~bitfield_is_signed</CODE>
<P>
<PRE>
-> BOOL
</PRE>
<I>.~bitfield_is_signed</I> is <I>true</I> if bitfield members of
structures in C are treated as signed, or <I>false</I> if unsigned.
<P>
<H3><A NAME=S13>4.2. Fortran mapping tokens</A></H3>
<B>4.2.1.</B> <CODE>.~F_char_width</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~F_char_width</I> is the number of bits required to store values
of the representation <CODE>VARIETY</CODE> that corresponds to the
Fortran77 type
<I>CHARACTER</I>.
<P>
In most cases, <I>.~F_char_width</I> is the same as <I>.~char_width</I>.
<P>
<B>4.2.2.</B> <CODE>.~F_int_width</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~F_int_width</I> is the number of bits required to store values
of the representation <CODE>VARIETY</CODE> that corresponds to the
Fortran77 type
<I>INTEGER</I>.
<P>
In most cases, <I>.~F_int_width</I> is the same as <I>.~int_width</I>.
<P>
<B>4.2.3.</B> <CODE>.~F_fl_rep</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~F_fl_rep</I> is the sequence number (see subsection <A HREF="#S8">3.2</A>)
of the floating point representation to be used for values of Fortran77
type <I>REAL</I>, with the constraint that <I>.~rep_fv_width</I>(<I>.~F_fl_rep
</I>) = <I>.~F_int_width</I>.
<P>
If this constraint cannot be met, <I>.~F_fl_rep</I> will be 0.
<P>
<B>4.2.4.</B> <CODE>.~F_dbl_rep</CODE>
<P>
<PRE>
-> NAT
</PRE>
<I>.~F_dbl_rep</I> is the sequence number (see subsection 3.2) of
the floating point representation to be used for values of Fortran77
type <I>DOUBLE PRECISION</I>, with the constraint that <I>.~rep_fv_width</I>(
<I>.~F_dbl_rep</I>) = 2 * <I>.~F_int_width</I>.
<P>
If this constraint cannot be met, <I>.~F_dbl_rep</I> will be 0.
<P>
<HR>
<H2><A NAME=S14>5. TDF Interface tokens</A></H2>
A very few specifically named tokens are referred to within the TDF
specification, which are required to complete the ability to use certain
TDF constructs. Responsibility for providing appropriate definitions
for these tokens is indicated with the specifications below.
<P>
Similarly, a few tokens are specified within the TDF Diagnostic Specification.
<P>
<H3><A NAME=S15>5.1. Exception handling</A></H3>
<B>5.1.1.</B> <CODE>~Throw</CODE>
<P>
<PRE>
<I>n</I>: NAT
-> EXP BOTTOM
</PRE>
The <CODE>EXP</CODE> <I>e</I> defined as the body of this token will
be evaluated on occurrence of any error whose <CODE>ERROR_TREATMENT</CODE>
is <I>trap</I>. The type of error can be determined within <I>e</I>
from the NAT
<I>n</I>, which will be <I>error_val(ec)</I> for some <CODE>ERROR_CODE</CODE>
<I>ec</I>. The token definition body <I>e</I> will typically consist
of a <I>long_jump</I> to some previously set exception handler.
<P>
Exception handling using <I>trap</I> and ~<I>Throw</I> will usually
be determined by producers for languages that specify their own exception
handling semantics. Responsibility for the <I>~Throw</I> token definition
will therefore normally rest with producers, by including this token
within the producer specific LPI.
<P>
<B>5.1.2.</B> <CODE>~Set_signal_handler</CODE>
<P>
<PRE>
-> EXP OFFSET (locals_alignment, locals_alignment)
</PRE>
<I>~Set_signal_handler</I> must be applied before any use of the
<CODE>ERROR_TREATMENT</CODE> <I>trap</I>, to indicate the need for
exception trapping. Responsibility for the <I>~Set_signal_handler</I>
token definition will rest with installers. Responsibility for applying
it will normally rest with producers.
<P>
The resulting offset value will contain the amount of space beyond
any stack limit, which must be reserved for use when handling a
<I>stack_overflow</I> trap raised by exceeding that limit.
<P>
<B>5.1.3.</B> <CODE>~Sync_handle</CODE>r
<P>
<PRE>
-> EXP TOP
</PRE>
<I>~Sync_handler</I> delays subsequent processing until any pending
exceptions have been raised, as necessary to synchronise exception
handler modification. It must be applied immediately prior to any
action that modifies the effect of <I>~Throw</I>, such as assignment
to a variable holding an exception handler as <I>long_jump</I> destination
Responsibility for the <I>~Sync_handler</I> token definition will
rest with installers. Responsibility for applying it will normally
rest with producers.
<P>
<H3><A NAME=S16>5.2. TDF Diagnostic Specification</A></H3>
The <A HREF="../diag/diag1.html">TDF Diagnostic Specification</A>
is a separate document which describes an extension to TDF, optionally
used to provide program diagnostic information that can be transformed
by installers to the form required by popular platform-specific debuggers.
This extension cannot be considered fully developed and is therefore
not included as part of standard TDF. Its use for other than DRA's
C producer has not been considered.
<P>
<B>5.2.1.</B> <CODE>~exp_to_source, ~diag_id_scope, ~diag_type_scope,
~diag_tag_scope</CODE>
<P>
<PRE>
<I>bdy</I>: EXP
... : ...
-> EXP
</PRE>
Each of these four tokens has several arguments of which the first,
<I>bdy</I>, is an <CODE>EXP</CODE>. In each case the default definition
body, when no diagnostic information is required, is simply <I>bdy</I>.
Note that this description is quite sufficient to enable installers
to ignore any diagnostic information that may be included in produced
TDF, without needing any further knowledge of the TDF Diagnostic Specification.
<P>
<H3><A NAME=S17>5.3. Accessing variable parameter lists</A></H3>
Installers should provide token definitions for the tokens listed
in this section.
<P>
<B>5.3.1.</B> <CODE>~va_list</CODE>
<P>
<PRE>
-> SHAPE
</PRE>
This is the <CODE>SHAPE</CODE> of a variable capable of holding state
information used for stepping through the anonymous parameters of
a procedure created by <I>make_proc</I>.
<P>
<B>5.3.2.</B> <CODE>~__va_start</CODE>
<P>
<PRE>
<I>p</I>: EXP POINTER var_param_alignment
-> EXP ~va_list
</PRE>
If <I>t</I> is the <CODE>TAG</CODE> introduced by <I>var_intro</I>
<CODE>OPTION(TAGACC)</CODE> in <I>make_proc</I>, then the token application
<I>~__va_start(obtain_tag(t))</I> will provide the initial value for
a local variable to be used for stepping through the anonymous parameters
of the procedure, starting with the first actual parameter (if any)
that does not have a corresponding entry in the make_proc params_intro
list.
<P>
<B>5.3.3.</B> <CODE>~va_arg</CODE>
<P>
<PRE>
<I>v</I>: EXP POINTER (alignment(~va_list))
<I>s</I>: SHAPE
-> EXP <I>s</I>
</PRE>
If <I>v</I> is the variable initialised by <I>~__va_start </I>(see
above), then successive token applications <I>~va_arg(v,s)</I>
will deliver the anonymous parameter values in turn. The successive
<CODE>SHAPE</CODE>s <I>s</I> must be the appropriate <CODE>SHAPE</CODE>s
for the successive parameters.
<P>
<B>5.3.4.</B> <CODE>~va_end</CODE>
<P>
<PRE>
<I>v</I>: EXP POINTER (alignment(~va_list))
-> EXP TOP
</PRE>
If <I>v</I> is a variable initialised by <I>~__va_start</I>, the token
application <I>~va_end(v)</I> indicates that no further use will be
made of <I>v</I>.
<P>
<B>5.3.5.</B> <CODE>~next_caller_offset</CODE>
<P>
<PRE>
<I>o1</I>: EXP OFFSET (<I>fa</I>,parameter_alignment(<I>s1</I>))
<I>s1</I>: SHAPE
<I>s2</I>: SHAPE
-> EXP OFFSET (<I>fa</I>,parameter_alignment(<I>s2</I>))
</PRE>
<I>~next_caller_offset</I> is used to provide access to successive
elements of the <I>caller_params</I> of an <I>apply_general_proc</I>,
by delivering successive <CODE>OFFSET</CODE>s of their positions relative
to the environment pointer created by that procedure application.
Both the
<I>apply_general_proc</I> and associated <I>make_general_proc</I>
will include <CODE>PROCPROPS</CODE> <I>var_callers</I>.
<P>
<I>o1</I> will be the <CODE>OFFSET</CODE> for a <I>caller_params</I>
element of
<CODE>SHAPE</CODE> <I>s1</I>, and will be derived either from <I>env_offset</I>
for a <CODE>TAG</CODE> introduced by <I>caller_intro</I> of the <I>make_general_proc
</I>, or from a previous application of <I>~next_caller_offset</I>.
<I>s2</I>
will be the <CODE>SHAPE</CODE> of the subsequent <I>caller_params</I>
element, whose <CODE>OFFSET</CODE> is delivered. <I>fa</I> will include
the set union of
<CODE>ALIGNMENT</CODE>s appropriate to the <I>make_general_proc</I>
(as specified by <I>current_env</I>).
<P>
<B>5.3.6.</B> <CODE>~next_callee_offset</CODE>
<P>
<PRE>
<I>o1</I>: EXP OFFSET (<I>fa</I>,parameter_alignment(<I>s1</I>))
<I>s1</I>: SHAPE
<I>s2</I>: SHAPE
-> EXP OFFSET (<I>fa</I>,parameter_alignment(<I>s2</I>))
</PRE>
<I>~next_callee_offset</I> is used to provide access to successive
elements of the <CODE>CALLEES</CODE> of an <I>apply_general_proc</I>
or <I>tail_call</I>, by delivering successive <CODE>OFFSET</CODE>s
of their positions relative to the environment pointer created by
that procedure application. Both the procedure application and associated
<I>make_general_proc</I> will include <CODE>PROCPROPS</CODE> <I>var_callees</I>.
<P>
<I>o1</I> will be the <CODE>OFFSET</CODE> for a <CODE>CALLEES</CODE>
element of <CODE>SHAPE</CODE> <I>s1</I>, and will be derived either
from <I>env_offset</I> for a <CODE>TAG</CODE> introduced by <I>callee_intro</I>
of the <I>make_general_proc</I>, or from a previous application of
<I>~next_callee_offset</I>. <I>s2</I>
will be the <CODE>SHAPE</CODE> of the subsequent <CODE>CALLEES</CODE>
element, whose <CODE>OFFSET</CODE>
is delivered. <I>fa</I> will include the set union of <CODE>ALIGNMENT</CODE>s
appropriate to the <I>make_general_proc</I> (as specified by <I>current_env
</I>).
<P>
<HR>
<H2><A NAME=S18>6. Language Programming Interfaces</A></H2>
A Language Programming Interface (LPI) is here defined to mean a set
of tokens, usually specific to a particular producer, which will encapsulate
language features at a higher level than basic TDF constructs, more
convenient for the producer to produce.
<P>
Responsibility for the specification of individual LPIs lies with
the appropriate producer itself. Before an application can be installed
on some target platform, the appropriate LPI token definitions must
have been built for that platform. In this sense, the LPI can be considered
as a primitive API, which is discussed in section <A HREF="#S21">7</A>.
<P>
The process by which the LPI token definition library or capsule is
generated for any specific platform will vary according to the LPI,
and responsibility for defining that process will also lie with the
appropriate producer. Some LPIs, such as that associated with DRA's
C producer, can be fully defined by architecture neutral TDF, using
the tokens specified in sections <A HREF="#S6">3</A> and <A HREF="#S11">4</A>
to encapsulate any target dependencies. When that is the case, the
generation process can be fully automated. For other LPIs the process
may be much less automated. In some cases where the source language
implies a complex run-time system, this might even require a small
amount of new code to be written for each platform.
<P>
Generally, the individual LPI tokens do not need to be specified in
the token registry, provided they follow a registered naming scheme
to ensure uniqueness (see section <A HREF="#S5">2</A>). In exceptional
circumstances it may be necessary for some TDF tool to recognise individual
LPI tokens explicitly by name. This will be the case when experimenting
with potential extensions to TDF, in the field of parallelism for
example. In other cases a TDF installer or other tool may recognise
an LPI token by name rather than its definition by choice, for some
unspecified advantage. We make a pragmatic choice in such cases whether
to include such token specifications in the token registry. For widely
used producers, we can assume availability of the LPI token specifcations,
or standard definitions, separately from the token register, but we
should expect any such tokens to be specified within the register
for all cases where significant advantage could be taken by an installer
only if it recognises the token by name.
<P>
<H3><A NAME=S19>6.1. The DRA C LPI</A></H3>
DRA's C producer LPI is defined by an architecture neutral token definition
capsule provided with the producer. Target specific detail is included
only by use of the target dependency tokens and C mapping tokens specified
in sections <A HREF="#S6">3</A> and <A HREF="#S12">4.1</A> respectively.
Target specific versions of this capsule are obtained by transformation,
using the `preprocessing' action of the TDF tool <I>tnc</I>, with
definitions of the target dependency and C mapping tokens that are
provided with the target installer. No special treatment is required
for any of the C LPI tokens, though translation time can be slightly
improved in a few cases if the names are recognised and standard token
definition exercised explicitly within some installers.
<P>
The DRA C LPI does not include standard library features, for which
the C language requires header files. The standard C library is one
example of an API, discussed in section <A HREF="#S21">7</A>.
<P>
<H3><A NAME=S191>6.2. The DRA C++ LPI</A></H3>
The DRA C++ LPI extends the DRA C LPI adding tokens for target specific
C++ features not found in C. Again, standard library features are
treated as an API.
<H3><A NAME=S20>6.3. The Etnoteam Fortran LPI</A></H3>
The details in this subsection are provisional, subject to confirmation
of argument and result <CODE>SORT</CODE>s, and development of model
token definitions.
<P>
The following tokens are named here in case any installers may be
able to produce better code than could be achieved by normal token
expansion. In particular, some installers may be able to inline standard
function calls.
<UL>
<LI><I>.Et~SQRT</I>: square root of any floating variety, including
complex.
<LI><I>.Et~<CODE>EXP</CODE></I>: exponential (<I>e ** x</I>) of any
floating variety, including complex.
<LI><I>.Et~LOG</I>: (natural) logarithm of any floating variety, including
complex.
<LI><I>.Et~LOG_10</I>: base 10 logarithm of any floating variety,
including complex.
<LI><I>.Et~LOG_2</I>: base 2 logarithm of any floating variety, including
complex.
<LI><I>.Et~SIN</I>: sine of any floating variety, including complex.
<LI><I>.Et~COS</I>: cosine of any floating variety, including complex.
<LI><I>.Et~TAN</I>: tangent of any floating variety, including complex.
<LI><I>.Et~ASIN</I>: inverse sine of any floating variety, including
complex.
<LI><I>.Et~ACOS</I>: inverse cosine of any floating variety, including
complex.
<LI><I>.Et~ATAN</I>: inverse (one argument) tangent of any floating
variety, including complex.
<LI><I>.Et~ATAN2</I>: inverse (two arguments) tangent of any floating
variety, excluding complex.
<LI><I>.Et~SINH</I>: hyperbolic sine of any floating variety, including
complex.
<LI><I>.Et~COSH</I>: hyperbolic cosine of any floating variety, including
complex.
<LI><I>.Et~TANH</I>: hyperbolic tangent of any floating variety, including
complex.
<LI><I>.Et~ASINH</I>: inverse hyperbolic sine of any floating variety,
including complex.
<LI><I>.Et~ACOSH</I>: inverse hyperbolic cosine of any floating variety,
including complex.
<LI><I>.Et~ATANH</I>: inverse hyperbolic tangent of any floating variety,
including complex.
<LI><I>.Et~MOD</I>: floating point remainder of any floating variety,
excluding complex.
</UL>
<P>
<HR>
<H2><A NAME=S21>7. Application Programming Interfaces</A></H2>
Application Programming Interfaces are typically specified with a
C mapping, which define the required contents for C header files which
a portable C program must include by name to gain access to target
specific implementations of an API library. The TDF approach to API
specification includes using a #pragma token syntax within architecture
neutral C header files, such that all implementation dependencies
are encapsulated by API specific tokens. These API tokens are the
TDF representation of the API. Both the API library and API token
definitions are required before a TDF program using the API can be
installed on any particular platform.
<P>
Platform specific definitions for API tokens are produced automatically,
with few exceptions, for any platform with a conformant implementation
of the API. This is achieved by a token library building process which
analyses the architecture neutral header files for the API concerned,
together with the platform specific header files that provide normal
(non-TDF) C access to the API. The few exceptions occur where the
platform specific header files have been written to make use of specific
C compiler built-in features, typically recognised by identifiers
with a prefix such as `<I>__builtin_</I>'. Such cases are very likely
to require explicit recognition of the corresponding token name in
TDF installers.
<P>
Generally, API token names and specifications are not detailed in
this token register. The token specifications are clearly dependent
on the associated API specifications. Authority for controlling the
actual API token names, and the relationship between API tokens and
the various API standardisation authorities, remain separate subjects
of discussion.
<P>
Names and specifications are given or implied below for those API
tokens which frequently require built-in support from installers,
and for other cases where an installer may be able to produce better
code than could be achieved by normal token expansion, for example
by inlining standard function calls.
<P>
<H3><A NAME=S22>7.1. ANSI C standard functions</A></H3>
The set of tokens implied below all have the form:
<P>
<B>7.1.1.</B> <CODE>ansi.<I>header</I>.<I>function</I></CODE>
<P>
<PRE>
... : ...
-> EXP
</PRE>
Tokens are defined for all cases where <I>header</I> is ctype or string
or math or stdlib, and <I>function</I> is the name of a non-ellipsis
function specified in the ANSI C standard library, declared within
the corresponding header <<I>header</I>.h>. (Note that ellipsis
functions, such as <I>printf</I>, cannot be represented as tokens
since they may take a variable number of arguments.)
<P>
These tokens have arguments all of <CODE>SORT</CODE> <CODE>EXP</CODE>,
whose number and shape, and token result shape, all correspond to
the implementation shape of the named ANSI C standard library function
parameters and result. For the few cases where the function is specified
not to return (e.g. <I>ansi.stdlib.abort</I>), the result shape may
be either <CODE>TOP</CODE> or <CODE>BOTTOM</CODE>.
<P>
<H3><A NAME=S23>7.2. Common exceptional cases</A></H3>
<B>7.2.1.</B> <CODE>ansi.setjmp.setjmp</CODE>
<P>
<PRE>
<I>jb</I>: EXP
-> EXP
</PRE>
<I>ansi.setjmp.setjmp</I> is a token which has the semantics and argument
and result implementation shapes corresponding to the ANSI C macro
<I>setjmp</I> declared within <setjmp.h>.
<P>
<B>7.2.2.</B> <CODE>ansi.setjmp.longjmp</CODE>
<P>
<PRE>
<I>jb</I>: EXP
<I>v</I>: EXP
-> EXP
</PRE>
<I>ansi.setjmp.longjmp</I> is a token which has the semantics and
argument implementation shapes corresponding to the ANSI C macro <I>longjmp
</I> declared within <setjmp.h>. The result shape may be either
TOP or BOTTOM.
<P>
<B>7.2.3.</B> <CODE>~alloca</CODE>
<P>
<PRE>
<I>i</I>: EXP
-> EXP
</PRE>
<I>~alloca</I> is a token which has the semantics and argument and
result implementation shapes corresponding to the BSD specified function
<I>alloca</I>.
<P>
<B>7.2.4.</B> <CODE>ansi.stdarg.va_list, ansi.stdarg.__va_start,
ansi.stdarg.va_arg, ansi.stdarg.va_end</CODE>
<P>
These four tokens are identical to the Interface Tokens <I>~va_list</I>,
<I>~__va_start</I>, <I>~va_arg</I> and <I>~va_end</I> respectively.
<P>
<HR>
<P><I>Part of the <A HREF="../index.html">TenDRA Web</A>.<BR>Crown
Copyright © 1998.</I></P>
</BODY>
</HTML>