Green Card pays attention only to Green Card directives, each of which
starts with a ``%'' at the beginning of a line. All other lines
are passed through to the output Haskell file unchanged.
The syntax of Green Card directives is as follows (the syntax for
dis is given in Section 9.1):
Program : Declaration_1
Declaration_n n >= 1
Declaration : Procedure
| '%const' [Var] [Var1 .. Varn]
| '%enum' [Var] Derivings
Type [Var1 .. Varn]
| '%dis' [Var1] [Var1 .. Varn] '=' dis
| '%#include' Filename
| '%prefix' Var
| '%C' ccode
Procedure : [Signature] [call] [ccode] [result]
Signature : '%fun' Var :: Type
Type : Var
| Var Type
| Type '->' Type
| '(' Type_1, ... , Type_n ')' n >= 1
Call : '%call' Dis_1 ... Dis_n
Result : '%fail' Cexp Cexp [Result]
| '%end' Cexp
| '%result' Dis
Cexp : anything up until '}' is encountered.
Ccode : '%code' Var
| '%safecode' Var
Filename : '<' Var '>'
| '"' Var '"'
Green Card understands the following directives:
%fun begins a procedure specification, which describes
the interface to a single C procedure, see Section 6.
%dis allows the programmer to describe a new
Data Interface Scheme (DIS). A DIS describes how to translate,
or marshall, data from Haskell to C and back again, see Section 9.
%const makes it easy to generate a collection of new Haskell
constants derived from C constants. This can be done with %fun, but
%const is much more concise, see Section 8.1.
%enum is similar to %const, but supports the mapping
of external constants to a corresponding Haskell data type, see
%prefix makes it easy to remove standard prefixes from the
Haskell function name, those are usually not needed since Haskell
allows qualified imports, see Section 8.3.
Procedure specifications can, as we shall see, contain fragments
of C. %#include tells Green Card to arrange that a specified
C header file will be included with the C code in the procedure
specifications when the latter is fed to a C compiler, see
``%C'' allows you to write fragments of C code which sits
outside any procedure specification. (We shall later see how to
include fragments of C code within procedures.) The entire line
of text following this directive is simply copied verbatim to the
generated C module.
A directive can span more than one line, but the continuation lines
must each start with a % followed by some whitespace. For
%fun draw :: Int -- Length in pixels
% -> Maybe Int -- Width in pixels
% -> IO ()
Haskell-style comments are permitted in Green Card directives (except,
for obvious reasons, ``%C''.)
A general principle we have followed is to define a single, explicit
(and hence long-winded) general mechanism, that should deal with just
about anything, and then define convenient abbreviations that save the
programmer from writing out the general mechanism in many common
cases. We have erred on the conservative side in defining such
abbreviations; that is, we have only defined an abbreviation where
doing without it seemed unreasonably long-winded, and where there
seemed to be a systematic way of defining an abbreviation.