Subversion Repositories tendra.SVN

Rev

Blame | Last modification | View Log | RSS feed

<!-- Crown Copyright (c) 1998 -->
<HTML>
<HEAD>
<TITLE>CAPSULEs and UNITs</TITLE>
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#400080" ALINK="#FF0000">
<A NAME=S8>
<H1>TDF Guide, Issue 4.0 </H1>
<H3>January 1998</H3>
<A HREF="guide6.html"><IMG SRC="../images/next.gif" ALT="next section">
</A> <A HREF="guide4.html">
<IMG SRC="../images/prev.gif" ALT="previous section"></A>
<A HREF="guide1.html"><IMG SRC="../images/top.gif" ALT="current document"></A>
<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="#S9"><B>3.1 </B> - make_capsule and name-spaces</A><DD>
<DT><A HREF="#S10"><B>3.1.1 </B> - External linkages</A><DD>
<DT><A HREF="#S11"><B>3.1.2 </B> - UNITs</A><DD>
<DT><A HREF="#S12"><B>3.1.3 </B> - make_unit</A><DD>
<DT><A HREF="#S13"><B>3.1.4 </B> - LINK</A><DD>
<DT><A HREF="#S14"><B>3.2 </B> - Definitions and declarations</A><DD>
<DT><A HREF="#S15"><B>3.2.1 </B> - Scopes and linking</A><DD>
<DT><A HREF="#S16"><B>3.2.2 </B> - Declaration and definition signatures</A><DD>
<DT><A HREF="#S17"><B>3.2.3 </B> - STRING</A><DD>
</DL>
<HR>
<H1>3  CAPSULEs and UNITs</H1>
A CAPSULE is typically the result of a single compilation - one could
regard it as being the TDF analogue of a Unix .o file. Just as with
.o files, a set of CAPSULEs can be linked together to form another.
Similarly, a CAPSULE may be translated to make program for some platform,
provided certain conditions are met. One of these conditions is obviously
that a translator exists for the platform, but there are others. They
basically state that any names that are undefined in the CAPSULE can
be supplied by the system in which it is to be run. For example, the
translator could produce assembly code with external identifiers which
will be supplied by some system library.<P>
<A NAME=S9>
<HR><H2>3.1. <A NAME=2>make_capsule and name-spaces</H2>
The only constructor for a CAPSULE is make_capsule. Its basic function
is to compose together UNITs which contain the declarations and definitions
of the program. The signature of make_capsule looks rather daunting
and is probable best represented graphically.<P>
<CENTER>
<IMG SRC="../images/guide2.gif">
</CENTER>
<P>
The diagram gives an example of a CAPSULE using the same components
as in the following text. <P>
Each CAPSULE has its own name-space, distinct from all other CAPSULEs'
name-spaces and also from the name-spaces of its component UNITs (see
<A HREF="#11">section 3.1.2 on page 14</A>). There are several different
kinds of names in TDF and each name-space is further subdivided into
one for each kind of name. The number of different kinds of names
is potentially unlimited but only three are used in core-TDF, namely
&quot;tag&quot;, &quot;token&quot; and &quot;al_tag&quot;. Those names
in a &quot;tag&quot; name-space generally correspond to identifiers
in normal programs and I shall use these as the paradigm for the properties
of them all.<P>
The actual representations of a &quot;tag&quot; name in a given name-space
is an integer, described as SORT TDFINT. These integers are drawn
from a contiguous set starting from 0 up to some limit given by the
constructor which introduces the name-space. For CAPSULE name-spaces,
this is given by the <I>capsule_linking</I> parameter of make_capsule:<P>
<PRE>
<I>capsule_linking</I>: SLIST(CAPSULE_LINK)
</PRE>
In the most general case in core-TDF, there would be three entries
in the list introducing limits using make_capsule_link for each of
the &quot;tag&quot;, &quot;token&quot; and &quot;al_tag&quot; name-spaces
for the CAPSULE. Thus if: <P>
<PRE>
<I>capsule_linking</I> = (make_capsule_link(&quot;tag&quot;, 5), 
                                    make_capsule_link(&quot;token&quot;, 6), 
                                    make_capsule_link(&quot;al_tag&quot;, 7))
