[m-dev.] diff: additions to samples/c_interface
Fergus Henderson
fjh at cs.mu.oz.au
Thu Jul 24 19:32:17 AEST 1997
Hi,
Can someone please review this?
doc/reference_manual.texi:
Document `pragma export'.
Also various minor corrections.
cvs diff: Diffing .
Index: reference_manual.texi
===================================================================
RCS file: /home/staff/zs/imp/mercury/doc/reference_manual.texi,v
retrieving revision 1.59
diff -u -r1.59 reference_manual.texi
--- reference_manual.texi 1997/07/23 20:04:42 1.59
+++ reference_manual.texi 1997/07/24 09:31:44
@@ -352,7 +352,7 @@
compiler hints about inlining, and the remainder are for the module system.
They are described in more detail in their respective chapters.
-(The current implementation allows @samp{when/2} declarations,
+(The current implementation also allows @samp{when/2} declarations,
but ignores them.
This helps when one wants to write a program
that is both a Mercury program and an NU-Prolog program.)
@@ -941,8 +941,6 @@
There must only be one predicate with a given name and arity in each module,
and only one function with a given name and arity in each module.
-The current implementation does not support defining a function of arity
- at var{N} and a predicate of arity @var{N+1} in the same module.
The compiler infers the types of data-terms, and in particular the types
of variables and overloaded constructors, functions, and predicates.
@@ -1861,7 +1859,7 @@
even though the lists used to represent the sets
might not be in the same order in every solution.
-However, the current implementation does not yet support
+However, the language does not yet support
either the @samp{unique} quantifier or user-defined equivalence relations.
@node Committed choice nondeterminism
@@ -2498,17 +2496,15 @@
will work correctly on every implementation, under every possible
implementation-defined semantics.
-The University of Melbourne Mercury implementation will offer eight
+The University of Melbourne Mercury implementation offers eight
different semantics, which will be selected with different
combinations of the @samp{--no-reorder-conj}, @samp{--no-reorder-disj},
and @samp{--fully-strict} options. (The @samp{--fully-strict} option
-will prevent
-the compiler from improving completeness by optimizing away infinite
+prevents the compiler from improving completeness by optimizing away infinite
loops or calls to @code{error/1}.) The default semantics will be the
commutative semantics. Enabling all of these options will give you the
the strict sequential semantics. Enabling just some of them will give
-you a semantics somewhere in between. (At the time of writing, however,
-these options had not been implemented.)
+you a semantics somewhere in between.
Future implementations of Mercury may wish to offer other operational semantics.
For example, they may wish to provide semantics in which function
@@ -2527,12 +2523,12 @@
from Mercury code, and vice versa.
* Inlining:: Pragmas can be used to suggest or prevent
procedure inlining.
-* Obsolescence:: Library developers can declare old versions
- of predicates or functions to be obsolete.
-* Source file name:: The @samp{source_file} pragma and
- @samp{#@var{line}} directives provide support
- for preprocessors and other tools that
- generate Mercury code.
+* Obsolescence:: Library developers can declare old versions
+ of predicates or functions to be obsolete.
+* Source file name:: The @samp{source_file} pragma and
+ @samp{#@var{line}} directives provide support
+ for preprocessors and other tools that
+ generate Mercury code.
@end menu
@c * Tabling:: Mercury predicates can be evaluated
@c using a three different forms of tabled
@@ -2543,22 +2539,29 @@
@section C interface
@menu
-* Calling C code:: How to call C code whenever there is
- a call to a Mercury predicate.
+* Calling C code from Mercury:: How to implement a Mercury predicate
+ or function as a call to C code.
* Including C headers:: Using functions with prototypes from a
non-standard header file.
* Including C code:: Including definitions of C
- functions in your Mercury code.
+ functions in your Mercury code.
* Linking with C object files:: Linking with C object files and
libraries.
+* Calling Mercury code from C:: How to export a Mercury function or
+ predicate for use by C code.
* Passing data to and from C:: Exchanging simple data types between
Mercury and C.
* Using C pointers:: Maintaining a reference to C data
structures in Mercury code.
@end menu
- at node Calling C code
- at subsection Calling C code
+The Mercury distribution includes a number of examples of the
+use of the C interface that show how to interface C++ with Mercury
+and how to set up @samp{Mmake} files to automate the build process.
+See the @samp{samples/c_interface} directory in the Mercury distribution.
+
+ at node Calling C code from Mercury
+ at subsection Calling C code from Mercury
A declaration of the form
@@ -2571,7 +2574,7 @@
@var{Mode2}, ...) being replaced by the C code given in @var{C_Code}.
If there is a @code{pragma c_code} declaration for a mode of a predicate,
-then that mode of the predicate must be det or semidet,
+then that mode of the predicate may not be @samp{multi} or @samp{nondet},
there must not be any clauses for that predicate,
and there must be a @code{pragma c_code} goal for every mode of the predicate.
@@ -2598,25 +2601,32 @@
(If you use this form, and the C code @emph{does} invoke Mercury code,
then the behaviour is undefined --- your program may misbehave or crash.)
- at c XXX may assume vars of input args are defined; must assign to output args
-
The C code in a @code{pragma c_code} declaration
-for a semidet mode of a predicate
+for any procedure whose determinism indicates that it could fail
must assign a truth value to the macro @var{SUCCESS_INDICATOR}.
-SUCCESS_INDICATOR should not be used other as the target of an assignment.
-(For example, it may be @code{#define}d to a register, so you should not try to
-take its address.)
-
- at c XXX must assign to output args iff SUCCESS_INDICATOR is set to true
+For example:
@example
:- pred string__contains_char(string, character).
:- mode string__contains_char(in, in) is semidet.
-:- pragma(c_code, string__contains_char(Str::in, Ch::in), will_not_call_mercury,
- "SUCCESS_INDICATOR = (strchr(Str, Ch) != NULL);").
+:- pragma c_code(string__contains_char(Str::in, Ch::in),
+ will_not_call_mercury,
+ "SUCCESS_INDICATOR = (strchr(Str, Ch) != NULL);").
@end example
+SUCCESS_INDICATOR should not be used other as the target of an assignment.
+(For example, it may be @code{#define}d to a register, so you should not
+try to take its address.)
+Procedures whose determinism indicates that that they cannot fail
+should not access SUCCESS_INDICATOR.
+
+Arguments whose mode is input will have their values set by the
+Mercury implementation on entry to the C code. If the procedure
+succeeds, the C code must set the values of all output arguments
+before returning. If the procedure fails, the C code need only
+set SUCCESS_INDICATOR to false (zero).
+
@node Including C headers
@subsection Including C headers
@@ -2652,8 +2662,8 @@
struct Employee @{
char name[SIZE];
@}
- extern int bar;
- extern void foo(void);
+ extern int bar;
+ extern void foo(void);
").
@end example
@@ -2675,16 +2685,76 @@
@example
:- pragma c_code("
- int bar = 42;
- void foo(void) @{@}
+ int bar = 42;
+ void foo(void) @{@}
").
@end example
Such code is copied verbatim into the generated C file.
+ at node Calling Mercury code from C
+ at subsection Calling Mercury code from C
+
+It is also possible to export Mercury procedures to C,
+so that you can call Mercury code from C (or from
+other languages that can interface to C, e.g. C++).
+
+A declaration of one the form
+
+ at example
+:- pragma export(@var{Pred}(@var{Mode1}, @var{Mode2}, ...), "@var{C_Name_1}").
+ at end example
+
+ at noindent
+or
+
+ at example
+:- pragma export(@var{Func}(@var{Mode1}, @var{Mode2}, ...) = @var{Mode}, "@var{C_Name_2}").
+ at end example
+
+ at noindent
+exports a procedure for use by C.
+
+For each Mercury module containing @samp{pragma export} declarations,
+the Mercury implementation will automatically create a header file
+for that module which declares a C function @var{C_Name()}
+for each of the @samp{pragma export} declarations.
+Each such C function is the C interface to the specified mode of
+the specified Mercury predicate or function.
+
+The interface to a Mercury procedure is determined as follows.
+Input arguments are passed by value. For output arguments, the
+caller must pass the address in which to store the result.
+If the Mercury procedure can fail, then its C interface function
+returns a truth value indicating success or failure.
+If the Mercury procedure is a Mercury function that cannot fail, and
+the function result has an output mode, then the C interface
+function will return the Mercury function result value.
+Otherwise the function result is appended as an extra argument.
+
+Calling polymorphically typed Mercury procedures from C is a little bit
+more difficult than calling ordinary (monomorphic) Mercury procedures.
+The simplest method is to just create monomorphic forwarding
+procedures that call the polymorphic procedures, and export them,
+rather than exporting the polymorphic procedures.
+
+If you do export a polymorphically typed Mercury procedure, the compiler
+will prepend one @samp{type_info} argument to the parameter list of
+the C interface function for each polymorphic type variable in the
+Mercury procedure's type signature. The caller must arrange to pass
+in appropriate @samp{type_info} values corresponding to the types
+of the other arguments passed. These @samp{type_info} arguments can
+be obtained using the Mercury @samp{type_of} function in the Mercury
+standard library module @samp{std_util}.
+
@node Linking with C object files
@subsection Linking with C object files
+A Mercury implementation should allow you to link with
+The exact mechanism for linking with C object files is
+implementation-dependent. The following text describes how
+it is done for the University of Melbourne Mercury implementation.
+
To link an existing object file or library into the Mercury executable,
set the @samp{Mmake} variable @samp{MLLIBS} in the
@samp{Mmake} file in the directory in which you are working. For
@@ -2697,6 +2767,9 @@
As illustrated by the example, the values for @samp{MLLIBS} are similar to
those taken by the Unix linker.
+For more information, see the ``Libraries'' chapter of the
+Mercury users guide, and the @samp{man} pages for @samp{mmc} and @samp{ml}.
+
@node Passing data to and from C
@subsection Passing data to and from C
@@ -2765,11 +2838,11 @@
");
:- pragma c_code(initialise_complicated_structure(Structure::uo),
- may_call_mercury,
+ may_call_mercury,
"Structure = init_struct();").
:- pragma c_code(do_calculation(Value::in, Structure0::di, Structure::uo,
- may_call_mercury,
+ may_call_mercury,
"Structure = perform_calculation(Value, Structure0);").
@end example
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list