Sophie

Sophie

distrib > Mandriva > 9.2 > i586 > by-pkgid > cb5625aca3e4def202f3617de4d26932 > files > 25

c2hs-0.9.9-2mdk.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
 <TITLE>The Binding Generator C->Haskell: Implementation of Haskell Binding Modules</TITLE>
 <LINK HREF="c2hs-4.html" REL=next>
 <LINK HREF="c2hs-2.html" REL=previous>
 <LINK HREF="c2hs.html#toc3" REL=contents>
</HEAD>
<BODY>
<A HREF="c2hs-4.html">Next</A>
<A HREF="c2hs-2.html">Previous</A>
<A HREF="c2hs.html#toc3">Contents</A>
<HR>
<H2><A NAME="s3">3. Implementation of Haskell Binding Modules</A></H2>

<P>A discussion of binding modules, the principles behind the tool, and a
discussion of related work can be found in a research paper located at
<A HREF="http://www.cse.unsw.edu.au/~chak/papers/papers.html#c2hs">http://www.cse.unsw.edu.au/~chak/papers/papers.html#c2hs</A>.  All
features described in the paper, except <CODE>enum define</CODE> hooks are implemented
in the tool, but since the publication of the paper, the tool has been
extended further.
<P>Furthermore, the distribution contains examples that illustrate the use of
C-&gt;Haskell.  In the source distribution, these examples are located below
the directories <CODE>tests</CODE> and <CODE>examples</CODE>.  The latter contains a binding 
for the 
<A HREF="http://www.gnome.org">Gnome</A> HTTP 1.1 library
<CODE>ghttp</CODE>.  The sources of the marshalling library <CODE>C2HS</CODE> are in the
directory <CODE>lib</CODE> and contain a fair amount of comments, which should help
getting you started.
<P>Since version 0.8.1 the interface of the marshalling library <CODE>C2HS</CODE>
changed.  The new interface essentially consists of the new Haskell FFI
Marshalling Library.  More details about this library are provided in the next
section.  For backward compatibilitym the old interface (i.e., the pre-0.8.1
interface) can still be used by importing <CODE>C2HSDeprecated</CODE> instead of
<CODE>C2HS</CODE>.
<P>The remainder of this section describes the hooks that are available in
binding modules.
<P>
<H2><A NAME="ss3.1">3.1 Import Hooks</A>
</H2>

