mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-24 22:04:13 +00:00
Estimated hours taken: 20 Add support for `pragma import', which is a simplified form of `pragma c_code'. With `pragma import', the user specifies only the C function name, rather than a C code fragment, and the Mercury compiler handles the argument-passing automatically. TODO - add documentation to doc/reference_manual.texi. WISHLIST - change `pragma import' and `pragma export' to take an additional parameter indicating the language (e.g. C, Prolog, Ada, Fortran, etc.) and/or calling convention compiler/prog_data.m: Add `pragma import' to the parse tree data structure. compiler/prog_io_pragma.m: Add code to parse `pragma import' declarations. compiler/mercury_to_mercury.m: Add code to pretty-print `pragma import' declarations. compiler/module_qual.m: Add code to module-qualify `pragma import' declarations. compiler/make_hlds.m: Add code to process `pragma import' declarations, by converting them to clauses with HLDS `c_code' instructions. compiler/export.m: Declare `export__exclude_argument_type' in the interface, for use by the code for handling `pragma import' in make_hlds.m. Change the documentation to say that this procedure is used for both exported and imported procedures. compiler/notes/compiler_design.html: Document how the compiler handles `pragma import' declarations. tests/hard_coded/Mmakefile: tests/hard_coded/pragma_import.m: tests/hard_coded/pragma_import.exp: Add some test cases for `pragma import'.
89 lines
2.1 KiB
Mathematica
89 lines
2.1 KiB
Mathematica
:- module foo.
|
|
:- interface.
|
|
:- import_module io.
|
|
|
|
:- pred main(io__state::di, io__state::uo) is det.
|
|
|
|
:- implementation.
|
|
|
|
main -->
|
|
foo(100, X, 200.0, Y, "Foo", S),
|
|
print("X = "), print(X), nl,
|
|
print("Y = "), print(Y), nl,
|
|
print("S = "), print(S), nl,
|
|
{ bar(X, X1) = X2 },
|
|
print("X1 = "), print(X1), nl,
|
|
print("X2 = "), print(X2), nl,
|
|
{ bar2(X, XX1) = XX2 },
|
|
print("XX1 = "), print(XX1), nl,
|
|
print("XX2 = "), print(XX2), nl,
|
|
( { baz(300, Y1) = Y2 } ->
|
|
print("Y1 = "), print(Y1), nl,
|
|
print("Y2 = "), print(Y2), nl
|
|
;
|
|
print("baz failed unexpectedly"), nl
|
|
),
|
|
( { baz(-300, _) = _ } ->
|
|
print("baz succeeded unexpectedly"), nl
|
|
;
|
|
print("baz failed, as expected"), nl
|
|
),
|
|
( { quux(400, Z) } ->
|
|
print("Z = "), print(Z), nl
|
|
;
|
|
print("quux failed unexpectedly"), nl
|
|
),
|
|
( { quux(-400, _) } ->
|
|
print("quux succeeded unexpectedly"), nl
|
|
;
|
|
print("quux failed, as expected"), nl
|
|
).
|
|
|
|
:- pred foo(int::in, int::out, float::in, float::out, string::in, string::out,
|
|
io__state::di, io__state::uo) is det.
|
|
:- func bar(int::in, int::out) = (int::out) is det.
|
|
:- func bar2(int::in, int::out) = (int::out) is det.
|
|
:- func baz(int::in, int::out) = (int::out) is semidet.
|
|
:- pred quux(int::in, int::out) is semidet.
|
|
|
|
:- pragma import(foo(in, out, in, out, in, out, di, uo), "cfoo").
|
|
:- pragma import(bar(in, out) = out, will_not_call_mercury, "cbar").
|
|
:- pragma export(bar(in, out) = out, "mbar").
|
|
:- pragma import(bar2(in, out) = out, may_call_mercury, "mbar").
|
|
:- pragma import(baz(in, out) = out, "cbaz").
|
|
:- pragma import(quux(in, out), may_call_mercury, "cquux").
|
|
|
|
:- pragma c_header_code("
|
|
typedef Integer Int;
|
|
void cfoo(Int, Int *, Float, Float *, String, String *);
|
|
Int cbar(Int, Int *);
|
|
bool cbaz(Int, Int *, Int *);
|
|
bool cquux(Int, Int *);
|
|
").
|
|
|
|
:- pragma c_code("
|
|
|
|
void cfoo(Int a1, Int *a2, Float a3, Float *a4, String a5, String *a6) {
|
|
*a2 = a1 + 1;
|
|
*a4 = a3 + 1.0;
|
|
*a6 = a5;
|
|
}
|
|
|
|
Int cbar(Int a1, Int *a2) {
|
|
*a2 = 1;
|
|
return a1 + *a2;
|
|
}
|
|
|
|
bool cbaz(Int a1, Int *a2, Int *a3) {
|
|
*a2 = a1 + 1;
|
|
*a3 = a1 + 2;
|
|
return a1 + *a2 + *a3 > 0;
|
|
}
|
|
|
|
bool cquux(Int a1, Int *a2) {
|
|
*a2 = a1 + 1;
|
|
return a1 + *a2 > 0;
|
|
}
|
|
|
|
").
|