Files
mercury/tests/hard_coded/pragma_import.m
Fergus Henderson 64009ded0b Add support for `pragma import', which is a simplified form of
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'.
1998-01-09 11:56:29 +00:00

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;
}
").