[m-rev.] for post-commit review: update and rewrite README.CSharp

Julien Fischer jfischer at opturion.com
Thu Jan 19 20:30:27 AEDT 2023


For review by anyone.

(This is similar to the recent update for README.Java.)

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

Update and rewrite README.CSharp.

Convert it to Markdown.

README.CSharp.
     Add a .md extension.

     Update many of the details in this file.

     Add a table-of-contents.

     Break up the FAQ into separate named sections.

README.md:
     Conform to the above change of name.

Julien.

diff --git a/README.CSharp.md b/README.CSharp.md
index b90c7dd9e..301dcf9b9 100644
--- a/README.CSharp.md
+++ b/README.CSharp.md
@@ -1,63 +1,85 @@
------------------------------------------------------------------------------
+Mercury C# Backend
+==================

-INTRODUCTION
+The Mercury compiler has a backend that generates C# source code, that can be
+compiled into bytecode suitable for running using the .NET or Mono runtime
+systems. The backend is mostly complete, but some parts of the Mercury standard
+library are not yet implemented.

-This release of Mercury contains a port to the ECMA Common Language
-Infrastructure (CLI), i.e. Microsoft .NET or Mono.  The Mercury
-compiler will generate C# source code that can be compiled into
-bytecode suitable for running on the .NET or Mono runtime systems.
+The C# backend requires C# 5.0 or higher -- older versions of C# are *not*
+supported.

-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).
+Contents
+--------

-The port is targeted at C# 5.0 or higher.
+* Prerequisites
+* Installing the `csharp` grade
+* Compiling programs with the `csharp` grade
+* Running `csharp` grade programs with Mono
+* Running `csharp` grade programs on Windows with .NET
+* Limitations
+* Library support
+* Interfacing with C#
+* Mercury-level debugging
+* Building the Mercury compiler in the `csharp` grade

-PREREQUISITES
+Prerequisites
+-------------

-In order to use this port you will need either Microsoft.NET 4.5 or above,
-or Mono 4.0 or above.
+In order to use Mercury's C# backend you will need either:

------------------------------------------------------------------------------
+* Microsoft .NET 4.5 or above.
+* Mono 4.0 or above.

-THE C# GRADE
+Installing the `csharp` grade
+-----------------------------

-The Mercury compiler currently supports the grade `csharp'.
-The csharp grade is enabled by using the option `--grade csharp'.
+The Mercury compiler uses the grade `csharp` to target C# source code that
+is then compiled by a C# compiler.

-To run a Mercury program using the csharp grade, you need to build the Mercury
-library and runtime in the csharp grade, using the Mercury source distribution.
+Mercury's autoconfiguration script will cause the `csharp` grade to be installed
+if it finds a suitable C# compiler (e.g. `csc`) and .NET runtime in your `PATH`.

-You can now build programs such as hello.m or calculator.m in the samples
-directory.
+You can check if your Mercury installation has been configured to include the
+`csharp` grade by looking if `csharp` is included in the output of the Mercury
+compiler's `--output-stdlib-grades` option.

-	cd samples
-	mmc ---grade csharp --make hello
+Compiling programs with the `csharp` grade
+------------------------------------------

-Note that when building programs using the csharp grade you *must* use
-mmc --make.
+Once you have a Mercury installation that includes the `csharp` grade, you
+can build programs such as `hello.m` of `calculator.m` in the [samples](samples)
+directory.

------------------------------------------------------------------------------
+```
+    $ cd samples
+    $ mmc ---grade csharp --make hello
+```

-RUNNING C# GRADE PROGRAMS ON UNIX WITH MONO
+When building programs with the `csharp` grade you *must* use `mmc --make`; using
+`mmake` to build programs using the `csharp` grade is _not_ supported.
+
+Running `csharp` grade programs with Mono
+-----------------------------------------

  For the example in the previous section on a Unix (or more generally,
  non-Windows) system using Mono, the Mercury compiler will generate a process
-assembly, e.g. hello.exe, and a wrapper shell script named hello.
+assembly, e.g. `hello.exe`, and a wrapper shell script named `hello`.

-The wrapper shell script will set the MONO_PATH environment variable
+The wrapper shell script will set the `MONO_PATH` environment variable
  to point to the location of the Mercury standard library assemblies.
