mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-29 00:04:55 +00:00
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.
61 lines
1.6 KiB
Mathematica
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
|