GreenCard for nhc13
GreenCard is a preprocessor for Haskell which allows Haskell
functions to call C. A paper (now superseded, see below) published in
the Haskell Workshop 97 proceedings describes the design goals, input
language, and translation mechanism. GreenCard is standard
across (almost) all implementations of Haskell.
Since the Haskell Workshop paper, several improvements have been made
to the input language and DIS macros. GreenCard for nhc13
follows the currently-agreed design. The only
up-to-date description
(of which we are aware) is published solely in HTML format.
There are just a few differences specific to the nhc13 version
of the tool.
- Some features are not yet implemented.
- %fail is currently ignored
silently; %const generates a warning and terminates processing;
you cannot yet use named fields (sometimes known as records) in DIS
definitions.
- Import clause needed.
- The code generated by GreenCard uses certain library
functions, which may not be visible in the source submitted to
GreenCard. To make things easier, we have collected these
functions together into a single library module, which should always
be imported when you use GreenCard. Simply add the line
import GreenCard
to your source file. GreenCard cannot add this line for
you automatically.
- Filename conventions.
- Source files containing GreenCard directives should have a
.gc extension. Both nhc13 and nhc13make
recognise the .gc extension and call GreenCard
automatically. When GreenCard is run on a file
Module.gc it generates two new files Module_.hs
and Module_.c which are processed separately by
nhc13 proper and gcc. The end result however is
still a single object file called Module.o. (We thought it
would be useful to expose the generated files to the user, since
any compilation errors will refer to these rather than to the
original source (although of course the error must be fixed in the
original .gc file)).
- Calling Haskell from C.
- The Haskell Workshop paper said that "in practice there is zero demand"
for calling Haskell from C. We disagree. Using "stable pointers"
however, it is possible to go some distance towards providing such a
facility. See the document
CcallingHaskell and
file $NHC13DIR/lib/greencard.h for details.
- DIS variable scope.
- The original paper said: "All the C variables bound in the
%call statement, and all those bound in declarations at the start of
the body scope over all the result-marshalling statements (%result and
%fail)". However, it did not say anything about the scope of
variables bound by a %result statement. We say that variables bound
in a %result statement are always declared implicitly and scope over
the whole body. For example, from the paper:
%fun foo :: (Age,Age) -> Age
%call (Age (int x), Age (int y))
%code r = foo(x,y);
%result (Age (int r))
This example is correct, and indicates that the three variables x y and r
are all declared as "int"s prior to the %code body, and scope over the
body.
%fun f :: This -> This
%call (MkThis (int p) (float q, float r))
%code int a,b,c;
% f( p, q, r, &a, &b, &c);
%result (this a b c)
But this example is incorrect, because the user's definitions of a b and c
conflict with the automatic definition from the %result statement. (The
variables b and c are "float"s, but the user has tried to declare them as
"int"s.
The latest updates to these pages are available on the WWW from
http://www.cs.york.ac.uk/fp/nhc13/
1997.11.26
York Functional Programming Group
Malcolm.Wallace@cs.york.ac.uk
|