</PRE>
there are 5 CAPSULE &quot;tag&quot; names used within the CAPSULE,
namely 0, 1, 2, 3 and 4; similarly there are 6 &quot;token&quot; names
and 7 &quot;al_tag&quot; names.<P>
<A NAME=S10>
<H3>3.1.1. External linkages</H3>
The context of usage will always determine when and how an integer
is to be interpreted as a name in a particular name-space. For example,
a TAG in a UNIT is constructed by make_tag applied to a TDFINT which
will be interpreted as a name from that UNIT's &quot;tag&quot; name-space.
An integer representing a name in the CAPSULE name-space would be
found in a LINKEXTERN of the <I>external_linkage</I>
parameter of make_capsule.<P>
<PRE>
<I>external_linkage: </I>SLIST(EXTERN_LINK)
</PRE>
Each EXTERN_LINK is itself formed from an SLIST of LINKEXTERNs given
by make_extern_link . The order of the EXTERN_LINKs determines which
name-space one is dealing with; they are in the same order as given
by the <I>capsule_linkage</I>
parameter. Thus, with the <I>capsule_linkage</I> given above, the
first EXTERN_LINK would deal with the &quot;tag&quot; name-space;
Each of its component  LINKEXTERNs constructed by make_linkextern
would be identifying a tag number with some name external to the CAPSULE;
for example one might be:<P>
<PRE>
make_linkextern (4, string_extern(&quot;printf&quot;))
</PRE>
This would mean: identify the CAPSULE's &quot;tag&quot; 4 with an
name called &quot;printf&quot;, external to the module. The name &quot;printf&quot;
would be used to linkage external to the CAPSULE; any name required
outside the CAPSULE would have to be linked like this.<P>
<P>
<A NAME=S11>
<H3>3.1.2. <A NAME=11>UNITs</H3>
This name &quot;printf&quot;, of course, does not necessarily mean
the C procedure in the system library. This depends both on the system
context in which the CAPSULE is translated and also the meaning of
the CAPSULE &quot;tag&quot; name 4 given by the component UNITs of
the CAPSULE in the <I>groups</I> parameter of make_capsule:<P>
<PRE>
<I>groups: </I>SLIST(GROUP)
</PRE>
Each GROUP in the <I>groups</I> SLIST will be formed by sets of UNITs
of the same kind. Once again, there are a potentially unlimited number
of kinds of UNITs but core-TDF only uses those named &quot;tld&quot;,&quot;al_tagdefs&quot;,
&quot;tagdecs&quot;, &quot;tagdefs&quot;, &quot;tokdecs&quot; and
&quot;tokdefs&quot; 
<A NAME=footnote71 HREF="footnote.html#71">*</A>. These names will
appear (in the same order as in <I>groups</I>) in the <I>prop_names
</I>parameter of make_capsule, one for each kind of UNIT appearing
in the CAPSULE:<P>
<PRE>
<I>prop_names: </I>SLIST<I>(</I>TDFIDENT)
</PRE>
Thus if:<P>
<PRE>
<I>prop_names</I> = (&quot;tagdecs&quot;, &quot;tagdefs&quot;)
</PRE>
then, the first element of <I>groups</I> would contain only &quot;tagdecs&quot;
UNITs and and the second would contain only &quot;tagdefs&quot; UNITs.
A &quot;tagdecs&quot; UNIT contains things rather like a set of global
identifier declarations in C, while a &quot;tagdefs&quot; UNIT is
like a set of global definitions of identifiers.<P>
<A NAME=S12>
<H3>3.1.3. make_unit</H3>
Now we come to the construction of UNITs using make_unit, as in the
diagram below<P>
<CENTER>
<IMG SRC="../images/guide1.gif">
</CENTER>
<P>
First we give the limits of the various name-spaces local to the UNIT
in the <I>local_vars</I> parameter:<P>
<PRE>
<I>local_vars</I><I>: </I>SLIST(TDFINT<I>)</I>
</PRE>
Just in the same way as with <I>external_linkage</I>, the numbers
in local_vars correspond (in the same order) to the spaces indicated
in <I>capsule_linking</I> in <A HREF="#2">section 3.1 on page 13</A>.
With our example,the first element of <I>local_vars</I> gives the
number of &quot;tag&quot; names local to the UNIT, the second gives
the number of &quot;token&quot; names local to the UNIT etc. These
will include all the names used in the body of the UNIT. Each declaration
of a TAG, for example, will use a new number from the &quot;tag&quot;
name-space; there is no hiding or reuse of names within a UNIT.<P>
<A NAME=S13>
<H3>3.1.4. LINK</H3>
Connections between the CAPSULE name-spaces and the UNIT name-spaces
are made by LINKs in the <I>lks </I>parameter of make_unit: <P>
<PRE>
<I>lks</I>: SLIST(LINKS<I>)</I>
</PRE>
Once again, <I>lks</I> is effectively indexed by the kind of name-space
a. Each LINKS is an SLIST of LINKs each of which which establish an
identity between names in the CAPSULE name-space and names in the
UNIT name-space. Thus if the first element of <I>lks</I> contains:<P>
<PRE>
make_link(42, 4)
</PRE>
then, the UNIT &quot;tag&quot; 42 is identical to the CAPSULE &quot;tag&quot;
4.<P>
Note that names from the CAPSULE name-space only arise in two places,
LINKs and LINK_EXTERNs. Every other use of names are derived from
some UNIT name-space.<P>
<A NAME=S14>
<HR><H2>3.2. <A NAME=19>Definitions and declarations</H2>
The encoding in the <I>properties</I>:BYTSTREAM parameter of a UNIT
is a PROPS , for which there are five constructors corresponding to
the kinds of UNITs in core-TDF, make_al_tagdefs, make_tagdecs, make_tagdefs,
make_tokdefs and make_tokdecs. Each of these will declare or define
names in the appropriate UNIT name-space which can be used by make_link
in the UNIT's <I>lks</I>
parameter as well as elsewhere in the <I>properties</I> parameter.
The distinction between &quot;declarations&quot; and &quot;definitions&quot;
is rather similar to C usage; a declaration provides the &quot;type&quot;
of a name, while a definition gives its meaning. For tags, the &quot;type&quot;
is the SORT SHAPE (see below). For tokens, the &quot;type&quot; is
a SORTNAME constructed from the SORTNAMEs of the parameters and result
of the TOKEN using token: <P>
<PRE>
        <I>params</I>:  LIST(SORTNAME)
        <I>result</I>:  SORTNAME
                   -&gt; SORTNAME
