[m-rev.] for review: new foreign_type syntax
Tyson Dowd
trd at cs.mu.OZ.AU
Thu Dec 6 13:19:19 AEDT 2001
Hi,
Here's a relative diff of the documentation, and a full diff of the
whole change, so let's try another iteration.
diff -u doc/reference_manual.texi doc/reference_manual.texi
--- doc/reference_manual.texi
+++ doc/reference_manual.texi
@@ -5010,25 +5010,32 @@
@node Using foreign types from Mercury
@section Using foreign types from Mercury
-Types defined in foreign language can be declared in Mercury using
+Types defined in foreign language can be defined in Mercury using
a declaration of the form
@example
-:- pragma foreign_type(@var{MercuryTypeName}, @var{ForeignTypeDescriptor}).
+:- pragma foreign_type(@var{Lang}, @var{MercuryTypeName}, @var{ForeignTypeDescriptor}).
@end example
-This declaration introduces a new abstract type in Mercury which is a
-synonym for a type defined in a foreign language.
+This defines @var{MercuryTypeName} as a synonym for type
+ at var{ForeignTypeDescriptor} defined in the foreign language @var{Lang}.
+You must declare @var{MercuryTypeName} using a @samp{:- type}
+declaration as usual, and the foreign_type pragma must have the same
+visibility as the type declaration (either both in the interface or both
+in the implementation).
@var{ForeignTypeDescriptor} defines how the Mercury type is mapped for a
-particular compilation grade. Specific syntax is given in the language
-specific information below.
+particular foreign language. Specific syntax is given in the language
+specific information below.
@var{MercuryTypeName} is treated as an abstract type at all times in
Mercury code.
However, if @var{MercuryTypeName} is one of the parameters of a
-foreign_proc, it will be passed to that foreign_proc as specified by
- at var{ForeignTypeDescriptor}.
+foreign_proc for @var{Lang}, it will be passed to that foreign_proc as
+specified by @var{ForeignTypeDescriptor}.
+Multiple foreign languages definitions may be given for the same type ---
+the appropriate definition will be used for the appropriate language (see the
+language specific inforation below for details).
@c -----------------------------------------------------------------------
@@ -5113,7 +5120,7 @@
@menu
* Interfacing with C :: How to write code to interface with C
-* Interfacing with .NET :: How to write code to interface with .NET
+* Interfacing with .NET CLR :: How to write code to interface with .NET CLR
* Interfacing with C# :: How to write code to interface with C#
* Interfacing with IL :: How to write code to interface with IL
* Interfacing with Managed C++ :: How to write code to interface with
@@ -5286,49 +5293,57 @@
@c ----------------------------------------------------------------------------
- at node Interfacing with .NET
- at subsection Interfacing with .NET
+ at node Interfacing with .NET CLR
+ at subsection Interfacing with .NET CLR
+
+This section describes how to interface with the .NET Common Language
+Runtime, as specified by the ECMA Common Language Infrastructure (ECMA
+TC39/TG3) standards.
@c XXX
Currently much of this section is still undocumented, sorry.
@menu
-* Using pragma foreign_type for .NET :: Declaring .NET types in Mercury
+* Using pragma foreign_type for .NET CLR :: Declaring .NET CLR types in Mercury
@end menu
- at node Using pragma foreign_type for .NET
- at subsubsection Using pragma foreign_type for .NET
+ at node Using pragma foreign_type for .NET CLR
+ at subsubsection Using pragma foreign_type for .NET CLR
-The .NET pragma foreign_type declaration is of the form:
+The .NET CLR @samp{pragma foreign_type} declaration is of
+the form:
@example
-:- pragma foreign_type(@var{MercuryTypeName}, il(@var{DotNetForeignType})).
+:- pragma foreign_type(il, @var{MercuryTypeName}, @var{DotNetForeignType}).
@end example
-If the @var{MercuryTypeName} is a parameter of a procedure defined using
- at samp{pragma foreign_proc}, it will be passed to user code as
- at var{DotNetForeignType}.
-Futhermore, any externally visible Mercury
+If the @var{MercuryTypeName} is the type of a parameter of a procedure
+defined using @samp{pragma foreign_proc} for any of the .NET CLR
+languages, it will be passed to user code as @var{DotNetForeignType}.
+Futhermore, any exported (with @samp{pragma export}) Mercury
procedure will use @var{DotNetForeignType} as the parameter type for
parameters whose Mercury type is @var{MercuryTypeName}.
-The CIL assembler syntax is used to specify type names for the .NET
+The CIL assembler syntax is used to specify type names for the .NET CLR
backend (this syntax is documented in the ECMA specifications for .NET).
-Currently on the .NET backend only reference classes are supported using
+Currently on the .NET CLR backend only reference classes are supported using
@samp{pragma foreign_type}, and hence the only supported syntax for
DotNetForeignType is @samp{"class [AssemblyName]ClassName"}.
-Note that extra whitespace is not handled, there should only be a single
-space between the class keyword and they assembly specifier.
+ at c XXX this restriction should be lifted
+Note that extra whitespace is not handled --- there should only be a single
+space between the class keyword and the assembly specifier.
+ at c XXX we should handle whitespace better
For example:
@example
-:- pragma foreign_type(xmldoc, il("class [System.Xml]System.Xml.XmlDocument")).
+:- type xmldoc.
+:- pragma foreign_type(il, xmldoc, "class [System.Xml]System.Xml.XmlDocument").
@end example
-ensures that on the .NET backend the mercury type @samp{xmldoc} is
-represented marhsalled by the backend as @samp{System.Xml.XmlDocument}
-from assembly System.Xml.
+ensures that on the .NET CLR backend the Mercury type @samp{xmldoc} is
+marshalled by the backend as @samp{System.Xml.XmlDocument} from assembly
+ at samp{System.Xml}.
The following example shows how one can use the marshalled data from C#.
@example
===================================================================
Estimated hours taken: 8
Branches: main
Fix and enable the new foreign_type syntax. We now accept declarations
such as:
:- pragma foreign_type(il, xmldoc, "class [System.Xml]System.Xml.XmlDocument").
compiler/prog_data.m:
Remove the foreign type location from the foreign_type pragma,
it is better to make this part of the backend type.
Rename backend as backend_type as it specifies a type in a
particular backend.
compiler/prog_io_pragma.m:
Uncomment the foreign_type parsing code, change the syntax.
Write some simple code to parse CIL type names.
compiler/make_hlds.m:
Check that there is a :- type declaration, and
that it has the same visibility as the pragma foreign_type.
compiler/mercury_to_mercury.m:
compiler/module_qual.m:
compiler/modules.m:
compiler/recompilation_version.m:
Handle changes to backend_type and the foreign_type pragma.
doc/reference_manual.texi:
Document the new syntax.
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.391
diff -u -r1.391 make_hlds.m
--- compiler/make_hlds.m 12 Nov 2001 11:08:07 -0000 1.391
+++ compiler/make_hlds.m 5 Dec 2001 22:40:16 -0000
@@ -395,18 +395,47 @@
{ Pragma = foreign_proc(_, _, _, _, _, _) },
{ Module = Module0 }
;
- { Pragma = foreign_type(Backend, _MercuryType, Name,
- ForeignType) },
+ { Pragma = foreign_type(Backend, _MercuryType, Name) },
- { Backend = il(ForeignTypeLocation) },
+ { Backend = il(ForeignTypeLocation, ForeignType) },
{ varset__init(VarSet) },
{ Args = [] },
{ Body = foreign_type(ForeignType, ForeignTypeLocation) },
{ Cond = true },
- module_add_type_defn_2(Module0, VarSet, Name, Args, Body,
- Cond, Context, Status, Module)
+ { TypeId = Name - 0 },
+ { module_info_types(Module0, Types) },
+ { TypeStr = error_util__describe_sym_name_and_arity(
+ Name / 0) },
+ (
+ { map__search(Types, TypeId, OldDefn) }
+ ->
+ { hlds_data__get_type_defn_status(OldDefn, OldStatus) },
+ { combine_status(OldStatus, ImportStatus, NewStatus) },
+ ( { NewStatus = abstract_exported } ->
+ { ErrorPieces = [
+ words("Error: pragma foreign_type "),
+ fixed(TypeStr),
+ words("must have the same visibility as the type declaration.")
+ ] },
+ error_util__write_error_pieces(Context, 0, ErrorPieces),
+ { module_info_incr_errors(Module0, Module) }
+
+ ;
+ module_add_type_defn_2(Module0, VarSet, Name,
+ Args, Body, Cond, Context, Status,
+ Module)
+ )
+ ;
+ { ErrorPieces = [
+ words("Error: type "),
+ fixed(TypeStr),
+ words("defined as foreign_type without being declared.")
+ ] },
+ error_util__write_error_pieces(Context, 0, ErrorPieces),
+ { module_info_incr_errors(Module0, Module) }
+ )
;
% Handle pragma tabled decls later on (when we process
% clauses).
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.198
diff -u -r1.198 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m 8 Nov 2001 15:30:31 -0000 1.198
+++ compiler/mercury_to_mercury.m 21 Nov 2001 05:33:10 -0000
@@ -467,18 +467,18 @@
PredOrFunc, Vars, VarSet, PragmaCode)
;
{ Pragma = foreign_type(Backend, _MercuryType,
- MercuryTypeSymName, ForeignType) },
+ MercuryTypeSymName) },
io__write_string(":- pragma foreign_type("),
% output_type(varset__init, no, MercuryType),
mercury_output_sym_name(MercuryTypeSymName),
io__write_string(", "),
- mercury_output_sym_name(ForeignType),
- io__write_string(", "),
- { Backend = il(ForeignLocStr) },
+ { Backend = il(ForeignLocStr, ForeignType) },
io__write_string("il(\""),
io__write_string(ForeignLocStr),
- io__write_string("\")).\n")
+ io__write_string("\", "),
+ mercury_output_sym_name(ForeignType),
+ io__write_string("\").\n")
;
{ Pragma = import(Pred, PredOrFunc, ModeList, Attributes,
C_Function) },
Index: compiler/module_qual.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.70
diff -u -r1.70 module_qual.m
--- compiler/module_qual.m 6 Nov 2001 15:21:05 -0000 1.70
+++ compiler/module_qual.m 21 Nov 2001 05:33:10 -0000
@@ -247,7 +247,7 @@
collect_mq_info_2(pred_or_func(_,_,__,_,_,_,_,_,_,_), Info, Info).
collect_mq_info_2(pred_or_func_mode(_,_,_,_,_,_), Info, Info).
collect_mq_info_2(pragma(Pragma), Info0, Info) :-
- ( Pragma = foreign_type(_, Type, SymName, _ForeignType) ->
+ ( Pragma = foreign_type(_, Type, SymName) ->
( type_to_type_id(Type, _ - Arity0, _) ->
Arity = Arity0
;
@@ -893,11 +893,11 @@
qualify_pragma(source_file(File), source_file(File), Info, Info) --> [].
qualify_pragma(foreign_decl(L, Code), foreign_decl(L, Code), Info, Info) --> [].
qualify_pragma(foreign_code(L, C), foreign_code(L, C), Info, Info) --> [].
+qualify_pragma(foreign_type(Backend, Type0, SymName),
+ foreign_type(Backend, Type, SymName), Info0, Info) -->
+ qualify_type(Type0, Type, Info0, Info).
qualify_pragma(foreign_import_module(L, M), foreign_import_module(L, M),
Info, Info) --> [].
-qualify_pragma(foreign_type(Backend, Type0, SymName, F),
- foreign_type(Backend, Type, SymName, F), Info0, Info) -->
- qualify_type(Type0, Type, Info0, Info).
qualify_pragma(
foreign_proc(Rec, SymName, PredOrFunc, PragmaVars0, Varset, Code),
foreign_proc(Rec, SymName, PredOrFunc, PragmaVars, Varset, Code),
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.209
diff -u -r1.209 modules.m
--- compiler/modules.m 28 Nov 2001 14:46:33 -0000 1.209
+++ compiler/modules.m 3 Dec 2001 01:36:32 -0000
@@ -1147,7 +1147,7 @@
pragma_allowed_in_interface(foreign_import_module(_, _), no).
pragma_allowed_in_interface(foreign_code(_, _), no).
pragma_allowed_in_interface(foreign_proc(_, _, _, _, _, _), no).
-pragma_allowed_in_interface(foreign_type(_, _, _, _), yes).
+pragma_allowed_in_interface(foreign_type(_, _, _), yes).
pragma_allowed_in_interface(inline(_, _), no).
pragma_allowed_in_interface(no_inline(_, _), no).
pragma_allowed_in_interface(obsolete(_, _), yes).
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.72
diff -u -r1.72 prog_data.m
--- compiler/prog_data.m 20 Nov 2001 13:53:19 -0000 1.72
+++ compiler/prog_data.m 22 Nov 2001 02:10:47 -0000
@@ -157,9 +157,8 @@
% PredName, Predicate or Function, Vars/Mode,
% VarNames, Foreign Code Implementation Info
- ; foreign_type(backend, (type), sym_name, sym_name)
- % Backend, MercuryType, MercuryTypeName,
- % ForeignType, ForeignTypeLocation
+ ; foreign_type(backend_type, (type), sym_name)
+ % BackendType, MercuryType, MercuryTypeName
; foreign_import_module(foreign_language, module_name)
% Equivalent to
@@ -288,9 +287,10 @@
% Stuff for the foreign interfacing pragmas.
%
-:- type backend
- % The location of the il name.
- ---> il(string).
+:- type backend_type
+ % The location of the il name, and the .NET type name
+ % (represented as a sym_name)
+ ---> il(string, sym_name).
%
% Stuff for tabling pragmas
Index: compiler/prog_io_pragma.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io_pragma.m,v
retrieving revision 1.38
diff -u -r1.38 prog_io_pragma.m
--- compiler/prog_io_pragma.m 20 Nov 2001 13:53:20 -0000 1.38
+++ compiler/prog_io_pragma.m 28 Nov 2001 07:37:58 -0000
@@ -70,52 +70,43 @@
ErrorTerm)
).
-/*
parse_pragma_type(ModuleName, "foreign_type", PragmaTerms,
ErrorTerm, _VarSet, Result) :-
- ( PragmaTerms = [MercuryName, ForeignName, Target] ->
- (
- parse_backend(Target, Backend)
- ->
- parse_implicitly_qualified_term(ModuleName, MercuryName,
+ ( PragmaTerms = [LangTerm, MercuryName, BackendTerm] ->
+ ( parse_foreign_language(LangTerm, Language) ->
+ parse_backend(BackendTerm, Language, MaybeBackend),
+ (
+ MaybeBackend = ok(Backend),
+ parse_implicitly_qualified_term(ModuleName, MercuryName,
ErrorTerm, "`:- pragma foreign_type' declaration",
MaybeMercuryType),
- (
- MaybeMercuryType = ok(MercuryTypeSymName, MercuryArgs),
- ( MercuryArgs = [] ->
- parse_qualified_term(ForeignName, ErrorTerm,
- "`:- pragma foreign_type' declaration",
- MaybeForeignType),
- (
- MaybeForeignType = ok(ForeignType, ForeignArgs),
- ( ForeignArgs = [] ->
- term__coerce(MercuryName, MercuryType),
- Result = ok(pragma(foreign_type(Backend,
- MercuryType, MercuryTypeSymName,
- ForeignType)))
- ;
- Result = error("foreign type arity not 0", ErrorTerm)
- )
+ (
+ MaybeMercuryType = ok(MercuryTypeSymName, MercuryArgs),
+ ( MercuryArgs = [] ->
+ term__coerce(MercuryName, MercuryType),
+ Result = ok(pragma(foreign_type(Backend,
+ MercuryType, MercuryTypeSymName)))
;
- MaybeForeignType = error(String, Term),
- Result = error(String, Term)
+ Result = error("foreign type arity not 0", ErrorTerm)
)
;
- Result = error("mercury type arity not 0", ErrorTerm)
+ MaybeMercuryType = error(String, Term),
+ Result = error(String, Term)
)
;
- MaybeMercuryType = error(String, Term),
+ MaybeBackend = error(String, Term),
Result = error(String, Term)
)
- ;
- Result = error("invalid backend parameter", Target)
+ ;
+ Result = error(
+ "invalid foreign language in `:- pragma foreign_type' declaration",
+ LangTerm)
)
;
Result = error(
"wrong number of arguments in `:- pragma foreign_type' declaration",
ErrorTerm)
).
-*/
parse_pragma_type(ModuleName, "foreign_decl", PragmaTerms,
ErrorTerm, VarSet, Result) :-
@@ -214,13 +205,42 @@
parse_foreign_language(term__functor(term__atom(String), _, _), Lang) :-
globals__convert_foreign_language(String, Lang).
-:- pred parse_backend(term, backend).
-:- mode parse_backend(in, out) is semidet.
+:- pred parse_backend(term, foreign_language, maybe1(backend_type)).
+:- mode parse_backend(in, in, out) is det.
+
+parse_backend(InputTerm, Language, Result) :-
+ (
+ Language = il
+ ->
+ (
+ InputTerm = term__functor(term__string(ILTypeName),
+ [], _)
+ ->
+ parse_il_type_name(ILTypeName, InputTerm, Result)
+ ;
+ Result = error("invalid backend specification term",
+ InputTerm)
+ )
+ ;
+ Result = error("unsupported language specified, unable to parse backend type", InputTerm)
+ ).
+
+:- pred parse_il_type_name(string, term, maybe1(backend_type)).
+:- mode parse_il_type_name(in, in, out) is det.
-parse_backend(term__functor(Functor, Args, _), Backend) :-
- Functor = term__atom("il"),
- Args = [term__functor(term__string(Module), [], _)],
- Backend = il(Module).
+parse_il_type_name(String0, ErrorTerm, BackendType) :-
+ (
+ string__append("class [", String1, String0),
+ string__sub_string_search(String1, "]", Index)
+ ->
+ string__left(String1, Index, AssemblyName),
+ string__split(String1, Index + 1, _, TypeNameStr),
+ string_to_sym_name(TypeNameStr, ".", TypeSymName),
+ BackendType = ok(il(AssemblyName, TypeSymName))
+ ;
+ BackendType = error("invalid backend type description",
+ ErrorTerm)
+ ).
% This predicate parses both c_header_code and foreign_decl pragmas.
:- pred parse_pragma_foreign_decl_pragma(module_name, string,
Index: compiler/recompilation_version.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/recompilation_version.m,v
retrieving revision 1.9
diff -u -r1.9 recompilation_version.m
--- compiler/recompilation_version.m 6 Nov 2001 15:21:10 -0000 1.9
+++ compiler/recompilation_version.m 21 Nov 2001 05:33:10 -0000
@@ -454,7 +454,7 @@
is_pred_pragma(foreign_proc(_, Name, PredOrFunc, Args, _, _),
yes(yes(PredOrFunc) - Name / Arity)) :-
adjust_func_arity(PredOrFunc, Arity, list__length(Args)).
-is_pred_pragma(foreign_type(_, _, _, _), no).
+is_pred_pragma(foreign_type(_, _, _), no).
is_pred_pragma(type_spec(Name, _, Arity, MaybePredOrFunc, _, _, _, _),
yes(MaybePredOrFunc - Name / Arity)).
is_pred_pragma(inline(Name, Arity), yes(no - Name / Arity)).
Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.228
diff -u -r1.228 reference_manual.texi
--- doc/reference_manual.texi 22 Nov 2001 19:19:54 -0000 1.228
+++ doc/reference_manual.texi 6 Dec 2001 01:56:20 -0000
@@ -4815,6 +4815,9 @@
or function as a call to code
written in a different
programming language.
+* Using foreign types from Mercury:: How to use a type defined in
+ a different programming language
+ in Mercury code.
* Adding foreign declarations:: How to add declarations of
entities in other programming
languages.
@@ -5004,6 +5007,38 @@
@c -----------------------------------------------------------------------
+ at node Using foreign types from Mercury
+ at section Using foreign types from Mercury
+
+Types defined in foreign language can be defined in Mercury using
+a declaration of the form
+
+ at example
+:- pragma foreign_type(@var{Lang}, @var{MercuryTypeName}, @var{ForeignTypeDescriptor}).
+ at end example
+
+This defines @var{MercuryTypeName} as a synonym for type
+ at var{ForeignTypeDescriptor} defined in the foreign language @var{Lang}.
+You must declare @var{MercuryTypeName} using a @samp{:- type}
+declaration as usual, and the foreign_type pragma must have the same
+visibility as the type declaration (either both in the interface or both
+in the implementation).
+
+ at var{ForeignTypeDescriptor} defines how the Mercury type is mapped for a
+particular foreign language. Specific syntax is given in the language
+specific information below.
+
+ at var{MercuryTypeName} is treated as an abstract type at all times in
+Mercury code.
+However, if @var{MercuryTypeName} is one of the parameters of a
+foreign_proc for @var{Lang}, it will be passed to that foreign_proc as
+specified by @var{ForeignTypeDescriptor}.
+Multiple foreign languages definitions may be given for the same type ---
+the appropriate definition will be used for the appropriate language (see the
+language specific inforation below for details).
+
+ at c -----------------------------------------------------------------------
+
@node Adding foreign declarations
@section Adding foreign declarations
@@ -5085,6 +5120,7 @@
@menu
* Interfacing with C :: How to write code to interface with C
+* Interfacing with .NET CLR :: How to write code to interface with .NET CLR
* Interfacing with C# :: How to write code to interface with C#
* Interfacing with IL :: How to write code to interface with IL
* Interfacing with Managed C++ :: How to write code to interface with
@@ -5126,6 +5162,7 @@
* 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
+* Using pragma foreign_type for C :: Declaring C types in Mercury
@end menu
@node Using pragma foreign_proc for C
@@ -5248,6 +5285,77 @@
@end example
Such code is copied verbatim into the generated C file.
+
+ at node Using pragma foreign_type for C
+ at subsubsection Using pragma foreign_type for C
+
+This pragma is currently not implemented for C backends.
+
+ at c ----------------------------------------------------------------------------
+
+ at node Interfacing with .NET CLR
+ at subsection Interfacing with .NET CLR
+
+This section describes how to interface with the .NET Common Language
+Runtime, as specified by the ECMA Common Language Infrastructure (ECMA
+TC39/TG3) standards.
+
+ at c XXX
+Currently much of this section is still undocumented, sorry.
+
+ at menu
+* Using pragma foreign_type for .NET CLR :: Declaring .NET CLR types in Mercury
+ at end menu
+
+ at node Using pragma foreign_type for .NET CLR
+ at subsubsection Using pragma foreign_type for .NET CLR
+
+The .NET CLR @samp{pragma foreign_type} declaration is of
+the form:
+
+ at example
+:- pragma foreign_type(il, @var{MercuryTypeName}, @var{DotNetForeignType}).
+ at end example
+
+If the @var{MercuryTypeName} is the type of a parameter of a procedure
+defined using @samp{pragma foreign_proc} for any of the .NET CLR
+languages, it will be passed to user code as @var{DotNetForeignType}.
+Futhermore, any exported (with @samp{pragma export}) Mercury
+procedure will use @var{DotNetForeignType} as the parameter type for
+parameters whose Mercury type is @var{MercuryTypeName}.
+
+The CIL assembler syntax is used to specify type names for the .NET CLR
+backend (this syntax is documented in the ECMA specifications for .NET).
+Currently on the .NET CLR backend only reference classes are supported using
+ at samp{pragma foreign_type}, and hence the only supported syntax for
+DotNetForeignType is @samp{"class [AssemblyName]ClassName"}.
+ at c XXX this restriction should be lifted
+Note that extra whitespace is not handled --- there should only be a single
+space between the class keyword and the assembly specifier.
+ at c XXX we should handle whitespace better
+
+For example:
+
+ at example
+:- type xmldoc.
+:- pragma foreign_type(il, xmldoc, "class [System.Xml]System.Xml.XmlDocument").
+ at end example
+
+ensures that on the .NET CLR backend the Mercury type @samp{xmldoc} is
+marshalled by the backend as @samp{System.Xml.XmlDocument} from assembly
+ at samp{System.Xml}.
+The following example shows how one can use the marshalled data from C#.
+
+ at example
+:- pred loadxml(string::in, xmldoc::di, xmldoc::uo) is det.
+
+:- pragma foreign_proc("C#", load(String::in, XML0::di, XML::uo),
+ [will_not_call_mercury],
+"
+ XML0.LoadXml(String);
+ XML = XML0;
+").
+ at end example
@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