[m-rev.] for review: samples/java_interface

Peter Wang novalazy at gmail.com
Wed Jul 7 14:25:39 AEST 2010


Branches: main, 10.04

samples/README:
samples/java_interface/README:
samples/java_interface/java_calls_mercury/JavaMain.java:
samples/java_interface/java_calls_mercury/Makefile:
samples/java_interface/java_calls_mercury/java_main_int.m:
samples/java_interface/java_calls_mercury/mercury_lib.m:
samples/java_interface/java_calls_mercury/mercury_main.m:
samples/java_interface/mercury_calls_java/JavaMain.java:
samples/java_interface/mercury_calls_java/Makefile:
samples/java_interface/mercury_calls_java/java_main_int.m:
samples/java_interface/mercury_calls_java/mercury_main.m:
        Add examples of Mercury/Java integration.

diff --git a/samples/README b/samples/README
index ef3ad58..051d5b4 100644
--- a/samples/README
+++ b/samples/README
@@ -58,6 +58,10 @@ diff                    This directory contains an implementation of a
 c_interface		This directory contains some examples of mixed
 			Mercury/C/C++/Fortran programs using the C interface.
 
+java_interface		This directory contains some examples of mixed
+			Mercury/Java programs using the foreign language
+			interface.
+
 rot13			This directory contains a few implementations of
 			rot-13 encoding.
 