-It will then invoke CLI execution environment on the above process assembly,
-i.e. you can run the program by simply running the wrapper shell script,
-for example
-
-      ./hello
+It will then invoke then CLI execution environment on the process assembly.
+You can run the program using wrapper shell script, for example:

------------------------------------------------------------------------------
+```
+    $ ./hello
+```

-RUNNING C# GRADE PROGRAMS ON WINDOWS WITH .NET
+Running `csharp` grade programs on Windows with .NET
+----------------------------------------------------

  On Windows, the Mercury compiler will only generate a process assembly, e.g.
-hello.exe.  (On Windows there is no need to generate a wrapper shell script.)
+`hello.exe`. On Windows there is no need to generate a wrapper shell script.

  With .NET, the library assemblies (.dlls) for the Mercury standard
  libraries must either (1) reside in (or under) the same directory as the process
@@ -65,42 +87,96 @@ assembly (.exe) or (2) be entered into the global assembly cache (GAC).
  If neither of these things is done then execution will abort with a message that
  begins:

-     Unhandled Exception: System.IO.FileNotFoundException: Could not load file
-     or assembly 'mer_std',  Version=...
+```
+    Unhandled Exception: System.IO.FileNotFoundException: Could not load file
+    or assembly 'mer_std',  Version=...
+```

  For (1), you will need to copy the library assemblies from the Mercury library
-installation into the same directory as the process assembly.
-The files for the library assemblies are located in
+installation directory into the same directory as the process assembly.
+The files for the Mercury library assemblies are located in

+```
       <prefix>\lib\mercury\lib\csharp
+```

-where <prefix> is the location of the Mercury installation.
-Copy all of the dll files in the above directory into that of the process
+where `<prefix>` is the location of the Mercury installation.
+Copy all of the .dll files in the above directory into that of the process
  assembly.

  To enter assemblies into the GAC, run the following command for each
  assembly.

-            gacutil /i mer_std.dll
+```
+    gacutil /i mer_std.dll
+```

  Assemblies can be removed from the GAC by doing, for example

+```
      gacutil /u mer_std.dll
+```

------------------------------------------------------------------------------
+Limitations
+-----------
+
+The following features of the Mercury implementation are not (currently)
+supported by the C# backend:

-USING C#
+* Mercury-level debugging (however, see further down).
+* Mercury-level profiling.
+* Trailing.
+* Tabling.
+* Backjumping.
+
+Library support
+----------------

  The Mercury standard library has not been fully ported to C# 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.
+with a stack trace and a message like:
+
+```
+    Sorry, not implemented: foreign code for this function
+```

  If you find missing functionality, you can interface to C# using Mercury's
  foreign language interface.

-For example:
+The following individual Mercury standard library procedures are either not
+supported or not fully implemented:
+ 
+1. `io.read_binary/{3,4}` 
+   `io.write_binary/{3,4}`
+
+    The current implementation of `read_binary` does not work with the
+    way Mercury file streams are implemented for the C# backend.
+
+2. `benchmarking.report_stats/0` 
+   `benchmarking.report_full_memory_stats/0`
+
+    Memory usage statistics are not yet available, and cpu time
+    is not the same as in the C backends, as per `time.m`.
+
+3. `store.arg_ref/5` 
+   `store.new_arg_ref/5`
+
+    Due to some limitations in RTTI support, dynamic type checking is missing
+    for these predicates. They should be used with care.
+
+4.  `math.fma/3`
+
+    This function is not available because it is not supported by C# 5.0.
+    (It will be supported once the minimum version of C# required by
+    Mercury increases.)
+
+Interfacing with C#
+-------------------

+You can call C# code directly from Mercury using the foreign language
+interface. For example:
+
+```
  :- pred to_string(T::in, string::out) is det.
  :- pragma foreign_proc("C#",
      to_string(T::in, Str::out),
@@ -108,95 +184,57 @@ For example:
  "
      Str = T.ToString();
  ").
+```

-The implementation will include this C# code in the module's .cs file, and
-you can then call the predicate to_string exactly the same as if it were
+The implementation will include this C# code in the module's .cs file, and you
+can then call the predicate `to_string/2` exactly the same as if it were
  implemented using pure Mercury code.

