[m-rev.] for review: csharp.ssdebug and readme
Peter Wang
novalazy at gmail.com
Mon Oct 25 15:23:04 AEDT 2010
Branches: main
Make it possible to install and use the csharp.ssdebug grade.
Mmake.workspace:
Never try to link with `mer_rt' in C# grades.
browser/Mmakefile:
mdbcomp/Mmakefile:
ssdb/Mmakefile:
Use `mmc --make' to install these libraries in `csharp' grades.
Don't add C libraries to MLLIBS in non-C or asm grades.
browser/Mercury.options:
ssdb/Mercury.options:
"EXTRA_LIBRARIES-libname" doesn't actually work with `mmc --make',
but "LIBRARIES-name" does.
library/exception.m:
ssdb/ssdb.m:
Handle EXCP events in C# grades.
Trap SIGINT when running ssdb in C# grades.
Add `exit_process' implementation.
browser/declarative_execution.m:
browser/listing.m:
Add stubs for C#.
README.CSharp:
Document the C# backend.
README.DotNet:
Add a pointer to README.CSharp.
configure.in:
Make `configure --enable-ssdebug-grades' add `csharp.ssdebug'
to the list of library grades.
diff --git a/Mmake.workspace b/Mmake.workspace
index bd22f8f..236bdb2 100644
--- a/Mmake.workspace
+++ b/Mmake.workspace
@@ -211,7 +211,12 @@ LINK_RT_LIB_OPTS=
LINK_STD_LIB_OPTS=
LINK_TRACE_SSDB_LIB_OPTS=
ifneq ($(LINK_BOEHM_GC_ONLY),yes)
+ifneq ("$(filter csharp%,$(GRADE))","")
+# There is no separate runtime library for C# grades.
+LINK_RT_LIB_OPTS =
+else
LINK_RT_LIB_OPTS = -l$(RT_LIB_NAME)
+endif
ifneq ($(LINK_RUNTIME_ONLY),yes)
LINK_STD_LIB_OPTS = -l$(STD_LIB_NAME)
ifneq ($(LINK_STDLIB_ONLY),yes)
diff --git a/README.CSharp b/README.CSharp
new file mode 100644
index 0000000..4fd3702
--- /dev/null
+++ b/README.CSharp
@@ -0,0 +1,131 @@
+-----------------------------------------------------------------------------
+
+INTRODUCTION
+
+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 in the .NET or Mono runtime systems.
+
+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).
+
+The port is currently targeted at C# 2.0 or higher.
+
+NOTE: a previous backend also targetted the .NET runtime, by generating IL
+(Intermediate Language), rather going via C#. That backend is out-of-date
+and may be removed in the future.
+
+PREREQUISITES
+
+In order to try this system you will need
+
+ - Either Microsoft.NET or Mono 2.8 or above.
+
+ - The Mercury distribution -- installed as usual. 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.mercury.csse.unimelb.edu.au>
+
+WARNING
+
+Please note that the C# backend is still an experimental feature.
+
+-----------------------------------------------------------------------------
+
+THE C# GRADE
+
+The Mercury compiler currently supports the grade `csharp'.
+The csharp grade is enabled by using any of the options
+`--grade csharp', `--target csharp', or just `--csharp'.
+
+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.
+
+You can now build programs such as hello.m or calculator.m in the samples
+directory.
+
+ cd samples
+ mmc --make --csharp hello
+
+Now you can run hello
+
+ ./hello
+
+-----------------------------------------------------------------------------
+
+USING C#
+
+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.
+
+If you find missing functionality, you can interface to C# using 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), [],
+"
+ 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
+implemented using pure Mercury code.
+
+For more information about the foreign language interface, see the Mercury
+Language Reference Manual, which you can find at:
+
+ <http://www.mercury.csse.unimelb.edu.au/information/documentation.html>
+
+-----------------------------------------------------------------------------
+
+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
+
+ In addition, the following individual procedures are incompletely
+ implemented:
+
+ io.read_binary/{3,4}:
+ io.write_binary/{3,4}:
+ io.read_binary is broken.
+
+ 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.
+
+ 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.
+
+ This list is not complete.
+
+
+Q. How do I debug Mercury programs on .NET?
+
+A. The only Mercury-level debugger available for C# grades is the
+ source-to-source debugger; see README.ssdebug.
+
+
+-----------------------------------------------------------------------------
diff --git a/README.DotNet b/README.DotNet
index be6c1ee..42ecbb5 100644
--- a/README.DotNet
+++ b/README.DotNet
@@ -1,5 +1,10 @@
-----------------------------------------------------------------------------
+WARNING
+
+The .NET backend described herein is out-of-date and may be removed in
+the future. See README.CSharp about a newer backend that targets C#.
+
INTRODUCTION
This release of Mercury contains a port to the Microsoft.NET Common
diff --git a/README.ssdebug b/README.ssdebug
index 3e5475e..4e6a8c5 100644
--- a/README.ssdebug
+++ b/README.ssdebug
@@ -18,7 +18,8 @@ INSTALLATION
To use the source-to-source debugger you must install grades containing the
".ssdebug" grade component. One way to do this is to invoke configure
with the option `--enable-ssdebug-grades'. This will add the grades
-hlc.gc.ssdebug and java.ssdebug to the set of library grades to install.
+hlc.gc.ssdebug, csharp.ssdebug and java.ssdebug to the set of library grades
+to install.
-----------------------------------------------------------------------------
@@ -59,7 +60,7 @@ increase the stack size, e.g.
LIMITATIONS
- There are no internal events. The only events are CALL, EXIT, REDO, FAIL,
- and, for Java grades, EXCP.
+ and, for Java and C# grades, EXCP.
- Standard library procedures are treated specially. Events will only be
generated at the boundaries at which a user procedure calls and returns
@@ -72,13 +73,16 @@ LIMITATIONS
reach the end of the procedure to retry, the program will simply keep
executing. Press ^C to get back the debugger prompt.
-- Exceptions are only handled in Java grades. Only a single EXCP event is
- generated when an exception is thrown, instead of propagating EXCP events
+- When running on Mono, ^C sometimes causes the program to hang.
+ This appears to be a bug in Mono.
+
+- Exceptions are only handled in Java and C# grades. Only a single EXCP event
+ is generated when an exception is thrown, instead of propagating EXCP events
up the call stack to the nearest exception handler.
-- In non-Java grades, the debugger's internal state will be inconsistent with
- the program's execution after an exception, so you had better quit the
- program and restart.
+- In grades which don't handle exceptions, the debugger's internal state will
+ be inconsistent with the program's execution after an exception, so you had
+ better quit the program and restart.
- Breakpoints currently match procedures by module and name only. Predicates
or functions with the same name but different arities will still match.
diff --git a/browser/Mercury.options b/browser/Mercury.options
index 808d4e9..10076f4 100644
--- a/browser/Mercury.options
+++ b/browser/Mercury.options
@@ -23,7 +23,7 @@ MCFLAGS-mdb.declarative_execution = --no-optimize-unused-args
# XXX This line is needed so that `mmake --use-mmc-make libmer_browser'
# passes `-lmer_mdbcomp' to `mmc --make' in the MLLIBS variable.
-EXTRA_LIBRARIES-libmer_browser = mer_mdbcomp
+LIBRARIES-mer_browser = mer_mdbcomp
# Whereas these lines are needed for plain `mmake'.
EXTRA_LIBRARIES-libmer_browser.so = mer_mdbcomp
diff --git a/browser/Mmakefile b/browser/Mmakefile
index 6e8e726..17eb5f1 100644
--- a/browser/Mmakefile
+++ b/browser/Mmakefile
@@ -65,8 +65,10 @@ MLFLAGS += -R$(FINAL_INSTALL_MERC_LIB_DIR) \
MCFLAGS += -R$(FINAL_INSTALL_MERC_LIB_DIR) \
-R$(FINAL_INSTALL_MERC_GC_LIB_DIR)
endif
+ifeq ("$(filter il% csharp% java% erlang%,$(GRADE))","")
MLLIBS += $(SOCKET_LIBRARY) $(NSL_LIBRARY) $(DL_LIBRARY) \
$(READLINE_LIBRARIES)
+endif
MCFLAGS += --flags MDB_FLAGS $(CONFIG_OVERRIDE)
@@ -252,14 +254,14 @@ realclean_local:
.PHONY: install
install: install_library
-ifneq ("$(filter il% csharp% erlang%,$(GRADE))","")
+ifneq ("$(filter il% erlang%,$(GRADE))","")
# there is no browser in the .NET or Erlang backends
.PHONY: install_library
install_library:
-else ifneq (,$(findstring java,$(GRADE)))
+else ifeq ($(MMAKE_USE_MMC_MAKE),yes)
.PHONY: install_library
install_library: lib$(BROWSER_LIB_NAME).install
diff --git a/browser/declarative_execution.m b/browser/declarative_execution.m
index a11a20d..55b7199 100644
--- a/browser/declarative_execution.m
+++ b/browser/declarative_execution.m
@@ -538,6 +538,13 @@ call_node_bytecode_layout(_, _) :-
}
").
+:- pragma foreign_proc("C#",
+ call_node_bytecode_layout(_CallLabelLayout::in, _ProcLayout::out),
+ [will_not_call_mercury, thread_safe, promise_pure],
+"
+ if (1 == 1) throw new System.Exception(\"not supported in csharp grade\");
+").
+
:- pragma foreign_proc("Java",
call_node_bytecode_layout(_CallLabelLayout::in, _ProcLayout::out),
[will_not_call_mercury, thread_safe, promise_pure],
@@ -570,6 +577,13 @@ have_cached_proc_defn_rep(_, _) :-
}
").
+:- pragma foreign_proc("C#",
+ have_cached_proc_defn_rep(_ProcLayout::in, _ProcDefnRep::out),
+ [will_not_call_mercury, thread_safe, promise_semipure],
+"
+ if (1 == 1) throw new System.Exception(\"not supported in csharp grade\");
+").
+
:- pragma foreign_proc("Java",
have_cached_proc_defn_rep(_ProcLayout::in, _ProcDefnRep::out),
[will_not_call_mercury, thread_safe, promise_semipure],
diff --git a/browser/listing.m b/browser/listing.m
index b847534..3349fbc 100644
--- a/browser/listing.m
+++ b/browser/listing.m
@@ -104,6 +104,7 @@
:- pragma foreign_type("C", c_file_ptr, "FILE *", [can_pass_as_mercury_type]).
% stub.
+:- pragma foreign_type("C#", c_file_ptr, "object").
:- pragma foreign_type("Java", c_file_ptr, "java.lang.Object").
% These predicates are called from trace/mercury_trace_internal.c.
diff --git a/configure.in b/configure.in
index 42073b5..f93e59a 100644
--- a/configure.in
+++ b/configure.in
@@ -3599,6 +3599,9 @@ if test "$enable_ssdebug_grades" = yes; then
*hlc.gc*) LIBGRADES="$LIBGRADES hlc.gc.ssdebug" ;;
esac
case "$LIBGRADES" in
+ *csharp*) LIBGRADES="$LIBGRADES csharp.ssdebug" ;;
+ esac
+ case "$LIBGRADES" in
*java*) LIBGRADES="$LIBGRADES java.ssdebug" ;;
esac
fi
diff --git a/library/exception.m b/library/exception.m
index 5caa016..5056f1a 100644
--- a/library/exception.m
+++ b/library/exception.m
@@ -1443,10 +1443,24 @@ mercury__exception__builtin_catch_model_non(MR_Mercury_Type_Info type_info,
%-----------------------------------------------------------------------------%
+:- pragma foreign_code("C#", "
+/*
+ * The ssdb module may supply its implementation of these methods at runtime.
+ */
+public class SsdbHooks {
+ public virtual void on_throw_impl(univ.Univ_0 univ) {}
+ public virtual int on_catch_impl() { return 0; }
+ public virtual void on_catch_impl_exception(int CSN) {}
+}
+
+public static SsdbHooks ssdb_hooks = new SsdbHooks();
+").
+
:- pragma foreign_proc("C#",
throw_impl(T::in),
[will_not_call_mercury, promise_pure],
"
+ exception.ssdb_hooks.on_throw_impl(T);
throw new runtime.Exception(T);
").
@@ -1454,22 +1468,27 @@ mercury__exception__builtin_catch_model_non(MR_Mercury_Type_Info type_info,
catch_impl(Pred::pred(out) is det, Handler::in(handler), T::out),
[will_not_call_mercury, promise_pure],
"
+ int CSN = ssdb_hooks.on_catch_impl();
try {
T = exception.ML_call_goal_det(TypeInfo_for_T, Pred);
}
catch (runtime.Exception ex) {
+ exception.ssdb_hooks.on_catch_impl_exception(CSN);
T = exception.ML_call_handler_det(TypeInfo_for_T, Handler,
(univ.Univ_0) ex.exception);
}
").
+
:- pragma foreign_proc("C#",
catch_impl(Pred::pred(out) is cc_multi, Handler::in(handler), T::out),
[will_not_call_mercury, promise_pure],
"
+ int CSN = ssdb_hooks.on_catch_impl();
try {
T = exception.ML_call_goal_det(TypeInfo_for_T, Pred);
}
catch (runtime.Exception ex) {
+ exception.ssdb_hooks.on_catch_impl_exception(CSN);
T = exception.ML_call_handler_det(TypeInfo_for_T, Handler,
(univ.Univ_0) ex.exception);
}
@@ -1497,12 +1516,14 @@ mercury__exception__builtin_catch_model_non(MR_Mercury_Type_Info type_info,
catch_impl(Pred::pred(out) is multi, Handler::in(handler), _T::out),
[will_not_call_mercury, promise_pure, ordinary_despite_detism],
"
+ int CSN = ssdb_hooks.on_catch_impl();
try {
runtime.MethodPtr3_r0<object, object, object> pred =
(runtime.MethodPtr3_r0<object, object, object>) Pred[1];
pred(Pred, cont, cont_env_ptr);
}
catch (runtime.Exception ex) {
+ ssdb_hooks.on_catch_impl_exception(CSN);
object T = exception.ML_call_handler_det(TypeInfo_for_T, Handler,
(univ.Univ_0) ex.exception);
((runtime.MethodPtr2_r0<object, object>) cont)(T, cont_env_ptr);
@@ -1516,12 +1537,14 @@ mercury__exception__builtin_catch_model_non(MR_Mercury_Type_Info type_info,
catch_impl(Pred::pred(out) is nondet, Handler::in(handler), _T::out),
[will_not_call_mercury, promise_pure, ordinary_despite_detism],
"
+ int CSN = ssdb_hooks.on_catch_impl();
try {
runtime.MethodPtr3_r0<object, object, object> pred =
(runtime.MethodPtr3_r0<object, object, object>) Pred[1];
pred(Pred, cont, cont_env_ptr);
}
catch (runtime.Exception ex) {
+ ssdb_hooks.on_catch_impl_exception(CSN);
object T = exception.ML_call_handler_det(TypeInfo_for_T, Handler,
(univ.Univ_0) ex.exception);
((runtime.MethodPtr2_r0<object, object>) cont)(T, cont_env_ptr);
diff --git a/mdbcomp/Mmakefile b/mdbcomp/Mmakefile
index c7eced3..3aaa7e9 100644
--- a/mdbcomp/Mmakefile
+++ b/mdbcomp/Mmakefile
@@ -56,8 +56,10 @@ MLFLAGS += -R$(FINAL_INSTALL_MERC_LIB_DIR) \
MCFLAGS += -R$(FINAL_INSTALL_MERC_LIB_DIR) \
-R$(FINAL_INSTALL_MERC_GC_LIB_DIR)
endif
+ifeq ("$(filter il% csharp% java% erlang%,$(GRADE))","")
MLLIBS += $(SOCKET_LIBRARY) $(NSL_LIBRARY) $(DL_LIBRARY) \
$(READLINE_LIBRARIES)
+endif
#-----------------------------------------------------------------------------#
@@ -211,14 +213,14 @@ realclean_local:
.PHONY: install
install: install_library
-ifneq ("$(filter il% csharp% erlang%,$(GRADE))","")
+ifneq ("$(filter il% erlang%,$(GRADE))","")
# there is no debugger in the .NET or Erlang backends
.PHONY: install_library
install_library:
-else ifneq (,$(findstring java,$(GRADE)))
+else ifeq ($(MMAKE_USE_MMC_MAKE),yes)
.PHONY: install_library
install_library: lib$(MDBCOMP_LIB_NAME).install
diff --git a/ssdb/Mercury.options b/ssdb/Mercury.options
index ef03464..1fb394c 100644
--- a/ssdb/Mercury.options
+++ b/ssdb/Mercury.options
@@ -10,7 +10,7 @@ MCFLAGS-mer_ssdb = --no-warn-nothing-exported --no-warn-unused-imports
# XXX This line is needed so that `mmake --use-mmc-make libmer_ssdb'
# passes `-lmer_mdbcomp' to `mmc --make' in the MLLIBS variable.
-EXTRA_LIBRARIES-libmer_ssdb = mer_mdbcomp mer_browser
+LIBRARIES-mer_ssdb = mer_mdbcomp mer_browser
# Whereas these lines are needed for plain `mmake'.
EXTRA_LIBRARIES-libmer_ssdb.so = mer_mdbcomp mer_browser
diff --git a/ssdb/Mmakefile b/ssdb/Mmakefile
index d9f35e8..9a0f6d2 100644
--- a/ssdb/Mmakefile
+++ b/ssdb/Mmakefile
@@ -65,8 +65,10 @@ MLFLAGS += -R$(FINAL_INSTALL_MERC_LIB_DIR) \
MCFLAGS += -R$(FINAL_INSTALL_MERC_LIB_DIR) \
-R$(FINAL_INSTALL_MERC_GC_LIB_DIR)
endif
+ifeq ("$(filter il% csharp% java% erlang%,$(GRADE))","")
MLLIBS += $(SOCKET_LIBRARY) $(NSL_LIBRARY) $(DL_LIBRARY) \
$(READLINE_LIBRARIES)
+endif
MCFLAGS += --flags SSDB_FLAGS $(CONFIG_OVERRIDE)
@@ -246,14 +248,14 @@ realclean_local:
.PHONY: install
install: install_library
-ifneq ("$(filter il% csharp% erlang%,$(GRADE))","")
+ifneq ("$(filter il% erlang%,$(GRADE))","")
# there is no ssdb in the .NET or Erlang backends
.PHONY: install_library
install_library:
-else ifneq (,$(findstring java,$(GRADE)))
+else ifeq ($(MMAKE_USE_MMC_MAKE),yes)
.PHONY: install_library
install_library: lib$(SSDB_LIB_NAME).install
diff --git a/ssdb/ssdb.m b/ssdb/ssdb.m
index dab37c4..ba42a5f 100755
--- a/ssdb/ssdb.m
+++ b/ssdb/ssdb.m
@@ -470,6 +470,27 @@ static void MR_ssdb_sigint_handler(void)
}
").
+:- pragma foreign_proc("C#",
+ install_sigint_handler(IO0::di, IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
+"
+ System.Console.TreatControlCAsInput = false;
+ System.Console.CancelKeyPress += new System.ConsoleCancelEventHandler(
+ ssdb.sigint_handler
+ );
+ IO = IO0;
+").
+
+:- pragma foreign_code("C#",
+"
+static void sigint_handler(object sender, System.ConsoleCancelEventArgs args)
+{
+ SSDB_step_next_stop();
+ // Don't terminate the process.
+ args.Cancel = true;
+}
+").
+
:- pragma foreign_proc("Java",
install_sigint_handler(IO0::di, IO::uo),
[will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
@@ -496,6 +517,8 @@ public static class SigIntHandler implements sun.misc.SignalHandler {
:- pragma foreign_export("C", step_next_stop(di, uo),
"SSDB_step_next_stop").
+:- pragma foreign_export("C#", step_next_stop(di, uo),
+ "SSDB_step_next_stop").
:- pragma foreign_export("Java", step_next_stop(di, uo),
"SSDB_step_next_stop").
@@ -802,6 +825,30 @@ search_nondet_stack_frame_2(ProcId, Depth, N, StackDepth, MaybeStackFrame,
install_exception_hooks(!IO).
+:- pragma foreign_proc("C#",
+ install_exception_hooks(_IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
+"
+ exception.ssdb_hooks = new ssdb.SsdbHooks();
+").
+
+:- pragma foreign_code("C#", "
+private class SsdbHooks : exception.SsdbHooks {
+ public override void on_throw_impl(univ.Univ_0 univ) {
+ ssdb.SSDB_handle_event_excp(""exception"", ""throw_impl"", univ);
+ }
+
+ public override int on_catch_impl() {
+ return ssdb.SSDB_get_cur_ssdb_csn();
+ }
+
+ public override void on_catch_impl_exception(int CSN) {
+ ssdb.SSDB_rollback_stack(CSN);
+ ssdb.SSDB_rollback_nondet_stack(CSN);
+ }
+}
+").
+
:- pragma foreign_proc("Java",
install_exception_hooks(_IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
@@ -830,6 +877,8 @@ private static class SsdbHooks extends exception.SsdbHooks {
").
:- impure pred handle_event_excp(string::in, string::in, univ::in) is det.
+:- pragma foreign_export("C#", handle_event_excp(in, in, in),
+ "SSDB_handle_event_excp").
:- pragma foreign_export("Java", handle_event_excp(in, in, in),
"SSDB_handle_event_excp").
@@ -880,6 +929,8 @@ handle_event_excp_2(ProcId, ListVarValue, !IO) :-
%----------------------------------------------------------------------------%
+:- pragma foreign_export("C#", get_cur_ssdb_csn(out),
+ "SSDB_get_cur_ssdb_csn").
:- pragma foreign_export("Java", get_cur_ssdb_csn(out),
"SSDB_get_cur_ssdb_csn").
@@ -1004,6 +1055,8 @@ nondet_stack_pop(!IO) :-
).
:- pred rollback_stack(int::in, io::di, io::uo) is det.
+:- pragma foreign_export("C#", rollback_stack(in, di, uo),
+ "SSDB_rollback_stack").
:- pragma foreign_export("Java", rollback_stack(in, di, uo),
"SSDB_rollback_stack").
@@ -1017,6 +1070,8 @@ rollback_stack(TargetCSN, !IO) :-
).
:- pred rollback_nondet_stack(int::in, io::di, io::uo) is det.
+:- pragma foreign_export("C#", rollback_nondet_stack(in, di, uo),
+ "SSDB_rollback_nondet_stack").
:- pragma foreign_export("Java", rollback_nondet_stack(in, di, uo),
"SSDB_rollback_nondet_stack").
@@ -3365,6 +3420,13 @@ restore_streams(!IO) :-
IO = IO0;
").
+:- pragma foreign_proc("C#",
+ exit_process(_IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ System.Environment.Exit(0);
+").
+
:- pragma foreign_proc("Java",
exit_process(_IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure, tabled_for_io],
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list