-----------------------------------------------------------------------------

WARNING

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.

INTRODUCTION

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.   

PREREQUISITES

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:
	  
		<http://msdn.microsoft.com/netframework/>
	  
	  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:

	      <http://www.mercurylang.org>

-----------------------------------------------------------------------------

THE IL GRADE

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
rudimentary.

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
running 
	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
directory.
	
	cd samples
	mmc --make --il hello

Now you can run hello

	./hello.exe

Alternatively, if you prefer, you can use mmake rather than `mmc --make':

	mmake hello.depend GRADE=il
	mmake hello GRADE=il
	./hello.exe

You can also set the grade in an Mmakefile, by adding the line

	GRADE=il

to the Mmakefile; then you can leave the "GRADE=il" part off the mmake
commands.

-----------------------------------------------------------------------------

USING DOTNET

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:

    <http://www.mercurylang.org/information/documentation.html>

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 
	CSCFLAGS-<modulename>_csharp_code=/reference:<foreignmodulename>.dll
or
	CSCFLAGS-<modulename>_csharp_code=/addmodule:<foreignmodulename>.dll

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.

-----------------------------------------------------------------------------

RESOURCES

You might find the following pages useful:

	<http://www.mercurylang.org/dotnet.html>

	<http://msdn.microsoft.com/netframework/>

	<http://www.gotdotnet.com/>

-----------------------------------------------------------------------------

FREQUENTLY ASKED QUESTIONS (FAQS)

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:

	benchmarking
	store

   The standard library modules that provide RTTI are only partly implemented
   (basically just enough to make io.print work):

	construct
	deconstruct

   In addition, the following individual procedures from other modules
   are still not yet implemented:

	io.binary_stream_offset/4
	io.seek_binary/5
	type_desc.make_type/2
	type_desc.type_ctor/1
	time.clock/3
	time.times/4

   The following procedures are implemented, but not completely:

        time.local_time/3 
        time.mktime/3 
	   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.

-----------------------------------------------------------------------------
