Files
mercury/tests/hard_coded/foreign_import_module.m
Zoltan Somogyi 36dc154ceb Fix two failing C# tests.
tests/general/read_dir_regression.m:
    Fix the code that canonicalized error messages for C#.
    It probably broke when we added a "can't open input file:" prefix
    to the error message, because the quote in "can't" confused it.

tests/hard_coded/foreign_import_module.m:
tests/hard_coded/foreign_import_module_helper_1.m:
    Fix several things to make this test case work.

    - Add a foreign_import_module pragma for the helper module.
      There was one originally, but it was marked as being for "il",
      and the pragma was deleted, not replaced, when the IL backend
      was deleted.

    - Refer to the foo function and the foo2 predicate that
      the main module imports from the helper module by their
      actual names in the compiler-generated C# code.
      (The old names the test used were probably IL-specific,
      though I am not sure.)

    - Invoke the foo function as a function; we used to invoke it as
      a predicate. (The C# calling convention may have changed
      in the meantime, and in fact, the original convention could have
      been for Managed C++ instead.)

    - Make the predicate exported by the C# foreign_code in the
      helper module public.

    - Initialize a variable passed by reference in order to avoid
      an error message from the C# compiler.

    Add an XXX about the code of foreign_import_module.m containing
    two just-about-identical halves.

tests/EXPECT_FAIL_TESTS.csharp:
    Stop expecting the foreign_import_module test case to fail.

tests/hard_coded/dst_test.m:
    Improve programming style, and fix some typos.
2025-10-09 01:34:13 +11:00

94 lines
2.4 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
:- module foreign_import_module.
:- interface.
:- import_module int.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- pred bar(int::in, int::out) is det.
:- implementation.
main(!IO) :-
bar(41, X),
io.write_line(X, !IO),
bar2(41, Y),
io.write_line(Y, !IO).
:- pragma foreign_import_module(c, foreign_import_module_helper_1).
:- pragma foreign_import_module(csharp, foreign_import_module_helper_1).
:- pragma foreign_import_module(java, foreign_import_module_helper_1).
:- pragma foreign_proc("C",
bar(X::in, Y::out),
[may_call_mercury, promise_pure],
"
foo(X, &Y);
").
:- pragma foreign_proc("C#",
bar(X::in, Y::out),
[may_call_mercury, promise_pure],
"
int Y1 = 0, Y2 = 0;
Y1 = foreign_import_module_helper_1.foo(X);
foreign_import_module_helper_1.foo2(X, ref Y2);
if (Y1 == Y2) {
Y = Y1;
} else {
throw new System.Exception(""Y1 != Y2"");
}
").
:- pragma foreign_proc("Java",
bar(X::in, Y::out),
[may_call_mercury, promise_pure],
"
Y = foreign_import_module_helper_1.foo(X);
").
% XXX The definition of "bar2" is identical to just plain "bar";
% the only difference between them is that only "bar" is exported.
% (There used to be more differences, but they seemed to deal with
% peculiarities of the IL backend, which is not an issue anymore.)
% XXX *If* this test has any purpose beyond testing the foreign_import_module
% pragma (which is NOT clear), and *if* the exported/not exported distinction
% has any bearing on this extra purpose, then both should be documented.
% Otherwise, I see no reason not to delete "bar2".
:- pred bar2(int::in, int::out) is det.
:- pragma foreign_proc("C",
bar2(X::in, Y::out),
[may_call_mercury, promise_pure],
"
foo(X, &Y);
").
:- pragma foreign_proc("C#",
bar2(X::in, Y::out),
[may_call_mercury, promise_pure],
"
int Y1 = 0, Y2 = 0;
Y1 = foreign_import_module_helper_1.foo(X);
foreign_import_module_helper_1.foo2(X, ref Y2);
if (Y1 == Y2) {
Y = Y1;
} else {
throw new System.Exception(""Y1 != Y2"");
}
").
:- pragma foreign_proc("Java",
bar2(X::in, Y::out),
[may_call_mercury, promise_pure],
"
Y = foreign_import_module_helper_1.foo(X);
").