</PRE>
Taking make_tagdefs as a paradigm for PROPS, we have:<P>
<PRE>
<I>     no_labels</I>:  TDFINT
<I>     tds</I>:        SLIST(TAGDEF)
                   -&gt; TAGDEF_PROPS
</PRE>
The <I>no_labels</I> parameter introduces the size of yet another
name-space local to the PROPS, this time for the LABELs used in the
TAGDEFs. Each TAGDEF in <I>tds</I> will define a &quot;tag&quot; name
in the UNIT's name-space. The order of these TAGDEFs is immaterial
since the initialisations of the tags are values which can be solved
at translate time, load time or as unordered dynamic initialisations.
<P>
There are three constructors for TAGDEFs, each with slightly different
properties. The simplest is make_id_tagdef:<P>
<PRE>
        <I>t</I>:       TDFINT  
        <I>signature</I>:       OPTION(STRING)
        <I>e</I>:       EXP <I>x</I>
                   -&gt; TAGDEF
</PRE>
Here, <I>t</I> is the tag name and the evaluation of <I>e</I> will
be the value of SHAPE <I>x</I> of an obtain_tag(<I>t</I>) in an EXP.
Note that t is not a variable; the value of obtain_tag(<I>t</I>) will
be invariant. The <I>signature</I> parameter gives a STRING (see 
<A HREF="#39">section 3.2.3 on page 18</A>) which may be used as an
name for the tag, external to TDF and also as a check introduced by
the producer that a tagdef and its corresponding tagdec have the same
notion of the language-specific type of the tag.<P>
<P>
The two other constructors for TAGDEF, make_var_tagdef and common_tagdef
both define variable tags and have the same signature: <P>
<PRE>
        <I>t</I>:       TDFINT
<I>     opt_access</I>: OPTION(ACCESS)
        <I>signature</I>:       OPTION(STRING)
        <I>e</I>:       EXP <I>x</I>
                   -&gt; TAGDEF
</PRE>
Once again <I>t</I> is tag name but now <I>e</I> is initialisation
of the variable <I>t</I>. A use of obtain_tag(<I>t</I>) will give
a pointer to the variable (of SHAPE POINTER x), rather than its contents
<A NAME=footnote72 HREF="footnote.html#72">*</A>. There can only be
one make_var_tagdef of a given tag in a program, but there may be
more than one common_tagdef, possibly with different initialisations;
however these initialisations must overlap consistently just as in
common blocks in FORTRAN.<P>
The ACCESS parameter gives various properties required for the tag
being defined and is discussed in <A HREF="guide7.html#40">section
5.3.2 on page 30</A>.<P>
The initialisation EXPs of TAGDEFs will be evaluated before the &quot;main&quot;
program is started. An initialiation EXP must either be a constant
(in the sense of <A HREF="guide11.html#0">section 9 on page 43</A>)
or reduce to (either directly or by token or _cond expansions) to
an initial_value:<P>
<PRE>
        <I>init</I>:    EXP <I>s</I>
                   -&gt; EXP <I>s</I>
