[m-rev.] for review: il as a foreign language

Tyson Dowd trd at cs.mu.OZ.AU
Tue Jul 17 19:48:30 AEST 2001


Ok, here's a relative diff of the suggestions you made. 


Estimated hours taken: 5
Branches: main

Begin documenting foreign_proc.

doc/reference_manual.texi:
	Add a section for foreign_proc (and other multi-language foreign
	language interfacing pragmas).
	At the moment we have some reasonable documentation for "C" and
	"IL" foreign_proc, and some documentation on foreign_decl and
	foreign_code for C.

doc/user_guide.texi:
	The language and implementation specific documentation of
	the foreign language interface.


diff -u doc/reference_manual.texi doc/reference_manual.texi
--- doc/reference_manual.texi
+++ doc/reference_manual.texi
@@ -97,8 +97,8 @@
                       collections.
 * Semantics::         Declarative and operational semantics of Mercury
                       programs.
-* Foreign language interface:: The foreign language interface allows
-		      C code to be called from Mercury code.
+* Foreign language interface:: Calling code written in other programming
+  			languages from Mercury code
 * C interface::       The C interface allows C code to be called
                       from Mercury code, and vice versa.
 * Impurity::          Users can write impure Mercury code.
@@ -4681,9 +4681,16 @@
 
 @menu
 * Calling foreign code from Mercury::  How to implement a Mercury predicate
-				       or function as a call to foreign
-				       language code.
-* Language specific bindings       ::  Information specific to each
+				       or function as a call to code
+				       written in a different
+				       programming language.
+* Adding foreign declarations::        How to add declarations of
+  				       enities in other programming
+				       languages.
+* Adding foreign definitions::         How to add definitions of entities
+  				       enities in other programming
+				       languages.
+* Language specific bindings::         Information specific to each
   				       foreign language.
 @end menu
 
@@ -4693,8 +4700,8 @@
 See the @pxref{C interface} chapter for the existing, supported C
 interface for Mercury.
 
-The syntax, documentation, behaviour and semantics of this chapter are
-subject to change without notice.
+The syntax, documentation, behaviour and semantics described in this
+chapter are subject to change without notice.
 
 @node Calling foreign code from Mercury
 @section Calling foreign code from Mercury
@@ -4729,7 +4736,12 @@
 @noindent
 means that any calls to the specified mode of @var{Pred} or @var{Func}
 will result in execution of the foreign code given in @var{Foreign_Code}
-written in language @var{Lang}.
+written in language @var{Lang}, if @var{Lang} is selected as the foreign
+language code by this implementation. 
+See the ``Foreign Language Interface'' chapter of the
+Mercury User's Guide, for more information about how the implementation
+selects the approriate @samp{foreign_proc} to use.
+
 The foreign code fragment may refer to the specified variables
 (@var{Var1}, @var{Var2}, @dots{}, and @var{Var})
 directly by name.
@@ -4739,18 +4751,20 @@
 implementation specific rules.
 
 Additional restrictions on the foreign language interface code
-depend on the foreign language, the backend target, and the implementation.
+depend on the foreign language and compilation options.
 For more information, including the list of supported foreign languages and 
 the strings used to identify them, see the language specific information
-in the rest of this chapter.
+in the ``Foreign Language Interface'' chapter of the
+Mercury User's Guide.
 
-If there is a @code{pragma foreign_proc} declaration for any
-mode of a predicate or function, then there must not be either a mode
+If there is one @code{pragma foreign_proc} declaration for any
+mode of a predicate or function, then there must be either a mode
 specific clause, or a @code{pragma foreign_proc} 
 @c or @code{pragma import} 
 declaration for every mode of the predicate or function.
 
-For example, the following piece of code defines a Mercury function
+Here's an example of code using @samp{pragma foreign_proc}:
+The following code defines a Mercury function
 @samp{sin/1} which calls the C function @samp{sin()} of the same name.
 
 @example
@@ -4771,7 +4785,9 @@
 @node Foreign code attributes
 @subsection Foreign code attributes
 
