The following table gives the DIS functions that Green Card provides
as a ``standard prelude''.
DIS Haskell type C type Comments
==============================================================
int x Int int
char c Char char
float f Float float
double d Double double
bool b Bool int 0 for False, 1 for True
addr a Addr (void *) An (immovable) external address
string s String (char *) Persistence not required
in either direction.
foreign x f ForeignObj (void *x),
((void (*)())f) f is the free routine; it
takes one parameter, namely
x, the thing to be freed.
stable x any unsigned int Makes it possible to pass a
Haskell pointer to C, and
perhaps get it back later,
without breaking the
garbage collector.
maybe dis Maybe dis type of dis Converts to and from
Maybe's, with 0 as 'Nothing'
maybeT he d Maybe dis type of dis Converts to and from 'Maybe's
Several of the standard DISs involve types that go beyond standard
Haskell:
Addr is a type large enough to contain a machine
address. The Haskell garbage collector treats it as a non-pointer,
however.
ForeignObj is a type designed to contain a reference to a
foreign resource of some kind: a malloc'd structure, a file
descriptor, an window system graphical context, or some such. The
size of this reference is assumed to be that of a machine address.
When the Haskell garbage collector decides that a value of type
ForeignObj is unreachable, it calls the object's finalisation
routine, which was given as an address in the argument of the DIS. The
finalisation routine is passed the object reference as its only
argument.
The stable DIS maps a value of any type onto a C unsigned
int. The unsigned int is actually an index into the stable
pointer table, which is treated as a source of roots by the garbage
collector. Thus the C procedure can effectively get a reference into
the Haskell heap. When stable is used to map from C to Haskell,
the process is reversed.
Almost all DISs work on single-constructor data types.
It is much less obvious how to translate values of multi-constructor
data types to and from C. Nevertheless, Green Card does deal in an
ad hoc fashion with the Maybe type, because it seems so
important. The syntax for the maybeT DIS is:
maybeT hexp dis
where dis is any DIS, and hexp is a Haskell
expression which you want to map to the Nothing value.
In the following example, the function foo takes an argument of
type Maybe Int. If the argument value is Nothing it will
bind x to 0; if it is Just a it will bind x to the
value of a. The return value will be Just r unless r == -1
in which case it will be Nothing.
%fun foo :: Maybe Int -> Maybe Int
%call (maybeT { 0 } (int x))
%code r = foo(x);
%result (maybeT { -1 } (int r))
There is also a maybe DIS wich just takes the DIS and defaults to
0 as the Nothing value.