mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 17:33:38 +00:00
Add examples of Mercury/Java integration.
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.
This commit is contained in:
1
samples/java_interface/.nocopyright
Normal file
1
samples/java_interface/.nocopyright
Normal file
@@ -0,0 +1 @@
|
||||
README
|
||||
10
samples/java_interface/README
Normal file
10
samples/java_interface/README
Normal file
@@ -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.
|
||||
|
||||
88
samples/java_interface/java_calls_mercury/JavaMain.java
Normal file
88
samples/java_interface/java_calls_mercury/JavaMain.java
Normal file
@@ -0,0 +1,88 @@
|
||||
// This source file is hereby placed in the public domain.
|
||||
|
||||
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("]");
|
||||
}
|
||||
}
|
||||
}
|
||||
25
samples/java_interface/java_calls_mercury/Makefile
Normal file
25
samples/java_interface/java_calls_mercury/Makefile
Normal file
@@ -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
|
||||
32
samples/java_interface/java_calls_mercury/java_main_int.m
Normal file
32
samples/java_interface/java_calls_mercury/java_main_int.m
Normal file
@@ -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;
|
||||
").
|
||||
72
samples/java_interface/java_calls_mercury/mercury_lib.m
Normal file
72
samples/java_interface/java_calls_mercury/mercury_lib.m
Normal file
@@ -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).
|
||||
|
||||
%-----------------------------------------------------------------------------%
|
||||
24
samples/java_interface/java_calls_mercury/mercury_main.m
Normal file
24
samples/java_interface/java_calls_mercury/mercury_main.m
Normal file
@@ -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).
|
||||
9
samples/java_interface/mercury_calls_java/JavaMain.java
Normal file
9
samples/java_interface/mercury_calls_java/JavaMain.java
Normal file
@@ -0,0 +1,9 @@
|
||||
// This source file is hereby placed in the public domain.
|
||||
|
||||
package my_package;
|
||||
|
||||
public class JavaMain {
|
||||
public static void java_main() {
|
||||
System.out.println("In java_main().");
|
||||
}
|
||||
}
|
||||
17
samples/java_interface/mercury_calls_java/Makefile
Normal file
17
samples/java_interface/mercury_calls_java/Makefile
Normal file
@@ -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
|
||||
31
samples/java_interface/mercury_calls_java/java_main_int.m
Normal file
31
samples/java_interface/mercury_calls_java/java_main_int.m
Normal file
@@ -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;
|
||||
").
|
||||
19
samples/java_interface/mercury_calls_java/mercury_main.m
Normal file
19
samples/java_interface/mercury_calls_java/mercury_main.m
Normal file
@@ -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).
|
||||
Reference in New Issue
Block a user