-For more information about the foreign language interface, see the Mercury
-Language Reference Manual, which you can find at:
+For more information about the foreign language interface, see the
+[Mercury Language Reference Manual](https://www.mercurylang.org/information/documentation.html).
+Additionally, the [samples/csharp_interface](samples/csharp_interface) directory in
+the Mercury distribution contains examples of how to use the foreign language
+interface with C#.

-     <http://www.mercurylang.org/information/documentation.html>
+Mercury-level debugging
+-----------------------

------------------------------------------------------------------------------
+The only Mercury-level debugger available for the C# backend is the
+_experimental_ source-to-source debugger; see [README.ssdebug](README.ssdebug)
+for details.

-BUILDING THE MERCURY COMPILER IN THE C# GRADE
+Building the Mercury compiler in the `csharp` grade
+---------------------------------------------------

-Building the Mercury compiler and other related tools in the C# grade
-is NOT generally supported and should be considered experimental.
+Building the Mercury compiler and other related tools in the C# grade is NOT
+generally supported and should be considered experimental.
  In particular, a Mercury compiler built in the C# grade may be slower than
  normal and some features may not be available.

  However, if you want to give it a try, the required steps are:

-(1) Ensure that you have an existing working Mercury compiler in your PATH
-and a clean version of the Mercury source tree.
-
-(2) Run ./prepare.sh; ./configure as normal.
-
-(3) Add the line:
-
-      GRADE=csharp
-
-    to a file named Mmake.params at the top-level of the source tree.
-
-(4) Begin the build process using the following command:
-
-    $ mmake --use-mmc-make GRADE=csharp
-
-The C# version of the compiler MUST be built using mmake's --use-mmc-make
-option; the build will not work otherwise.  Setting the variable GRADE in the
-invocation of mmake is currently necessary in order to avoid some variable
-definition ordering problems in Mmake.workspace.
-
-(5) To install the C# version of the compiler, do:
-
-   $ mmake --use-mmc-make install GRADE=csharp
-
------------------------------------------------------------------------------
-
-FREQUENTLY ASKED QUESTIONS (FAQS)
-
-Q. What are the advantages of using the C# back-end?
-
-A. The main advantage is easy access to the wide range of libraries for the
-   .NET platform, and the portability you get from using CIL bytecode.
-
-
-Q. What features are not yet implemented for the C# back-end?
-
-A. The following implementation features are not supported:
-
-	Mercury-level debugging (but see next question)
-	Mercury-level profiling
-	trailing
-	tabling
-	backjumping
+1. Ensure that you have an existing working Mercury compiler in your `PATH`
+   and a clean version of the Mercury source tree.

-   In addition, the following individual procedures are incompletely
-   implemented:
+2. Run `prepare.sh` and `configure` as normal.

-	io.read_binary/{3,4}:
-	io.write_binary/{3,4}:
-		io.read_binary is broken.
+3. Add the line:

-	benchmarking.report_stats/0:
-	benchmarking.report_full_memory_stats/0:
-		Memory usage statistics are not yet available, and cpu time
-		is not the same as in the C backends, as per time.m.
+       GRADE=csharp

-	store.arg_ref/5:
-	store.new_arg_ref/5:
-		Due to the absence of RTTI, dynamic type checking is missing
-		for these predicates.  They should be used with care.
+    to a file named `Mmake.params` at the top-level of the source tree.

-   This list is not complete.
+4. Begin the build process using the following command:

+       $ mmake --use-mmc-make GRADE=csharp

-Q. How do I debug Mercury programs on .NET?
+   The C# version of the compiler MUST be built using `mmake`'s `--use-mmc-make`
+   option; the build will not work otherwise. Setting the variable `GRADE` in the
+   invocation of mmake is currently necessary in order to avoid some variable
+   definition ordering problems in `Mmake.workspace`.

-A. The only Mercury-level debugger available for C# grades is the
-   source-to-source debugger; see README.ssdebug.
+5. To install the C# version of the compiler, do:

+       $ mmake --use-mmc-make install GRADE=csharp

  -----------------------------------------------------------------------------
diff --git a/README.md b/README.md
index 02eec9d6f..92ffc1017 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ Specific information is contained in individual README files:
    * High-level backend targets

        * C
-      * [C#](README.CSharp)
+      * [C#](README.CSharp.md)
        * [Java](README.Java.md)

    * Supported operating systems


More information about the reviews mailing list