-As described above, @samp{pragma import} and @samp{pragma c_code}
+As described above, 
+ at c @samp{pragma import} and 
+ at samp{pragma foreign_proc}
 declarations may include a list of attributes describing properties
 of the given foreign function or code.
 All Mercury implementations must support the attributes listed below.
@@ -4783,21 +4799,23 @@
 @table @asis
 
 @item @samp{may_call_mercury}/@samp{will_not_call_mercury}
-This attribute declares whether or not execution inside this C code may
-call back into Mercury or not.  The default, in case neither is specified,
-is @samp{may_call_mercury}.  Specifying @samp{will_not_call_mercury}
-may allow the compiler to generate more efficient code.
+This attribute declares whether or not execution inside this foreign
+language code may call back into Mercury or not.  The default, in case
+neither is specified, is @samp{may_call_mercury}.
+Specifying @samp{will_not_call_mercury} may allow the compiler to
+generate more efficient code.
 If you specify @samp{will_not_call_mercury},
-but the C code @emph{does} invoke Mercury code, then the behaviour is
-undefined.
+but the foreign language code @emph{does} invoke Mercury code, then the
+behaviour is undefined.
 
 @item @samp{thread_safe}/@samp{not_thread_safe}
 This attribute declares whether or not it is safe for multiple threads
-to execute this C code concurrently.
+to execute this foreign language code concurrently.
 The default, in case neither is specified, is @samp{not_thread_safe}.
-If the C code is declared @samp{thread_safe}, then the Mercury implementation
-is permitted to execute the code concurrently from multiple threads without
-taking any special precautions.  If the C code is declared
+If the foreign language code is declared @samp{thread_safe}, then the
+Mercury implementation is permitted to execute the code concurrently
+from multiple threads without taking any special precautions.  If the
+foreign language code is declared
 @samp{not_thread_safe},
 then the Mercury implementation must not invoke the code concurrently from
 multiple threads.  If the Mercury implementation does use multithreading,
@@ -4806,9 +4824,10 @@
 University of Melbourne Mercury implementation protects
 @samp{not_thread_safe} code using a mutex:
 C code that is not thread-safe has code inserted around it to obtain
-and release a mutex.  All non-thread-safe C code shares a single mutex.)
- at c XXX this can cause deadlocks if not_thread_safe C code calls
- at c     Mercury which calls C
+and release a mutex.  All non-thread-safe foreign language code shares a
+single mutex.)
+ at c XXX this can cause deadlocks if not_thread_safe foreign language code calls
+ at c     Mercury which calls foreign language code
 @end table
 
 Additional attributes which are supported by the Melbourne Mercury
@@ -4818,7 +4837,7 @@
 
 @item @samp{max_stack_size(Size)}
 This attribute declares the maximum stack usage of a particular piece of
-code.  The unit @samp{Size} is measured in depend upon foreign language
+code.  The unit that @samp{Size} is measured in depends upon foreign language
 being used.  
 Currently this attribute is only used (and is in fact required) by the 
 @samp{IL} foreign language interface, and is measured in units of stack
@@ -4828,6 +4847,35 @@
 
 @c -----------------------------------------------------------------------
 
+ at node Adding foreign declarations
+ at section Adding foreign declarations
+
+Foreign language declarations (such as type declarations, header file
+inclusions or macro defintions) can included in the Mercury source file as
+part of a @samp{foreign_decl} declaration of the form
+
+ at example
+:- pragma foreign_decl("@var{Lang}", @var{DeclCode}).
+ at end example
+
+The semantics of @samp{foreign_decl} depend upon the implementation and
+foreign language used. 
+
+ at node Adding foreign definitions
+ at section Adding foreign definitions
+
+Definitions of foreign language entities (such as functions or global
+variables) may be included using a declaration of the form
+
+ at example
+:- pragma foreign_code("@var{Lang}", @var{Code}).
+ at end example
+
+The semantics of @samp{foreign_code} depend upon the implementation and
+foreign language used. 
+
+ at c -----------------------------------------------------------------------
+
 @node Language specific bindings
 @section Language specific bindings
 