</PRE>
The translator will arrange that <I>init</I> will be evaluated once
only before any procedure application, other than those themselves
involved in initial_values, but after any constant initialisations.
The order of evaluation of different initial_values is arbitrary.<P>
<A NAME=S15>
<H3>3.2.1. Scopes and linking</H3>
Only names introduced by AL_TAGDEFS, TAGDEFS, TAGDECs, TOKDECs and
TOKDEFs can be used in other UNITs (and then, only via the <I>lks</I>
parameters of the UNITs involved). You can regard them as being similar
to C global declarations. Token definitions include their declarations
implicitly; however this is not true of tags. This means that any
CAPSULE which uses or defines a tag across UNITs must include a TAGDEC
for that tag in its &quot;tagdecs&quot; UNITs. A TAGDEC is constructed
using either make_id_tagdec , make_var_tagdec or common_tagdec, all
with the same form:<P>
<PRE>
        <I>t_intro</I>: TDFINT
        <I>acc</I>:             OPTION(ACCESS)
        <I>signature</I>:       OPTION(STRING)
        <I>x</I>:               SHAPE
                   -&gt; TAGDEC
</PRE>
Here the tagname is given by <I>t_intro</I>; the SHAPE <I>x</I> will
defined the space and alignment required for the tag (this is analogous
to the type in a C declaration). The <I>acc</I> field will define
certain properties of the tag not implicit in its SHAPE; I shall return
to the kinds of properties envisaged in discussing local declarations
in <A HREF="guide7.html#34">section 5.3 on page 30</A>.<P>
Most program will appear in the &quot;tagdefs&quot; UNITs - they will
include the definitions of the procedures of the program which in
turn will include local definitions of tags for the locals of the
procedures.<P>
The standard TDF linker allows one to link CAPSULEs together using
the name identifications given in the LINKEXTERNs, perhaps hiding
some of them in the final CAPSULE. It does this just by generating
a new CAPSULE name-space, grouping together component UNITs of the
same kind and replacing their <I>lks</I> parameters with values derived
from the new CAPSULE name-space without changing the UNITs' name-spaces
or their <I>props</I> parameters. The operation of grouping together
UNITs is effectively assumed to be associative, commutative and idempotent
e.g. if the same tag is declared in two capsules it is assumed to
be the same thing . It also means that there is no implied order of
evaluation of UNITs or of their component TAGDEFs<P>
Different languages have different conventions for deciding how programs
are actually run. For example, C requires the presence of a suitably
defined &quot;main&quot; procedure; this is usually enforced by requiring
the system ld utility to bind the name &quot;main&quot; along with
the definitions of any library values required. Otherwise, the C conventions
are met by standard TDF linking. Other languages have more stringent
requirements. For example, C++ requires dynamic initialisation of
globals, using initial_value. As the only runnable code in TDF is
in procedures, C++ would probably require an additional linking phase
to construct a &quot;main&quot; procedure which calls the initialisation
procedures of each CAPSULE involved if the system linker did not provide
suitable C++ linking. <P>
<A NAME=S16>
<H3>3.2.2. <A NAME=37>Declaration and definition <I>signatures</I></H3>
The <I>signature</I> arguments of TAGDEFs and TAGDECs are designed
to allow a measure of cross-UNIT checking when linking independently
compiled CAPSULEs. Suppose that we have a tag, <I>t</I>, used in one
CAPSULE and defined in another; the first CAPSULE would have to have
a TAGDEC for <I>t</I> whose TAGDEF is in the second. The <I>signature</I>
STRING of both could be arranged to represent the language-specific
type of <I>t</I> as understood at compilation-time. Clearly, when
the CAPSULEs are linked the types must be identical and hence their
STRING representation must be the same - a translator will reject
any attempt to link definitions and declarations of the same object
with different signatures.<P>
Similar considerations apply to TOKDEFs and TOKDECs; the &quot;type&quot;
of a TOKEN may not have any familiar analogue in most HLLs, but the
principle remains the same.<P>
<A NAME=S17>
<H3>3.2.3. <A NAME=39>STRING</H3>
The SORT STRING is used in various constructs other than declarations
and definitions. It is a first-class SORT with  string_apply_token
and string_cond. A primitive STRING is constructed from a TDFSTRING(k,n)
which is an encoding of n integers,each of k bits, using make_string:
<P>
<PRE>
        <I>arg</I>:     TDFSTRING<I>(k, n)</I>
                   -&gt; STRING<I>(k, n)</I>
</PRE>
STRINGs may be concatenated using concat_string:<P>
<PRE>
        <I>arg1</I>:    STRING<I>(k, n)</I>
        <I>arg2</I>:    STRING<I>(k,m)</I>
                   -&gt; STRING<I>(k, n+m)</I>
</PRE>
Being able to compose strings, including token applications etc, means
that late-binding is possible in <I>signature</I> checking in definitions
and declarations. This late-binding means that the representation
of platform-dependent HLL types need only be fully expanded at install-time
and hence the types could be expressed in their representational form
on the specific platform.<P>
<P>
<HR>
<P><I>Part of the <A HREF="../index.html">TenDRA Web</A>.<BR>Crown
Copyright &copy; 1998.</I></P>
</BODY>
</HTML>