For each of the Mercury types
string, there is a C typedef for the corresponding type in C:
In the current implementation,
MR_Integer is a typedef for a signed
integral type whose size is the same size as a pointer of type ‘void *’;
MR_Float is a typedef for
double (unless the program and the
Mercury library was compiled with ‘--single-prec-float’, in which case it
is a typedef for
MR_Char is a typedef for a signed
32-bit integral type and
MR_String is a typedef for ‘char *’.
Mercury variables of type
string are passed to and from C as C variables whose type is
given by the corresponding typedef.
For the Mercury standard library type ‘bool.bool’, there is a
corresponding C type,
MR_Bool. C code can refer to the boolean
data constructors ‘yes’ and ‘no’, as
For the Mercury standard library type ‘builtin.comparison_result’, there
is a corresponding C type,
MR_Comparison_Result. C code can refer
to the data constructors of this type, ‘(<)’, ‘(=)’ and ‘(>)’,
Mercury variables of a type for which there is a C ‘pragma foreign_type’ declaration (see Using foreign types from Mercury) will be passed as the corresponding C type.
Mercury tuple types are passed as
MR_Tuple, which in the current
implementation is a typedef for a pointer of type ‘void *’ if
‘--high-level-code’ is enabled, and a typedef for
Mercury variables of any other type
are passed as a
MR_Word, which in the current implementation
is a typedef for an unsigned type whose size is the same size as a pointer.
(Note: it would in fact be better for each Mercury type to map to a distinct
abstract type in C, since that would be more type-safe, and thus we may
change this in a future release. We advise programmers who are manipulating
Mercury types in C code to use typedefs for each user-defined Mercury type,
and to treat each such type as an abstract data type. This is good style
and it will also minimize any compatibility problems if and when we do change
Mercury lists can be manipulated by C code using the following macros, which are defined by the Mercury implementation.
MR_list_is_empty(list) /* test if a list is empty */ MR_list_head(list) /* get the head of a list */ MR_list_tail(list) /* get the tail of a list */ MR_list_empty() /* create an empty list */ MR_list_cons(head,tail) /* construct a list with the given head and tail */
Note that the use of these macros is subject to some caveats (see Memory management for C).
The implementation provides the macro
MR_word_to_float for converting a
value of type
MR_Word to one of type
MR_Float, and the macro
MR_float_to_word for converting a value of type
MR_Float to one
These macros must be used to perform these conversions since for some Mercury
implementations ‘sizeof(MR_Float)’ is greater than ‘sizeof(MR_Word)’.
The following fragment of C code illustrates the correct way to extract the head of a Mercury list of floats.
MR_Float f; f = MR_word_to_float(MR_list_head(list));
Omitting the call to
MR_word_to_float in the above example would yield
incorrect results for implementations where ‘sizeof(MR_Float)’ is greater