diff --git a/.nocopyright b/.nocopyright index 4932de3e5c..aa6515eb2e 100644 --- a/.nocopyright +++ b/.nocopyright @@ -34,3 +34,4 @@ README.MS-Windows README.OSF1 README.Solaris README.ssdebug +README.CSharp diff --git a/Mmake.workspace b/Mmake.workspace index bd22f8fb62..3c409519a1 100644 --- a/Mmake.workspace +++ b/Mmake.workspace @@ -1,5 +1,5 @@ #-----------------------------------------------------------------------------# -# Copyright (C) 2002-2008 The University of Melbourne. +# Copyright (C) 2002-2008, 2010 The University of Melbourne. # This file may only be copied under the terms of the GNU General # Public Licence - see the file COPYING in the Mercury distribution. #-----------------------------------------------------------------------------# @@ -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 0000000000..11b2bfc3a7 --- /dev/null +++ b/README.CSharp @@ -0,0 +1,124 @@ +----------------------------------------------------------------------------- + +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 on 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 than 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. + +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: + + + +----------------------------------------------------------------------------- + +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 be6c1ee66b..784c080f4f 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.Charp for details of a newer backend that targets .NET. + INTRODUCTION This release of Mercury contains a port to the Microsoft.NET Common diff --git a/README.Erlang b/README.Erlang index 5a86d71aed..c52394df1f 100644 --- a/README.Erlang +++ b/README.Erlang @@ -19,16 +19,6 @@ In order to try this system you will need downloaded from - - The Mercury source distribution. See below for installation - instructions. - - If you're reading this file from somewhere other than the - Mercury distribution, try the Mercury homepage at - - - - An installed Mercury compiler. You must use `mmc --make' to - install the standard library for Erlang. See below. - - A Unix-like environment. The Erlang support has not been tested on Windows, but you will need a shell script interpreter. diff --git a/README.Java b/README.Java index b87bf41684..83dae4b883 100644 --- a/README.Java +++ b/README.Java @@ -21,13 +21,6 @@ In order to try this system you will need OR any other compatible Java implementation. - - 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 - - WARNING Please note that the Java backend is still an experimental feature. diff --git a/README.ssdebug b/README.ssdebug index 3e5475e0b5..4e6a8c5f51 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 808d4e99c7..cb5687bcfe 100644 --- a/browser/Mercury.options +++ b/browser/Mercury.options @@ -1,5 +1,5 @@ #-----------------------------------------------------------------------------# -# Copyright (C) 2002-2006 University of Melbourne. +# Copyright (C) 2002-2006, 2010 University of Melbourne. # This file may only be copied under the terms of the GNU General # Public License - see the file COPYING in the Mercury distribution. #-----------------------------------------------------------------------------# @@ -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 6e8e726cb3..17eb5f1b4b 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 a11a20d86e..ef73df8875 100644 --- a/browser/declarative_execution.m +++ b/browser/declarative_execution.m @@ -1,7 +1,7 @@ %-----------------------------------------------------------------------------% % vim: ft=mercury ts=4 sw=4 et %-----------------------------------------------------------------------------% -% Copyright (C) 1999-2007 The University of Melbourne. +% Copyright (C) 1999-2007, 2010 The University of Melbourne. % This file may only be copied under the terms of the GNU Library General % Public License - see the file COPYING.LIB in the Mercury distribution. %-----------------------------------------------------------------------------% @@ -538,6 +538,13 @@ impure cache_proc_defn_rep(ProcLayout, ProcDefnRep), } "). +:- 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 @@ impure cache_proc_defn_rep(ProcLayout, ProcDefnRep), } "). +:- 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 b8475341c0..3349fbca29 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 09fbaf86f2..a40711ee49 100644 --- a/configure.in +++ b/configure.in @@ -3345,6 +3345,11 @@ AC_ARG_ENABLE(dotnet-grades, AC_HELP_STRING([--enable-dotnet-grades], [install the .NET grades]), enable_dotnet_grades="$enableval",enable_dotnet_grades=no) +# We don't enable the csharp grade by default. +AC_ARG_ENABLE(csharp-grade, + AC_HELP_STRING([--enable-csharp-grade], [install the C# grade]), + enable_csharp_grade="$enableval",enable_csharp_grade=no) + # We don't enable the java grade by default. AC_ARG_ENABLE(java-grade, AC_HELP_STRING([--enable-java-grade], [install the Java grade]), @@ -3378,6 +3383,7 @@ if test "$enable_most_grades" = no; then enable_par_grades=no enable_stseg_grades=no enable_dotnet_grades=no + enable_csharp_grade=no enable_java_grade=no enable_erlang_grade=no fi @@ -3601,6 +3607,12 @@ then LIBGRADES="$LIBGRADES il" fi +# Add C# back-end grade, if a C# compiler is installed. +if test "$CSC" != "" -a "$enable_csharp_grade" = yes +then + LIBGRADES="$LIBGRADES csharp" +fi + # Add Java back-end grade, if Java is installed. if test $mercury_cv_java = yes -a "$enable_java_grade" = yes then @@ -3626,6 +3638,9 @@ if test "$enable_ssdebug_grades" = yes; then case "$LIBGRADES" in *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 diff --git a/library/exception.m b/library/exception.m index 5caa016310..5056f1afc6 100644 --- a/library/exception.m +++ b/library/exception.m @@ -1443,10 +1443,24 @@ void MR_CALL success_cont(void) { %-----------------------------------------------------------------------------% +:- 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 @@ void MR_CALL success_cont(void) { 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 @@ void MR_CALL success_cont(void) { 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 pred = (runtime.MethodPtr3_r0) 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) cont)(T, cont_env_ptr); @@ -1516,12 +1537,14 @@ void MR_CALL success_cont(void) { 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 pred = (runtime.MethodPtr3_r0) 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) cont)(T, cont_env_ptr); diff --git a/mdbcomp/Mmakefile b/mdbcomp/Mmakefile index c7eced360a..3aaa7e9b86 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 ef03464a5b..d3ce6c8ae9 100644 --- a/ssdb/Mercury.options +++ b/ssdb/Mercury.options @@ -1,5 +1,5 @@ #-----------------------------------------------------------------------------# -# Copyright (C) 2007 University of Melbourne. +# Copyright (C) 2007, 2010 University of Melbourne. # This file may only be copied under the terms of the GNU General # Public License - see the file COPYING in the Mercury distribution. #-----------------------------------------------------------------------------# @@ -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 d9f35e864c..9a0f6d2f29 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 dab37c45cb..ba42a5fc64 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 void handle(sun.misc.Signal sig) { :- 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 @@ impure consume_io(!.IO) 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 @@ public void on_catch_impl_exception(int CSN) { "). :- 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 @@ impure consume_io(!.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 @@ impure consume_io(!.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 @@ impure consume_io(!.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 @@ impure consume_io(!.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],