diff --git a/samples/java_interface/README b/samples/java_interface/README
new file mode 100644
index 0000000..d4bc3b8
--- /dev/null
+++ b/samples/java_interface/README
@@ -0,0 +1,10 @@
+
+This directory contains some examples of mixed Mercury/Java programs using
+the Java interface.
+
+mercury_calls_java		A detailed example of Mercury code
+				calling Java code.
+
+java_calls_mercury		A detailed example of Java code calling
+				Mercury code.
+
diff --git a/samples/java_interface/java_calls_mercury/JavaMain.java b/samples/java_interface/java_calls_mercury/JavaMain.java
new file mode 100644
index 0000000..2ce7b5c
--- /dev/null
+++ b/samples/java_interface/java_calls_mercury/JavaMain.java
@@ -0,0 +1,86 @@
+package my_package;
+
+import jmercury.list;
+import jmercury.mercury_lib;
+import static java.lang.System.out;
+
+public class JavaMain {
+    public static void java_main() {
+        out.println("In java_main().");
+
+        /*
+        ** call the Java method foo_test(), which is the interface
+        ** to the Mercury predicate foo/1 in mode
+        **      :- mode foo(in) is semidet.
+        */
+        out.print("foo_test(42) returns ");
+        out.println(mercury_lib.foo_test(42) ? "TRUE" : "FALSE");
+        out.print("foo_test(43) returns ");
+        out.println(mercury_lib.foo_test(43) ? "TRUE" : "FALSE");
+
+        /*
+        ** call the Java method one_foo(), which is the interface
+        ** to the Mercury predicate foo/1 in mode
+        **      :- mode foo(out) is cc_multi.
+        */
+        int value = mercury_lib.one_foo();
+        out.println("one_foo() gives value = " + value);
+
+        /*
+        ** call the Java method foo_list(), which is the interface
+        ** to the Mercury predicate foo/1 in mode
+        **      :- mode foo(out) is multi.
+        */
+        list.List_1<Integer> lst = mercury_lib.foo_list();
+        out.print("foo_list() = ");
+        print_list(lst);
+
+        /*
+        ** call the Java methods bar(), bar_test(), and bar_inverse(),
+        ** which are the interfaces to the Mercury function bar/1
+        ** in the modes
+        **      :- mode bar(in) = out is det.
+        **      :- mode bar(out) = in is det.
+        **      :- mode bar(in) = in is det.
+        ** respectively.
+        */
+        out.println("bar(100) = " + mercury_lib.bar(100));
+        out.print("bar_test(100, 101) returns ");
+        out.println(mercury_lib.bar_test(100, 101) ? "TRUE" : "FALSE");
+        out.print("bar_test(100, 200) returns ");
+        out.println(mercury_lib.bar_test(100, 200) ? "TRUE" : "FALSE");
+        value = mercury_lib.bar_inverse(101);
+        out.println("bar_inverse(101) gives value = " + value);
+        value = mercury_lib.bar_inverse(200);
+        out.println("bar_inverse(200) gives value = " + value);
+
+        jmercury.runtime.Ref<Integer> ref = new jmercury.runtime.Ref<Integer>();
+        if (mercury_lib.baz(1, ref)) {
+            out.println("baz(1, ref) returns TRUE with value = " + ref.val);
+        } else {
+            out.println("baz(100, ref) returns FALSE");
+        }
+        if (mercury_lib.baz(100, ref)) {
+            out.println("baz(100, ref) returns TRUE with value = " + ref.val);
+        } else {
+            out.println("baz(100, ref) returns FALSE");
+        }
+
+        out.println("Returning from java_main()...");
+    }
+
+    static void print_list(list.List_1<Integer> lst) {
+        if (list.is_empty(lst)) {
+            out.println("[]");
+        } else {
+            out.print("[");
+            out.print(list.det_head(lst));
+            lst = list.det_tail(lst);
+            while (!list.is_empty(lst)) {
+                out.print(", " + list.det_head(lst));
+                lst = list.det_tail(lst);
+            }
+            out.println("]");
+        }
+    }
+}
diff --git a/samples/java_interface/java_calls_mercury/Makefile b/samples/java_interface/java_calls_mercury/Makefile
new file mode 100644
index 0000000..5a51ab7
--- /dev/null
+++ b/samples/java_interface/java_calls_mercury/Makefile
@@ -0,0 +1,25 @@
+#-----------------------------------------------------------------------------#
+# This source file is hereby placed in the public domain.
+#-----------------------------------------------------------------------------#
+
+# We need to tell javac about the Mercury libraries.
+GRADE = java
+MER_LIB_DIR = $(dir $(shell which mmc))../lib/mercury/lib/$(GRADE)
+MER_JARS = $(MER_LIB_DIR)/mer_std.jar:$(MER_LIB_DIR)/mer_rt.jar
+
+.PHONY: all
+all: mercury_main
+
+mercury_main: mercury_main.m my_package/JavaMain.class
+	mmc --grade $(GRADE) --make mercury_main --java-classpath .
+
+my_package/JavaMain.class: JavaMain.java libmercury_lib.jar
+	javac JavaMain.java -cp $(MER_JARS):Mercury/classs -d .
+
+libmercury_lib.jar: mercury_lib.m
+	mmc --grade $(GRADE) --make libmercury_lib
+
+.PHONY: clean
+clean:
+	$(RM) mercury_main mercury_lib.jar *.err
+	$(RM) -r Mercury my_package
diff --git a/samples/java_interface/java_calls_mercury/java_main_int.m b/samples/java_interface/java_calls_mercury/java_main_int.m
new file mode 100644
index 0000000..d1d1c13
--- /dev/null
+++ b/samples/java_interface/java_calls_mercury/java_main_int.m
@@ -0,0 +1,32 @@
+% This module java_main_int defines a Mercury predicate java_main which acts as an
+% interface to the Java method java_main(), which is defined in JavaMain.java.
+
+% This source file is hereby placed in the public domain.
+
+:- module java_main_int.
+
+:- interface.
+:- import_module io.
+
+% Since the java_main() function has side effects, we declare the corresponding
+% Mercury predicate as one that takes an io__state pair.  If we didn't do
+% this, the Mercury compiler might optimize away calls to it!
+
+:- pred java_main(io::di, io::uo) is det.
+
+:- implementation.
+
+	% Import the Java class containing the method java_main.
+	% As usual for Java, this is not necessary; you may also
+	% fully qualify the method at the call site.
+:- pragma foreign_decl("Java", "import my_package.JavaMain;").
+
+	% Define the Mercury predicate java_main to call the Java method
+	% java_main.
+:- pragma foreign_proc("Java",
+	java_main(IO0::di, IO::uo),
+	[may_call_mercury, promise_pure],
+"
+	JavaMain.java_main();
+	IO = IO0;
+").
diff --git a/samples/java_interface/java_calls_mercury/mercury_lib.m b/samples/java_interface/java_calls_mercury/mercury_lib.m
new file mode 100644
index 0000000..a0d2edc
--- /dev/null
+++ b/samples/java_interface/java_calls_mercury/mercury_lib.m
@@ -0,0 +1,72 @@
+% This source file is hereby placed in the public domain.  -fjh (the author).
+
+%-----------------------------------------------------------------------------%
+:- module mercury_lib.
+:- interface.
+
+	% A Mercury predicate with multiple modes.
+	% 
+:- pred foo(int).
+:- mode foo(in) is semidet.
+:- mode foo(out) is multi.
+
+	% A Mercury function with multiple modes.
+	%
+:- func bar(int) = int.
+:- mode bar(in) = out is det.
+:- mode bar(out) = in is det.
+:- mode bar(in) = in is semidet.
+
+	% A semidet (i.e. partial) Mercury function.
+:- func baz(int) = int.
+:- mode baz(in) = out is semidet.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module int.
+:- import_module list.
+:- import_module solutions.
+
+% well, this is just a silly example...
+foo(42).
+foo(53).
+foo(197).
+
+bar(X) = X + 1.
+
+baz(1) = 9.
+baz(2) = 16.
+baz(3) = 27.
+
+%-----------------------------------------------------------------------------%
+
+% The following code provides provides access to the Mercury predicate foo
+% from Java code.
+
+:- pragma foreign_export("Java", foo(in), "foo_test").
+
+:- pragma foreign_export("Java", bar(in) = out, "bar").
+:- pragma foreign_export("Java", bar(in) = in,  "bar_test").
+:- pragma foreign_export("Java", bar(out) = in, "bar_inverse").
+
+:- pragma foreign_export("Java", baz(in) = out, "baz").
+
+	% The nondet mode of `foo' cannot be exported directly with
+	% the current Mercury/C interface.  To get all solutions,
+	% must define a predicate which returns all the solutions of foo,
+	% and export it to C.  We give it the name foo_list() in C.
+:- pred all_foos(list(int)::out) is det.
+:- pragma foreign_export("Java", all_foos(out), "foo_list").
+all_foos(L) :- solutions((pred(X::out) is multi :- foo(X)), L).
+
+	% If we just want one solution, and don't care which one, then
+	% we can export a `cc_multi' (committed-choice nondeterminism)
+	% version of `foo'. We give it the name one_foo().
+:- pred cc_foo(int::out) is cc_multi.
+:- pragma foreign_export("Java", cc_foo(out), "one_foo").
+cc_foo(X) :- foo(X).
+
+%-----------------------------------------------------------------------------%
diff --git a/samples/java_interface/java_calls_mercury/mercury_main.m b/samples/java_interface/java_calls_mercury/mercury_main.m
new file mode 100644
index 0000000..f0200b6
--- /dev/null
+++ b/samples/java_interface/java_calls_mercury/mercury_main.m
@@ -0,0 +1,24 @@
+% This source file is hereby placed in the public domain.  -fjh (the author).
+
+:- module mercury_main.
+:- interface.
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+	% Nothing from mercury_lib is used in mercury_main.
+	% The import is needed to make sure mmake includes
+	% mercury_lib in the executable.
+:- import_module mercury_lib.
+
+% import the module which defines the Mercury interface to the
+% Java method java_main().
+:- import_module java_main_int.
+
+% main just invokes java_main
+main(!IO) :-
+	io.write_string("In Mercury main, about to call java_main...\n", !IO),
+	java_main(!IO),
+	io.write_string("Back in Mercury main.\n", !IO).
diff --git a/samples/java_interface/mercury_calls_java/JavaMain.java b/samples/java_interface/mercury_calls_java/JavaMain.java
new file mode 100644
index 0000000..1877ef2
--- /dev/null
+++ b/samples/java_interface/mercury_calls_java/JavaMain.java
@@ -0,0 +1,7 @@
+package my_package;
+
+public class JavaMain {
+	public static void java_main() {
+		System.out.println("In java_main().");
+	}
+}
diff --git a/samples/java_interface/mercury_calls_java/Makefile b/samples/java_interface/mercury_calls_java/Makefile
new file mode 100644
index 0000000..dc9c988
--- /dev/null
+++ b/samples/java_interface/mercury_calls_java/Makefile
@@ -0,0 +1,17 @@
+#-----------------------------------------------------------------------------#
+# This source file is hereby placed in the public domain.
+#-----------------------------------------------------------------------------#
+
+.PHONY: all
+all: mercury_main
+
+mercury_main: mercury_main.m my_package/JavaMain.class
+	mmc --java --make mercury_main --java-classpath .
+
+my_package/JavaMain.class: JavaMain.java
+	javac JavaMain.java -d .
+
+.PHONY: clean
+clean:
+	$(RM) mercury_main *.err
+	$(RM) -r Mercury my_package
diff --git a/samples/java_interface/mercury_calls_java/java_main_int.m b/samples/java_interface/mercury_calls_java/java_main_int.m
new file mode 100644
index 0000000..b16b6ce
--- /dev/null
+++ b/samples/java_interface/mercury_calls_java/java_main_int.m
@@ -0,0 +1,31 @@
+% This module java_main_int defines a Mercury predicate java_main which acts as an
+% interface to the Java method java_main(), which is defined in JavaMain.java.
+
+% This source file is hereby placed in the public domain.
+
+:- module java_main_int.
+:- interface.
+:- import_module io.
+
+% Since the java_main() function has side effects, we declare the corresponding
+% Mercury predicate as one that takes an io__state pair.  If we didn't do
+% this, the Mercury compiler might optimize away calls to it!
+
+:- pred java_main(io::di, io::uo) is det.
+
+:- implementation.
+
+	% Import the Java class containing the method java_main.
+	% As usual for Java, this is not necessary; you may also
+	% fully qualify the method at the call site.
+:- pragma foreign_decl("Java", "import my_package.JavaMain;").
+
+	% Define the Mercury predicate java_main to call the Java function
+	% java_main.
+:- pragma foreign_proc("Java",
+	java_main(IO0::di, IO::uo),
+	[promise_pure, will_not_call_mercury],
+"
+	JavaMain.java_main();
+	IO = IO0;
+").
diff --git a/samples/java_interface/mercury_calls_java/mercury_main.m b/samples/java_interface/mercury_calls_java/mercury_main.m
new file mode 100644
index 0000000..7299902
--- /dev/null
+++ b/samples/java_interface/mercury_calls_java/mercury_main.m
@@ -0,0 +1,19 @@
+% This source file is hereby placed in the public domain.
+
+:- module mercury_main.
+:- interface.
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+% import the module which defines the Mercury interface to the
+% Java method JavaMain.java_main().
+:- import_module java_main_int.
+
+% main just invokes java_main
+main(!IO) :-
+	io.write_string("In Mercury main, about to call java_main...\n", !IO),
+	java_main(!IO),
+	io.write_string("Back in Mercury main.\n", !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