Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Branch: master
Fetching contributors…

Cannot retrieve contributors at this time

269 lines (186 sloc) 9.348 kB
The .NET backend described herein is out-of-date and may be removed in
the future. See README.CSharp for details of a newer backend that targets .NET.
This release of Mercury contains a port to the Microsoft.NET Common
Language Runtime (CLR). The Mercury compiler will generate code
in Microsoft's Intermediate Language (IL) that can be assembled into
bytecode suitable for running in the .NET runtime system.
The port is mostly complete, but some parts of the Mercury standard
library are not yet implemented (for a full list see the FAQ below).
However, enough is implemented correctly to bootstrap the Mercury
compiler, and to pass more than 90% of the applicable tests in the Mercury
test suite.
The port is currently targeted at the Microsoft .NET Framework SDK versions
1 and 1.1. We recommend version 1.1.
In order to try this system you will need
- The Microsoft .NET Framework SDK version 1 or 1.1, which can be
downloaded for free from:
If you are an MSDN Universal subscriber you can also order
CDs as part of your subscription.
It might also work with later versions, but we haven't tested
with those.
- A windows system suitable for development with Microsoft .NET.
According to Microsoft, the .NET Framework SDK runs on:
Microsoft Windows NT 4.0 (SP 6a required)
Microsoft Windows 2000 (SP 2 recommended)
Microsoft Windows XP Professional
We have tested only on Windows 2000 (with SP 2) and
Windows XP Home.
- Cygwin (see README.MS-Windows for how to install).
The Mercury compiler still runs as a native compiler, built
with gcc by default -- although see README.MS-VisualC for how
to build with VC++ if you wish.
Mercury still relies upon the Cygwin environment for
development environment tools such as `mmake'.
You need the following Cygwin packages:
- gcc
- binutils
- make
- If you have installed the .NET SDK as part of Visual
Studio .NET, you will need to put the Visual Studio
binaries in your path, and set appropriate environment
variables. The easiest way to do this is to put the line
call "C:\Program Files\Microsoft Visual Studio.NET\Common7\Tools\vsvars32.bat"
into your cygwin.bat file (installed on the desktop by Cygwin),
after the line that says @echo off.
Substitute your Visual Studio installation path for the default path
given here.
- The Mercury distribution -- installed as usual. You invoke the
configure with the option `--enable-dotnet-grades' in order to
enable .NET support. Make sure the installation is run after the
Microsoft .NET SDK is installed (run it again if necessary) so that
the configuration scripts detect the installation path of the SDK.
If `configure' finds `ilasm' and `cl' then this has been successful.
You can install from either the source or binary distribution.
If you're reading this file from somewhere other than the Mercury
distribution, try the Mercury homepage at:
The Mercury compiler currently supports the grade `il' to target the
Microsoft.NET CLR. This grade is enabled by any of the options
`--grade il', `--target il', or just `--il'.
Support for building and installation of this grade is still somewhat
To run a Mercury program using the il grade, you need to build the
library and runtime in the il grade, using the Mercury source distribution.
If configure finds the .NET SDK installed on your machine, the il grade
will be added to the list of default grades to be installed, so simply
mmake install
from the Mercury source distribution will install the il grade.
You can now build programs such as hello.m or calculator.m in the samples
cd samples
mmc --make --il hello
Now you can run hello
Alternatively, if you prefer, you can use mmake rather than `mmc --make':
mmake hello.depend GRADE=il
mmake hello GRADE=il
You can also set the grade in an Mmakefile, by adding the line
to the Mmakefile; then you can leave the "GRADE=il" part off the mmake
The Mercury standard library has not been fully ported to .NET yet.
The use of unimplemented procedures will result in a run-time error,
with a message such as "Sorry, not implemented: foreign code for this
function", and a stack trace.
If you find missing functionality, you can interface to the .NET
Frameworks using C# and Mercury's foreign language interface.
For example:
:- pred to_string(T::in, string::out) is det.
:- pragma foreign_proc("C#",
to_string(T::in, Str::out),
[promise_pure, will_not_call_mercury],
Str = T.ToString();
For more information about the foreign language interface, refer to the Mercury
Language Reference Manual, which you can find at:
The implementation will put this C# in a separate file, which will be
compiled with Microsoft's C# compiler. Mmake will automatically
generate dependencies for this file and invoke the C# compiler with the
appropriate options.
You can also use the C# interface to interface with any .NET language
(Implementations have been announced or are under development for
C++, C#, Visual Basic, Cobol, Eiffel, SmallTalk, ML, Haskell, Scheme,
Python, Perl, Component Pascal and others).
Add a
to your Mmakefile to pass the appropriate flag to the C# compiler so
that you can reference another DLL from the C# code.
<modulename> is the name of your Mercury module, and <foreignmodulename> is
the name of the dll you want to use from Mercury via C#.
We are working on a tool that automatically generates a Mercury interface
for any .NET component, but it is not yet ready for public use.
Currently each top level Mercury module is placed into its own assembly.
For example, module.m will be placed into the assembly `module', while
module.sub.m will also be placed into the assembly `module'.
To create a strongly named assemblies in Mercury you need to pass the
--sign-assembly flag to the Mercury compiler. Note that this flag needs
to be also passed when generating the dependencies for the module being
compiled. Currently we use the same strong name as used by the mercury
standard library to sign all the Mercury modules, at a later date we
hope to lift this restriction.
You might find the following pages useful:
Q. What are the advantages of using the .NET back-end?
A. The main advantage is easy access to the wide range of libraries for the
.NET platform.
Q. Does it work with other .NET Common Language Runtime implementations,
such as Mono, Portable.Net, or Rotor?
A. In theory, it should be possible to build Mercury programs in the
`il' grade using any ECMA-compliant IL assembler that provides the same
command-line interface as the Microsoft ilasm.exe program, and to execute
them using any ECMA-complaint .NET CLR implementation. However, we have
not yet tried using other .NET CLR implementations.
Q. Does it work with versions of the Microsoft .NET Framework SDK greater
than 2.0?
A. We don't know, because we've only tried it with version 1.0 and 1.1.
If you have a later version, try it out yourself and let us know
whether it works!
Q. How does it compare in efficiency with the usual Mercury implementation?
A. Our paper "Compiling Mercury to the .NET Common Language Runtime",
which is available from the Mercury web site, has some benchmark
results. As usual, your mileage may vary.
Q. What features are not yet implemented?
A. The following standard library modules are completely unimplemented:
The standard library modules that provide RTTI are only partly implemented
(basically just enough to make io.print work):
In addition, the following individual procedures from other modules
are still not yet implemented:
The following procedures are implemented, but not completely:
During times close to the transition to/from daylight savings time,
local_time/3 may return incorrect values for the tm_dst field,
and mktime/3 may incorrectly ignore the value of the tm_dst field
in its input. The problem is due to flaws in the .NET time APIs.
Jump to Line
Something went wrong with that request. Please try again.