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.
This first revision includes additional tokens for accessing variable parameter lists (see section 5.3), and a C mapping token to support the optional type long long int.
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.
Five classes of tokens are identified:
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.
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 7.
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.
The following prefixes are currently reserved:
~
.~
~cpp.
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.
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.
3.1.1. .~rep_var_width
w: NAT -> NATIf w lies within the range of
VARIETY
sizes supported
by the associated installer, rep_var_width(w) will be
the number of bits required to store values of VARIETY
var_width(
b,w), for any BOOL
b.
If w is outside the range of VARIETY
sizes supported
by the associated installer, rep_var_width(w) will be
0.
3.1.2. .~rep_atomic_width
-> NAT.~rep_atomic_width will be the number of bits required to store values of some
VARIETY
v such that assign
and assign_with_mode are atomic operations if the value assigned
has SHAPE
integer(v). The TDF specification
guarantees existence of such a number.
3.2.1. .~rep_fv
n: NAT -> FLOATING_VARIETY.~rep_fv(n) will be the
FLOATING_VARIETY
whose representation is the nth of the sequence of supported
floating point representations.
n will lie within this range.
3.2.2. .~rep_fv_width
n: NAT -> NATIf n lies within the sequence range of supported floating point representations, .~rep_fv_width(n) will be the number of bits required to store values of
FLOATING_VARIETY
.~rep_fv(n).
If n is outside the sequence range of supported floating point representations, .~rep_fv_width(n) will be 0.
3.2.3. .~rep_fv_radix
n: NAT -> NAT.~rep_fv_radix(n) will be the radix used in the representation of values of
FLOATING_VARIETY
.~rep_fv(n).
n will lie within the sequence range of supported floating point representations.
3.2.4. .~rep_fv_mantissa
n: NAT -> NAT.~rep_fv_mantissa(n) will be the number of base .~rep_fv_radix(n) digits in the mantissa representation of values of
FLOATING_VARIETY
.~rep_fv(n).
n will lie within the sequence range of supported floating point representations.
3.2.5. .~rep_fv_min_exp
n: NAT -> NAT.~rep_fv_min_exp(n) will be the maximum integer m such that (.~rep_fv_radix(n))-m is exactly representable (though not necessarily normalised) by the
FLOATING_VARIETY
.~rep_fv(n).
n will lie within the sequence range of supported floating point representations.
3.2.6. .~rep_fv_max_exp
n: NAT -> NAT.~rep_fv_max_exp(n) will be the maximum integer m such that (.~rep_fv_radix(n))m is exactly representable by the
FLOATING_VARIETY
.~rep_fv(
n).
n will lie within the sequence range of supported floating point representations.
3.2.7. .~rep_fv_epsilon
n: NAT -> EXP FLOATING .~rep_fv(n).~rep_fv_epsilon(n) will be the smallest strictly positive real x such that (1.0 + x) is exactly representable by the
FLOATING_VARIETY
.~rep_fv(n).
n will lie within the sequence range of supported floating point representations.
3.2.8. .~rep_fv_min_val
n: NAT -> EXP FLOATING .~rep_fv(n).~rep_fv_min_val(n) will be the smallest strictly positive real number that is exactly representable (though not necessarily normalised)) by the
FLOATING_VARIETY
.~rep_fv(n).
n will lie within the sequence range of supported floating point representations.
3.2.9. .~rep_fv_max_val
n: NAT -> EXP FLOATING .~rep_fv(n).~rep_fv_max_val(n) will be the largest real number that is exactly representable by the
FLOATING_VARIETY
.~rep_fv(n).
n will lie within the sequence range of supported floating point representations.
.~ptr_width
-> NAT.~ptr_width will be the minimum .~rep_var_width(w) for any w such that any pointer to any alignment may be converted to an integer of
VARIETY
var_width(b,w),
for some BOOL
b, and back again without loss of
information, using the conversions .~ptr_to_int and .~int_to_ptr
(q.v.).
3.3.2. .~best_div
-> NAT.~best_div 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.
3.3.3. .~little_endian
-> BOOL.~little_endian 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 .~little_endian is true, then smaller indices of the smaller variety array map onto smaller ranges of the larger variety. If .~little_endian is false, no such assertion can be made.
3.4.1. .~ptr_to_ptr
a1: ALIGNMENT a2: ALIGNMENT p: EXP POINTER(a1) -> EXP POINTER(a2).~ptr_to_ptr converts pointers from one pointer shape to another.
If p is any pointer with alignment a1, then .~ptr_to_ptr (a2, a1, .~ptr_to_ptr(a1, a2, p)) shall result in the same pointer p, provided that the number of bits required to store a pointer with alignment a2 is not less than that required to store a pointer with alignment a1.
3.4.2. .~ptr_to_int
a: ALIGNMENT v: VARIETY p: EXP POINTER(a) -> EXP INTEGER(v).~ptr_to_int converts a pointer to an integer. The result is undefined if the
VARIETY
v is insufficient to distinguish
between all possible distinct pointers p of alignment a.
3.4.3. .~int_to_ptr
v: VARIETY a: ALIGNMENT i: EXP INTEGER(v) -> EXP POINTER(a).~int_to_ptr converts an integer to a pointer. The result is undefined unless the integer i was obtained without modification from some pointer using .~ptr_to_int with the same variety and alignment arguments.
If p is any pointer with alignment a, and v
is var_width(b, .~ptr_width) for some BOOL
b, then .~int_to_ptr(v, a, .~ptr_to_int
(a, v, p)) shall result in the same pointer
p.
3.4.4. .~f_to_ptr
a: ALIGNMENT fn: EXP PROC -> EXP POINTER(a).~f_to_ptr converts a procedure to a pointer. The result is undefined except as required for consistency with .~ptr_to_f.
3.4.5. .~ptr_to_f
a: ALIGNMENT p: EXP POINTER(a) -> EXP PROC.~ptr_to_f converts a pointer to a procedure. The result is undefined unless the pointer p was obtained without modification from some procedure f using .~f_to_ptr(a, f). The same procedure f is delivered.
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.
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 4.
.~char_width
-> NAT.~char_width is the number of bits required to store values of the representation
VARIETY
that corresponds to the
C type char.
4.1.2. .~short_width
-> NAT.~short_width is the number of bits required to store values of the representation
VARIETY
that corresponds to the
C type short int.
4.1.3. .~int_width
-> NAT.~int_width is the number of bits required to store values of the representation
VARIETY
that corresponds to the
C type int.
4.1.4. .~long_width
-> NAT.~long_width is the number of bits required to store values of the representation
VARIETY
that corresponds to the
C type long int.
4.1.5. .~longlong_width
-> NAT.~longlong_width is the number of bits required to store values of the representation
VARIETY
that corresponds to the
C type long long int.
4.1.6. .~size_t_width
-> NAT.~size_t_width is the number of bits required to store values of the representation
VARIETY
that corresponds to the
C type size_t. It will be the same as one of .~short_width,
.~int_width, or .~long_width.
4.1.7. .~fl_rep
-> NAT.~fl_rep is the sequence number (see subsection 3.2) of the floating point representation to be used for values of C type float.
4.1.8. .~dbl_rep
-> NAT.~dbl_rep is the sequence number (see subsection 3.2) of the floating point representation to be used for values of C type double.
4.1.9. .~ldbl_rep
-> NAT.~ldbl_rep is the sequence number (see subsection 3.2) of the floating point representation to be used for values of C type long double.
4.1.10. .~pv_align
-> ALIGNMENT.~pv_align is the common alignment for all pointers that can be represented by the C generic pointer type void*. For architecture independence, this would have to be a union of several alignments, but for many installers it can be simplified to alignment(integer(var_width(false, .~char_width))).
4.1.11. .~min_struct_rep
-> NAT.~min_struct_rep 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 .~char_width, .~short_width, .~int_width, or .~long_width.
4.1.12. .~char_is_signed
-> BOOL.~char_is_signed is true if the C type char is treated as signed, or false if it is unsigned.
4.1.13. .~bitfield_is_signed
-> BOOL.~bitfield_is_signed is true if bitfield members of structures in C are treated as signed, or false if unsigned.
.~F_char_width
-> NAT.~F_char_width is the number of bits required to store values of the representation
VARIETY
that corresponds to the
Fortran77 type
CHARACTER.
In most cases, .~F_char_width is the same as .~char_width.
4.2.2. .~F_int_width
-> NAT.~F_int_width is the number of bits required to store values of the representation
VARIETY
that corresponds to the
Fortran77 type
INTEGER.
In most cases, .~F_int_width is the same as .~int_width.
4.2.3. .~F_fl_rep
-> NAT.~F_fl_rep is the sequence number (see subsection 3.2) of the floating point representation to be used for values of Fortran77 type REAL, with the constraint that .~rep_fv_width(.~F_fl_rep ) = .~F_int_width.
If this constraint cannot be met, .~F_fl_rep will be 0.
4.2.4. .~F_dbl_rep
-> NAT.~F_dbl_rep is the sequence number (see subsection 3.2) of the floating point representation to be used for values of Fortran77 type DOUBLE PRECISION, with the constraint that .~rep_fv_width( .~F_dbl_rep) = 2 * .~F_int_width.
If this constraint cannot be met, .~F_dbl_rep will be 0.
Similarly, a few tokens are specified within the TDF Diagnostic Specification.
~Throw
n: NAT -> EXP BOTTOMThe
EXP
e defined as the body of this token will
be evaluated on occurrence of any error whose ERROR_TREATMENT
is trap. The type of error can be determined within e
from the NAT
n, which will be error_val(ec) for some ERROR_CODE
ec. The token definition body e will typically consist
of a long_jump to some previously set exception handler.
Exception handling using trap and ~Throw will usually be determined by producers for languages that specify their own exception handling semantics. Responsibility for the ~Throw token definition will therefore normally rest with producers, by including this token within the producer specific LPI.
5.1.2. ~Set_signal_handler
-> EXP OFFSET (locals_alignment, locals_alignment)~Set_signal_handler must be applied before any use of the
ERROR_TREATMENT
trap, to indicate the need for
exception trapping. Responsibility for the ~Set_signal_handler
token definition will rest with installers. Responsibility for applying
it will normally rest with producers.
The resulting offset value will contain the amount of space beyond any stack limit, which must be reserved for use when handling a stack_overflow trap raised by exceeding that limit.
5.1.3. ~Sync_handle
r
-> EXP TOP~Sync_handler 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 ~Throw, such as assignment to a variable holding an exception handler as long_jump destination Responsibility for the ~Sync_handler token definition will rest with installers. Responsibility for applying it will normally rest with producers.
5.2.1. ~exp_to_source, ~diag_id_scope, ~diag_type_scope,
~diag_tag_scope
bdy: EXP ... : ... -> EXPEach of these four tokens has several arguments of which the first, bdy, is an
EXP
. In each case the default definition
body, when no diagnostic information is required, is simply bdy.
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.
5.3.1. ~va_list
-> SHAPEThis is the
SHAPE
of a variable capable of holding state
information used for stepping through the anonymous parameters of
a procedure created by make_proc.
5.3.2. ~__va_start
p: EXP POINTER var_param_alignment -> EXP ~va_listIf t is the
TAG
introduced by var_intro
OPTION(TAGACC)
in make_proc, then the token application
~__va_start(obtain_tag(t)) 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.
5.3.3. ~va_arg
v: EXP POINTER (alignment(~va_list)) s: SHAPE -> EXP sIf v is the variable initialised by ~__va_start (see above), then successive token applications ~va_arg(v,s) will deliver the anonymous parameter values in turn. The successive
SHAPE
s s must be the appropriate SHAPE
s
for the successive parameters.
5.3.4. ~va_end
v: EXP POINTER (alignment(~va_list)) -> EXP TOPIf v is a variable initialised by ~__va_start, the token application ~va_end(v) indicates that no further use will be made of v.
5.3.5. ~next_caller_offset
o1: EXP OFFSET (fa,parameter_alignment(s1)) s1: SHAPE s2: SHAPE -> EXP OFFSET (fa,parameter_alignment(s2))~next_caller_offset is used to provide access to successive elements of the caller_params of an apply_general_proc, by delivering successive
OFFSET
s of their positions relative
to the environment pointer created by that procedure application.
Both the
apply_general_proc and associated make_general_proc
will include PROCPROPS
var_callers.
o1 will be the OFFSET
for a caller_params
element of
SHAPE
s1, and will be derived either from env_offset
for a TAG
introduced by caller_intro of the make_general_proc
, or from a previous application of ~next_caller_offset.
s2
will be the SHAPE
of the subsequent caller_params
element, whose OFFSET
is delivered. fa will include
the set union of
ALIGNMENT
s appropriate to the make_general_proc
(as specified by current_env).
5.3.6. ~next_callee_offset
o1: EXP OFFSET (fa,parameter_alignment(s1)) s1: SHAPE s2: SHAPE -> EXP OFFSET (fa,parameter_alignment(s2))~next_callee_offset is used to provide access to successive elements of the
CALLEES
of an apply_general_proc
or tail_call, by delivering successive OFFSET
s
of their positions relative to the environment pointer created by
that procedure application. Both the procedure application and associated
make_general_proc will include PROCPROPS
var_callees.
o1 will be the OFFSET
for a CALLEES
element of SHAPE
s1, and will be derived either
from env_offset for a TAG
introduced by callee_intro
of the make_general_proc, or from a previous application of
~next_callee_offset. s2
will be the SHAPE
of the subsequent CALLEES
element, whose OFFSET
is delivered. fa will include the set union of ALIGNMENT
s
appropriate to the make_general_proc (as specified by current_env
).
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 7.
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 3 and 4 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.
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 2). 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.
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 7.
SORT
s, and development of model
token definitions.
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.
EXP
: exponential (e ** x) of any
floating variety, including complex.
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 `__builtin_'. Such cases are very likely to require explicit recognition of the corresponding token name in TDF installers.
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.
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.
7.1.1. ansi.header.function
... : ... -> EXPTokens are defined for all cases where header is ctype or string or math or stdlib, and function is the name of a non-ellipsis function specified in the ANSI C standard library, declared within the corresponding header <header.h>. (Note that ellipsis functions, such as printf, cannot be represented as tokens since they may take a variable number of arguments.)
These tokens have arguments all of SORT
EXP
,
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. ansi.stdlib.abort), the result shape may
be either TOP
or BOTTOM
.
ansi.setjmp.setjmp
jb: EXP -> EXPansi.setjmp.setjmp is a token which has the semantics and argument and result implementation shapes corresponding to the ANSI C macro setjmp declared within <setjmp.h>.
7.2.2. ansi.setjmp.longjmp
jb: EXP v: EXP -> EXPansi.setjmp.longjmp is a token which has the semantics and argument implementation shapes corresponding to the ANSI C macro longjmp declared within <setjmp.h>. The result shape may be either TOP or BOTTOM.
7.2.3. ~alloca
i: EXP -> EXP~alloca is a token which has the semantics and argument and result implementation shapes corresponding to the BSD specified function alloca.
7.2.4. ansi.stdarg.va_list, ansi.stdarg.__va_start,
ansi.stdarg.va_arg, ansi.stdarg.va_end
These four tokens are identical to the Interface Tokens ~va_list, ~__va_start, ~va_arg and ~va_end respectively.
Part of the TenDRA Web.
Crown
Copyright © 1998.