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 ‘float’); ‘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 ‘MR_Word’ otherwise.
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 this.)
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 of type ‘MR_Word’. 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 than ‘sizeof(MR_Word)’.