[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