@@ -4838,138 +4886,21 @@
 
 @item @samp{C}
 Use the string "C" to set the foreign language to C.
-Default foreign language on all backends which compile to C.
-Only available on backends that do compile to C.
 
 @item @samp{Managed C++}
 Use the string "MC++" to set the foreign language to Managed C++.
-Default foreign language on all backends which compile to IL.
-Only available on backends that compile to IL.
-Requires a Managed Extensions for C++ compiler installed.
 
 @item @samp{C#}
 Use the string "C#" to set the foreign language to C#.
-Only available on backends that compile to IL.
-Requires a C# compiler installed.
-To use the pass mmc @samp{--use-foreign-language csharp} and
- at samp{--backend-foreign-language csharp}.
 
 @item @samp{IL}
 Use the string "IL" to set the foreign language to IL.
-Only available on backends that compile to IL.
-Requires an IL assembler installed.
-To use the pass mmc @samp{--use-foreign-language il} and
- at samp{--backend-foreign-language il}.
 
 @end table
 
- at menu
-* Interfacing with C 		:: How to write code to interface with C
-* Interfacing with Managed C++ 	:: How to write code to interface with
-* Interfacing with C# 		:: How to write code to interface with C#
-* Interfacing with IL 		:: How to write code to interface with IL
-  				   Managed C++
- at end menu
-
- at node Interfacing with C
- at subsection Interfacing with C
-
-The input and output variables will have C types corresponding
-to their Mercury types, as determined by the rules specified in
- at ref{Passing data to and from C}. 
-
-The C code fragment may declare local variables, but it should not
-declare any labels or static variables unless there is also a Mercury
- at samp{pragma no_inline} declaration (@pxref{Inlining}) for the procedure.
-The reason for this is that otherwise the Mercury implementation may
-inline the procedure by duplicating the C code fragment for each call.
-If the C code fragment declared a static variable, inlining it in this
-way could result in the program having multiple instances of the static
-variable, rather than a single shared instance.  If the C code fragment
-declared a label, inlining it in this way could result in an error due
-to the same label being defined twice inside a single C function.
-
-C code in a @code{pragma foreign_proc} declaration
-for any procedure whose determinism indicates that it could fail
-must assign a truth value to the macro @samp{SUCCESS_INDICATOR}.
-For example:
-
- at example
-:- pred string__contains_char(string, character).
-:- mode string__contains_char(in, in) is semidet.
-
-:- pragma foreign_proc("C", string__contains_char(Str::in, Ch::in),
-        [will_not_call_mercury],
-        "SUCCESS_INDICATOR = (strchr(Str, Ch) != NULL);").
- at end example
-
- at code{SUCCESS_INDICATOR} should not be used other than 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 @code{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 @code{SUCCESS_INDICATOR} to false (zero).
-
- at node Interfacing with C#
- at subsection Interfacing with C#
-
-Currently undocumented, sorry.
-
- at node Interfacing with Managed C++
- at subsection Interfacing with Managed C++
-
-Currently undocumented, sorry.
-
- at node Interfacing with IL
- at subsection Interfacing with IL
-
-Variables can be accessed from IL by using ldloc (for input) 
-stloc (for output).  Do not use a ret instruction or tail.call
-instruction within the handwritten IL code.
-
-The IL code in a @code{pragma foreign_proc} declaration
-for any procedure whose determinism indicates that it could fail
-must assign a truth value to the local variable @samp{succeeded}.
-For example:
-
- at example
-:- pred same(int::in, int::in) is semidet.
-:- pragma foreign_proc("il", same(X::in, Y::in), [max_stack_size(2)], "
-	ldloc X
-	ldloc Y
-	ceq
-	stloc succeeded
-").
- at end example
+Each of these foreign language interfaces requires that an appropriate
+compiler be installed.
 
- at code{succeeded} should not be used other than as the target of
-an stloc.
-Procedures whose determinism indicates that that they cannot fail
-should not access @code{succeeded}.
-
-Arguments whose mode is input will have their values set by the
-Mercury implementation on entry to the IL code.  If the procedure
-succeeds, the IL code must set the values of all output arguments
-before returning.  If the procedure fails, the IL code need only
-set @code{success} to false (zero).
-
-The Mercury types @code{int}, @code{float}, @code{char},
-and @code{string} are mapped to the Common Language Runtime types 
- at code{int32}, @code{float64}, @code{char} and @code{System.String}
-respectively.
-
-Mercury variables which are polymorphically typed (e.g. whose type is a 
-type variables) will be passed as @code{System.Object} while all other
-Mercury variables are passed as @code{System.Object[]}.
-This mapping is subject to change and you should try to avoid writing
-code that relies heavily upon a particular representation of Mercury
-terms.
 
 @node C interface
 @chapter C interface



only in patch2:
--- doc/user_guide.texi	2001/07/12 22:20:06	1.261
+++ doc/user_guide.texi	2001/07/17 09:43:57
@@ -73,6 +73,7 @@
 @author Thomas Conway
 @author Zoltan Somogyi
 @author Peter Ross
+ at author Tyson Dowd
 @page
 @vskip 0pt plus 1filll
 Copyright @copyright{} 1995-2001 The University of Melbourne.
@@ -118,6 +119,8 @@
 * Invocation::      List of options for the Mercury compiler.
 * Environment::     Environment variables used by the compiler and utilities.
 * C compilers::     How to use a C compiler other than GNU C.
+* Foreign language interface:: Interfacing to other programming
+		    languages from Mercury.
 * Index::
 @end menu
 @end ifinfo
@@ -5699,6 +5702,322 @@
 code with @samp{--no-static-ground-terms}.
 
 @end itemize
+
+ at c ----------------------------------------------------------------------------
+
+ at node Foreign language interface
+ at chapter Foreign language interface
+
+ at menu
+* Interfacing with C 		:: How to write code to interface with C
+* Interfacing with Managed C++ 	:: How to write code to interface with
+* Interfacing with C# 		:: How to write code to interface with C#
+* Interfacing with IL 		:: How to write code to interface with IL
+  				   Managed C++
+ at end menu
+
+ at table @asis
+
+ at item @samp{C}
+This is the default foreign language on all backends which compile to C
+or assembler.
+Only available on backends that compile to C or assembler.
+
+ at item @samp{Managed C++}
+Managed Extensions for C++ provides support for writing .NET components
+in C++, by adding extra keywords and syntax.
+
+This is the default foreign language on all backends which compile to IL.
+In the current implementation, this is only available on backends that
+compile to IL.
+Requires a Managed Extensions for C++ compiler installed.
+
+
+ at item @samp{C#}
+Only available on backends that compile to IL.
+Requires a C# compiler installed.
+To use it pass mmc @samp{--use-foreign-language csharp} and
+ at samp{--backend-foreign-language csharp}.
+
+ at item @samp{IL}
+IL (or CIL) is the intermediate language of the .NET Common Language
+Runtime.
+
+Use the string "IL" to set the foreign language to IL.
+Only available on backends that compile to IL.
+Requires an IL assembler installed.
+To use it pass mmc @samp{--use-foreign-language il} and
+ at samp{--backend-foreign-language il}.
+
+ at end table
+
+ at node Interfacing with C
+ at section Interfacing with C
+
+ at menu
+* Using pragma foreign_proc for C 	:: Calling C code from Mercury
+* Using pragma foreign_decl for C 	:: Including C declarations in Mercury
+* Using pragma foreign_code for C 	:: Including C code in Mercury
+ at end menu
+
+ at node Using pragma foreign_proc for C
+ at subsection Using pragma foreign_proc for C
+
+The input and output variables will have C types corresponding
+to their Mercury types, as determined by the rules specified in
+``Passing data to and from C'' in the ``C Interface''
+chapter of the Mercury Language Reference Manual.
+
+The C code fragment may declare local variables, but it should not
+declare any labels or static variables unless there is also a Mercury
+ at samp{pragma no_inline} declaration for the procedure.
+The reason for this is that otherwise the Mercury implementation may
+inline the procedure by duplicating the C code fragment for each call.
+If the C code fragment declared a static variable, inlining it in this
+way could result in the program having multiple instances of the static
+variable, rather than a single shared instance.  If the C code fragment
+declared a label, inlining it in this way could result in an error due
+to the same label being defined twice inside a single C function.
+
+C code in a @code{pragma foreign_proc} declaration
+for any procedure whose determinism indicates that it could fail
+must assign a truth value to the macro @samp{SUCCESS_INDICATOR}.
+For example:
+
+ at example
+:- pred string__contains_char(string, character).
+:- mode string__contains_char(in, in) is semidet.
+
+:- pragma foreign_proc("C", string__contains_char(Str::in, Ch::in),
+        [will_not_call_mercury],
+        "SUCCESS_INDICATOR = (strchr(Str, Ch) != NULL);").
+ at end example
+
+ at code{SUCCESS_INDICATOR} should not be used other than 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 @code{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 @code{SUCCESS_INDICATOR} to false (zero).
+
+ at node Using pragma foreign_decl for C
+ at subsection Using pragma foreign_decl for C
+
+Any macros, function prototypes, or other C declarations
+that are used in @samp{foreign_code} or @samp{foreign_proc} 
+pragmas must be included using a @samp{foreign_decl} declaration of the form
+
+ at example
+:- pragma foreign_decl("C", @var{HeaderCode}).
+ at end example
+
+ at noindent
+ at var{HeaderCode} can be a C @samp{#include} line, for example
+
+ at example
+:- pragma foreign_decl("C", "#include <math.h>")
+ at end example
+
+ at noindent
+or
+
+ at example
+:- pragma foreign_decl("C", "#include ""tcl.h""").
+ at end example
+
+ at noindent
+or it may contain any C declarations, for example
+
+ at example
+:- pragma foreign_decl("C", "
+        extern int errno;
+        #define SIZE 200
+        struct Employee @{
+                char name[SIZE];
+        @}
+        extern int bar;
+        extern void foo(void);
+").
+ at end example
+
+Mercury automatically includes certain headers such as @code{<stdlib.h>},
+but you should not rely on this, as the set of headers which Mercury
+automatically includes is subject to change.
+
+ at node Using pragma foreign_code for C
+ at subsection Using pragma foreign_code for C
+
+Definitions of C functions or global variables may be
+included using a declaration of the form
+
+ at example
+:- pragma foreign_code("C", @var{Code}).
+ at end example
+
+For example,
+
+ at example
+:- pragma foreign_code("C", "
+        int bar = 42;
+        void foo(void) @{@}
+").
+ at end example
+
+Such code is copied verbatim into the generated C file.
+
+ at c ----------------------------------------------------------------------------
+
+ at node Interfacing with C#
+ at section Interfacing with C#
+
+ at c XXX
+Currently undocumented, sorry.
+
+ at menu
+* Using pragma foreign_proc for C# 	:: Calling C# code from Mercury
+* Using pragma foreign_decl for C# 	:: Including C# declarations in Mercury
+* Using pragma foreign_code for C# 	:: Including C# code in Mercury
+ at end menu
+
+ at node Using pragma foreign_proc for C#
+ at subsection Using pragma foreign_proc for C#
+
+Not currently supported for C#.
+ at c XXX
+
+ at node Using pragma foreign_decl for C#
+ at subsection Using pragma foreign_decl for C#
+
+Not currently supported for C#.
+ at c XXX
+
+ at node Using pragma foreign_code for C#
+ at subsection Using pragma foreign_code for C#
+
+Not currently supported for C#.
+ at c XXX
+
+
+ at c ----------------------------------------------------------------------------
+
+ at node Interfacing with Managed C++
+ at section Interfacing with Managed C++
+
+ at c XXX
+Currently undocumented, sorry.
+
+ at menu
+* Using pragma foreign_proc for MC++::  Calling MC++ code from Mercury
+* Using pragma foreign_decl for MC++::  Including MC++ declarations in Mercury
+* Using pragma foreign_code for MC++::  Including MC++ code in Mercury
+ at end menu
+
+ at node Using pragma foreign_proc for MC++
+ at subsection Using pragma foreign_proc for MC++
+
+Currenly undocumented, sorry.
+ at c XXX
+
+ at node Using pragma foreign_decl for MC++
+ at subsection Using pragma foreign_decl for MC++
+
+Currenly undocumented, sorry.
+ at c XXX
+
+ at node Using pragma foreign_code for MC++
+ at subsection Using pragma foreign_code for MC++
+
+Currenly undocumented, sorry.
+ at c XXX
+
+ at c ----------------------------------------------------------------------------
+
+ at node Interfacing with IL
+ at section Interfacing with IL
+
+ at menu
+* Using pragma foreign_proc for IL 	:: Calling IL code from Mercury
+* Using pragma foreign_decl for IL 	:: Including IL declarations in Mercury
+* Using pragma foreign_code for IL 	:: Including IL code in Mercury
+ at end menu
+
+ at node Using pragma foreign_proc for IL
+ at subsection Using pragma foreign_proc for IL
+
+Variables can be accessed from IL by using ldloc (for input parameters) 
+and stloc (for output parameters).
+Do not use ret or jmp instructions or tail calls within the handwritten
+IL code.
+The stack must be empty at the end of the IL code.
+
+ at example
+:- pred add(int::in, int::in, int::out) det.
+:- pragma foreign_proc("il", add(X::in, Y::in, Z::out), [max_stack_size(2)], "
+	ldloc X
+	ldloc Y
+	add
+	stloc Z
+").
+ at end example
+
+IL code for procedures whose determinism indicates they could fail 
+is currently not supported.
+
+ at c XXX document how semidet works -- but get it working first.
+ at c
+ at c The IL code in a @code{pragma foreign_proc} declaration
+ at c for any procedure whose determinism indicates that it could fail
+ at c must assign a truth value to the local variable @samp{succeeded}.
+ at c For example:
+ at c
+ at c @example
+ at c :- pred same(int::in, int::in) is semidet.
+ at c :- pragma foreign_proc("il", same(X::in, Y::in), [max_stack_size(2)], "
+ at c 	ldloc X
+ at c 	ldloc Y
+ at c 	ceq
+ at c 	stloc succeeded
+ at c ").
+ at c @end example
+
+Arguments whose mode is input will have their values set by the
+Mercury implementation on entry to the IL code.  If the procedure
+succeeds, the IL code must set the values of all output arguments
+before returning. 
+
+ at c If the procedure fails, the IL code need only
+ at c set @code{success} to false (zero).
+
+The Mercury types @code{int}, @code{float}, @code{char},
+and @code{string} are mapped to the Common Language Runtime types 
+ at code{int32}, @code{float64}, @code{char} and @code{System.String}
+respectively.
+
+Mercury variables which are polymorphically typed (e.g. whose type is a 
+type variables) will be passed as @code{System.Object} while all other
+Mercury variables are passed as @code{System.Object[]}.
+This mapping is subject to change and you should try to avoid writing
+code that relies heavily upon a particular representation of Mercury
+terms.
+
+ at node Using pragma foreign_decl for IL
+ at subsection Using pragma foreign_decl for IL
+
+Not currently supported for IL.
+ at c XXX
+
+ at node Using pragma foreign_code for IL
+ at subsection Using pragma foreign_code for IL
+
+Not currently supported for IL.
+ at c XXX
+
 
 @c ----------------------------------------------------------------------------
 

-- 
       Tyson Dowd           # 
                            #  Surreal humour isn't everyone's cup of fur.
     trd at cs.mu.oz.au        # 
http://www.cs.mu.oz.au/~trd #
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list