Files
mercury/tests/invalid/multimode_addr_problems.m
Peter Wang f03995c7bd Support currying of multi-moded predicates or functions when the mode to curry
Estimated hours taken: 15
Branches: main

Support currying of multi-moded predicates or functions when the mode to curry
can be determined from the insts of the higher-order arguments. e.g.

	mymap(P, L0, L) :-
	    map(wrap(P), L0, L).

	:- pred wrap(...).
	:- mode wrap(in(pred(...) is det), ...) is det.
	:- mode wrap(in(pred(...) is cc_multi, ...) is cc_multi.
	...

compiler/post_typecheck.m:
	Don't abort immediately on taking the address of a multi-moded
	predicate.  Leave the proc_id as invalid_proc_id and handle that
	in polymorphism.m.

compiler/polymorphism.m:
	Convert higher order terms to lambda goals even if the proc_id is
	invalid (as above) moded by arbitrarily using the first mode.  Then
	polymorphism can proceed as usual.  Mark the goals with feature
	`feature_lambda_undetermined_mode', which tells mode checking to
	handle it.

	Add a predicate to fix up such lambda goals once mode checking does
	figure out which mode should be called.

compiler/modecheck_unify.m:
compiler/mode_errors.m:
	Handle goals with the `feature_lambda_undetermined_mode'.  Try to
	select a unique mode for the curried predicate then fix up the lambda
	goal.

compiler/hlds_goal.m:
compiler/saved_vars.m:
	Add `feature_lambda_undetermined_mode'.

compiler/goal_util.m:
	Add a predicate to return all the pred_ids called in a goal
	with the associated argument variables.

NEWS:
doc/reference_manual.texi:
	Document and announce the change.

tests/hard_coded/Mmakefile:
tests/hard_coded/multimode_addr.exp:
tests/hard_coded/multimode_addr.m:
tests/invalid/Mmakefile:
tests/invalid/multimode_addr_problems.err_exp:
tests/invalid/multimode_addr_problems.m:
	Add tests.
2008-04-28 00:50:56 +00:00

61 lines
1.6 KiB
Mathematica

% Test error messages with problems that arise trying to taking the
% address of multi-moded predicates.
:- module multimode_addr_problems.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is cc_multi.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module int.
:- import_module list.
%-----------------------------------------------------------------------------%
main(!IO) :-
% The compiler can't choose which mode of absolute to use.
Abs = absolute,
Abs(3, X),
io.write_int(X, !IO),
io.nl(!IO).
:- pred absolute(int, int).
:- mode absolute(in, out) is det.
:- mode absolute(out, in) is multi.
:- pragma promise_equivalent_clauses(absolute/2).
absolute(X::in, Y::out) :-
Y = ( X < 0 -> -X ; X).
absolute(X::out, Y::in) :-
( X = Y
; X = -Y
).
:- func my_foldl(func(L, A) = A, list(L), A) = A.
:- mode my_foldl(in(func(in, in) = out is det), in, in) = out is det.
my_foldl(F, L, A0) = A :-
% None of the modes of f2p are usable.
% XXX the error message without this explicit unification is confusing.
P = f2p(F),
list.foldl(P, L, A0, A).
:- pred f2p(func(L, A) = A, L, A, A).
:- mode f2p(in(func(in, di) = uo is det), in, di, uo) is det.
% :- mode f2p(in(func(in, in) = out is det), in, in, out) is det.
:- mode f2p(in(func(in, in) = out is semidet), in, in, out) is semidet.
f2p(F, L, A0, A) :-
F(L, A0) = A.
%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=8 sw=4 et wm=0 tw=0