[mercury-users] Destructive map_replace
Julien Fischer
juliensf at csse.unimelb.edu.au
Mon Jan 5 22:13:10 AEDT 2009
On Mon, 5 Jan 2009, Michael Day wrote:
> Here is a C implementation of map_replace, changed to return a boolean result
> instead of a maybe, to simplify the C code and reduce allocation:
>
> :- pred replace_foo(string, list(string), bool).
> :- mode replace_foo(ui, uo, out) is det.
>
> replace_foo(X, Xs, Res) :-
> ( if X = "foo" then
> copy(["bar"], Xs),
> Res = yes
> else
> Xs = [],
> Res = no
> ).
>
> :- pred call_pred(pred(T, list(T), bool), T, list(T), bool).
> :- mode call_pred(in(pred(ui, uo, out) is det), ui, uo, out) is det.
>
> call_pred(Pred, X, Xs, Res) :- Pred(X, Xs, Res).
>
> :- pragma foreign_export(c, call_pred(in(pred(ui, uo, out) is det), ui, uo,
> out), "call_pred").
>
> :- pred map_replace(pred(T, list(T), bool), list(T), list(T)).
> :- mode map_replace(in(pred(ui, uo, out) is det), di, uo) is det.
>
> :- pragma foreign_proc(c,
> map_replace(Pred::in(pred(ui, uo, out) is det), Xs::di, Ys::uo),
> [will_not_call_mercury, thread_safe, promise_pure], "
> {
> MR_Word *AddrOfPrev;
>
> Ys = Xs;
> AddrOfPrev = &Ys;
>
> while (!MR_list_is_empty(Xs))
> {
> MR_Integer X = (MR_Integer) MR_list_head(Xs);
> MR_Word Xs0 = (MR_Word) MR_list_tail(Xs);
> MR_Word NewXs;
> MR_Word Res;
> MR_Word Fake;
>
> call_pred(Fake, Pred, X, &NewXs, &Res);
>
> if (Res != 0)
> {
> if (MR_list_is_empty(NewXs))
> {
> *AddrOfPrev = Xs0;
> }
> else
> {
> *AddrOfPrev = NewXs;
>
> do
> {
> Xs = NewXs;
> NewXs = (MR_Word) MR_list_tail(NewXs);
> }
> while (!MR_list_is_empty(NewXs));
>
> MR_list_tail(Xs) = Xs0;
>
> AddrOfPrev = &(MR_list_tail(Xs));
> }
> }
> else
> {
> AddrOfPrev = &(MR_list_tail(Xs));
> }
>
> Xs = Xs0;
> }
> }
> ").
>
> One question: I'm passing a fake type info to call_pred, and nothing seems to
> go wrong yet, but I feel guilty. Should I be?
When the first argument of call_pred needs to use RTTI you will be ;-)
Julien.
--------------------------------------------------------------------------
mercury-users mailing list
Post messages to: mercury-users at csse.unimelb.edu.au
Administrative Queries: owner-mercury-users at csse.unimelb.edu.au
Subscriptions: mercury-users-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the users
mailing list