<P>
<BLOCKQUOTE><CODE>
{#import [qualified] <I>modid</I>#}
</CODE></BLOCKQUOTE>
<P>Is translated into the same syntactic form in Haskell, which implies that it
may be followed by an explicit import list.  Moreover, it implies that
the module <I>modid</I> is also generated by C-&gt;Haskell and instructs the
tool to read the file <I>modid</I><CODE>.chi</CODE>.
<P>If an explicit output file name is given (<CODE>--output</CODE> option), this name
determines the basename for the <CODE>.chi</CODE> file of the currently translated
module. 
<P>Currently, only pointer hooks generate information that is stored in a
<CODE>.chi</CODE> file and needs to be incorporated into any client module that makes
use of these pointer types.  It is, however, regarded as good style to use
import hooks for any module generated by C-&gt;Haskell.
<P>
<H2><A NAME="ss3.2">3.2 Context Hooks</A>
</H2>

<P>
<BLOCKQUOTE><CODE>
{#context [header = <I>header</I>] [lib = <I>lib</I>] [prefix = <I>prefix</I>]#}
</CODE></BLOCKQUOTE>
<P>Context hooks define a set of global configuration options.  Currently, there
are three parameters all of which are strings:
<UL>
<LI><EM>header</EM> is the C header file containing the definitions, which are
bound in the current binding module.</LI>
<LI><EM>lib</EM> is a dynamic library that contains symbols needed by the
present binding.</LI>
<LI><EM>prefix</EM> is an identifier prefix that may be omitted in the lexemes
of identifiers referring to C definitions in any binding hook.  The is useful
as C libraries often use a prefix, such as <CODE>gtk_</CODE>, as a form of poor man's
name spaces.  Any occurrence of underline characters between a prefix and the
main part of an identifier must also be dropped.  Case is not relevant in a
prefix.  In case of a conflict of the abbreviation with an explicitly defined
identifier, the explicit definition takes preference.</LI>
</UL>
<P>All three parameters are optional.  An example of a context hook is the
following:
<BLOCKQUOTE><CODE>
{#context header = "gtkwidget.h" prefix = "gtk"#}
</CODE></BLOCKQUOTE>
<P>If a binding module contains a binding hook, it must be the first hook in the
module.
<P>
<H2><A NAME="ss3.3">3.3 Type Hooks</A>
</H2>

<P>
<BLOCKQUOTE><CODE>
{#type <I>ident</I>#}
</CODE></BLOCKQUOTE>
<P>A type hooks maps a C type to a Haskell type.  As an example, consider
<P>
<BLOCKQUOTE><CODE>
type GInt = {#type gint#}
</CODE></BLOCKQUOTE>
<P>The type must be a defined type, primitive types, such as <CODE>int</CODE>, are not
admissible.
<P>
<H2><A NAME="ss3.4">3.4 Sizeof Hooks</A>
</H2>

<P>
<BLOCKQUOTE><CODE>
{#sizeof <I>ident</I>#}
</CODE></BLOCKQUOTE>
<P>A sizeof hooks maps a C type to its size in bytes.  As an example, consider
<P>
<BLOCKQUOTE><CODE>
gIntSize :: IntgIntSize  = {#sizeof gint#}
</CODE></BLOCKQUOTE>
<P>The type must be a defined type, primitive types, such as <CODE>int</CODE>, are not
admissible.  The size of primitive types can always be obtained using
<CODE>Storable.sizeOf</CODE>. 
<P>
<H2><A NAME="ss3.5">3.5 Enumeration Hooks</A>
</H2>

<P>
<BLOCKQUOTE><CODE>
{#enum <I>cid</I> [as <I>hsid</I>] {<I>alias1</I> , ... , <I>aliasn</I>}
[with prefix = <I>pref</I>] [deriving (<I>clid1</I> , ... , <I>clidn</I>)]#}
</CODE></BLOCKQUOTE>
<P>Rewrite the C enumeration called <I>cid</I> into a Haskell data type
declaration, which is made an instance of <CODE>Enum</CODE> such that the ordinals
match those of the enumeration values in C.  This takes explicit enumeration
values in the C definitions into account.  If <I>hsid</I> is given, this is
the name of the Haskell data type.  The identifiers <I>clid1</I> to <I>clidn</I>
are added to the deriving clause of the Haskell type.
<P>By default, the names of the C enumeration are used for the constructors in
Haskell.  If <I>alias1</I> is <CODE>underscoreToCase</CODE>, the original C names are
capitalised and the use of underscores is rewritten to caps.  Moreover,
<I>alias1</I> to <I>aliasn</I> may be aliases of the form <I>cid</I> <CODE>as</CODE>
<I>hsid</I>, which map individual C names to Haskell names.  Instead of the
global prefix introduced by a context hook, a local prefix <I>pref</I> can
optionally be specified.
<P>As an example, consider
<P>
<BLOCKQUOTE><CODE>
{#enum WindowType {underscoreToCase} deriving (Eq)#}
</CODE></BLOCKQUOTE>
<P><B>Note:</B> The <CODE>enum define</CODE> hooks described in the C-&gt;Haskell are not
implemented yet.
<P>
<H2><A NAME="ss3.6">3.6 Call Hooks</A>
</H2>

<P>
<BLOCKQUOTE><CODE>
{#call [fun] [unsafe] <I>cid</I> [as <I>hsid</I>]#}
</CODE></BLOCKQUOTE>
<P>A call hook rewrites to a call to the C function <I>cid</I> and also ensures
that the appropriate foreign import declaration is generated.  The tags
<CODE>fun</CODE> and <CODE>unsafe</CODE> specify that the external function is purely
functional and cannot re-enter the Haskell runtime, respectively.  If
<I>hsid</I> is present, it is used as the identifier for the foreign
declaration, which otherwise defaults to the <I>cid</I>.
<P>As an example, consider
<P>
<BLOCKQUOTE><CODE>
<PRE>
sin :: Float -> Float
sin  = {#call fun sin as "_sin"#}
</PRE>
</CODE></BLOCKQUOTE>
<P>
<H2><A NAME="ss3.7">3.7 Get Hooks</A>
</H2>

<P>
<BLOCKQUOTE><CODE>
{#get <I>apath</I>#}
</CODE></BLOCKQUOTE>
<P>A get hook supports accessing a member value of a C structure.  The hook
itself yields a function that, when given the address of a structure of the
right type, performs the structure access.  The member that is to be extracted
is specified by the access path <I>apath</I>.  Access paths are formed as
follows (following a subset of the C expression syntax):
<UL>
<LI>The root of any access path is a simple identifier, which denotes either
a type name or <CODE>struct</CODE> tag.</LI>
<LI>An access path of the form <CODE>*</CODE><I>apath</I> denotes dereferencing of
the pointer yielded by accessing the access path <I>apath</I>.</LI>
<LI>An access path of the form <I>apath</I><CODE>.</CODE><I>cid</I> specifies that the
value of the <CODE>struct</CODE> member called <I>cid</I> should be accessed.</LI>
<LI>Finally, an access path of the form <I>apath</I><CODE>-></CODE><I>cid</I>, as in
C, specifies a combination of dereferencing and member selection.</LI>
</UL>
<P>For example, we may have
<P>
<BLOCKQUOTE><CODE>
<PRE>
visualGetType              :: Visual -> IO VisualType
visualGetType (Visual vis)  = liftM cToEnum $ {#get Visual->type#} vis
</PRE>
</CODE></BLOCKQUOTE>
<P>
<H2><A NAME="ss3.8">3.8 Set Hooks</A>
</H2>

<P>
<BLOCKQUOTE><CODE>
{#get <I>apath</I>#}
</CODE></BLOCKQUOTE>
<P>Set hooks are formed in the same way as get hooks, but yield a function that
assigns a value to a member of a C structure.  These functions expect a pointer
to the structure as the first and the value to be assigned as the second
argument.  For example, we may have
<P>
<BLOCKQUOTE><CODE>
{#set sockaddr_in.sin_family#} addr_in (cFromEnum AF_NET)
</CODE></BLOCKQUOTE>
<P>
<H2><A NAME="ss3.9">3.9 Pointer Hooks</A>
</H2>

<P>
<BLOCKQUOTE><CODE>
{#pointer [*] <I>cid</I> [as <I>hsid</I>] [foreign | stable] [newtype | -&gt; <I>hsid2</I>]#}
</CODE></BLOCKQUOTE>
<P>A pointer hook facilitates the mapping of C to Haskell pointer types.  In
particular, it enables the use of <CODE>ForeignPtr</CODE> and <CODE>StablePtr</CODE> types and
defines type name translations for pointers to non-basic types.  In general,
such a hook establishes an association between the C type <I>cid</I> or
<CODE>*</CODE><I>cid</I> and the Haskell type <I>hsid</I>, where the latter defaults to
<I>cid</I> if not explicitly given.  The identifier <I>cid</I> will usually be a
type name, but in the case of <CODE>*</CODE><I>cid</I> may also be a struct, union, or
enum tag.  If both a type name and a tag of the same name are available, the
type name takes precedence.  Optionally, the Haskell representation of
the pointer can be by a <CODE>ForeignPtr</CODE> or <CODE>StablePtr</CODE> instead of a plain
<CODE>Ptr</CODE>.  If the <CODE>newtype</CODE> tag is given, the Haskell type <I>hsid</I> is
defined as a <CODE>newtype</CODE> rather than a transparent type synonym.  In case of
a <CODE>newtype</CODE>, the type argument to the Haskell pointer type will be
<I>hsid</I>, which gives a cyclic definition, but the type argument is here
really only used as a unique type tag.  Without <CODE>newtype</CODE>, the default
type argument is <CODE>()</CODE>, but another type can be specified after the symbol
<CODE>-&gt;</CODE>.
<P>For example, we may have
<P>
<BLOCKQUOTE><CODE>
<PRE>
{#pointer *GtkObject as Object foreign newtype#}
</PRE>
</CODE></BLOCKQUOTE>
<P>This will generate a new type <CODE>Object</CODE> as follows:
<P>
<BLOCKQUOTE><CODE>
<PRE>
newtype Object = Object (ForeignPtr Object)
</PRE>
</CODE></BLOCKQUOTE>
<P>which allows to export <CODE>Object</CODE> as an abstract type and facilitates type
checking at call sites of imported functions using the encapsulated foreign
pointer.  The latter is achieved by C-&gt;Haskell as follows.  The tool
remembers the association of the C type <CODE>*GtkObject</CODE> with the Haskell type
<CODE>Object</CODE>, and so, it generates for the C function
<P>
<BLOCKQUOTE><CODE>
<PRE>
void gtk_unref_object (GtkObject *obj);
</PRE>
</CODE></BLOCKQUOTE>
<P>the import declaration
<P>
<BLOCKQUOTE><CODE>
<PRE>
foreign import gtk_unref_object :: Object -> IO ()
</PRE>
</CODE></BLOCKQUOTE>
<P>This function can obviously only be applied to pointers of the right type, and
thus, protects against the common mistake of confusing the order of pointer
arguments in function calls.
<P>However, as the Haskell FFI does not allow to return <CODE>ForeignPtr</CODE>s from
function calls, the tool will use the type <CODE>Ptr HsName</CODE> in this case, where
<CODE>HsName</CODE> is the Haskell name of the type.  In the above example, that would
be <CODE>Ptr Object</CODE>.
<P>As an example that does not represent the pointer as an abstract type,
consider the C type declaration:
<P>
<BLOCKQUOTE><CODE>
<PRE>
typedef struct {int x, y;} *point;
</PRE>
</CODE></BLOCKQUOTE>
<P>We can represent it in Haskell as
<P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
data Point = Point {x :: Int, y :: Int}
{#pointer point as PointPtr -> Point#}
</PRE>
</CODE></BLOCKQUOTE>
<P>which will translate to
<P>
<BLOCKQUOTE><CODE>
<PRE>
data Point = Point {x :: Int, y :: Int}
type PointPtr = Ptr Point
</PRE>
</CODE></BLOCKQUOTE>
<P>and establish a type association between <CODE>point</CODE> and <CODE>PointPtr</CODE>.
<P><EM>Restriction:</EM> The name <I>cid</I> cannot be a basic C type (such as
<CODE>int</CODE>), it must be a defined name.
<P>
<H2><A NAME="ss3.10">3.10 Grammar Rules</A>
</H2>

<P>The following grammar rules define the syntax of binding hooks:
<BLOCKQUOTE><CODE>
<PRE>
hook     -> `{#' inner `#}'
inner    -> `import' ['qualified'] ident
          | `context' ctxt
          | `type' ident
          | `sizeof' ident
          | `enum' idalias trans [`with' prefix] [deriving]
          | `call' [`fun'] [`unsafe'] idalias
          | `get' apath
          | `set' apath
          | `pointer' ['*'] idalias ptrkind

ctxt     -> [`header' `=' string] [`lib' `=' string] [prefix]
idalias  -> ident [`as' ident]
prefix   -> `prefix' `=' string
deriving -> `deriving' `(' ident_1 `,' ... `,' ident_n `)'
apath    -> ident
          | `*' apath
          | apath `.' ident
          | apath `->' ident
trans    -> `{' alias_1 `,' ... `,' alias_n `}'
alias    -> `underscoreToCase'
          | ident `as' ident
ptrkind  -> [`foreign' | `stable'] ['newtype' | '->' ident]
</PRE>
</CODE></BLOCKQUOTE>
<P>
<HR>
<A HREF="c2hs-4.html">Next</A>
<A HREF="c2hs-2.html">Previous</A>
<A HREF="c2hs.html#toc3">Contents</A>
</BODY>
</HTML>