mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 17:33:38 +00:00
201 lines
5.3 KiB
Mathematica
201 lines
5.3 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 1994-2007, 2010 The University of Melbourne.
|
|
% Copyright (C) 2013-2016, 2018, 2025 The Mercury team.
|
|
% This file is distributed under the terms specified in COPYING.LIB.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% File: mutvar.m.
|
|
% Stability: high.
|
|
%
|
|
% This module is used in the implementation of all-solutions predicates
|
|
% (solutions.m) and stores (store.m). This module is a private part of the
|
|
% Mercury implementation; user modules should never explicitly import this
|
|
% module. The interface for this module does not get included in the Mercury
|
|
% library reference manual.
|
|
%
|
|
% XXX When we move to use submodules in the standard library, we should
|
|
% make this module a private submodule.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module mutvar.
|
|
:- interface.
|
|
|
|
% A non-backtrackably destructively modifiable reference type.
|
|
%
|
|
:- type mutvar(T).
|
|
|
|
% Create a new mutvar given a term for it to reference.
|
|
%
|
|
:- impure pred new_mutvar(T, mutvar(T)).
|
|
:- mode new_mutvar(in, out) is det.
|
|
:- mode new_mutvar(di, uo) is det.
|
|
|
|
% Create a new mutvar with undefined initial value.
|
|
%
|
|
:- impure pred new_mutvar0(mutvar(T)).
|
|
:- mode new_mutvar0(uo) is det.
|
|
|
|
% Get the value currently referred to by a reference.
|
|
%
|
|
:- impure pred get_mutvar(mutvar(T), T).
|
|
:- mode get_mutvar(in, uo) is det. % XXX this is a work-around
|
|
/*
|
|
XXX `ui' modes don't work yet
|
|
:- mode get_mutvar(in, uo) is det.
|
|
:- mode get_mutvar(ui, uo) is det. % unsafe, but we use it safely
|
|
*/
|
|
|
|
% Destructively modify a reference to refer to a new object.
|
|
%
|
|
:- impure pred set_mutvar(mutvar(T), T).
|
|
:- mode set_mutvar(in, in) is det.
|
|
/*
|
|
XXX `ui' modes don't work yet
|
|
:- pred set_mutvar(ui, di) is det.
|
|
*/
|
|
|
|
% Destructively clear a reference to avoid retaining the value.
|
|
%
|
|
:- impure pred clear_mutvar(mutvar(T)).
|
|
:- mode clear_mutvar(in) is det.
|
|
/*
|
|
XXX `ui' modes don't work yet
|
|
:- pred clear_mutvar(ui) is det.
|
|
*/
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- pragma inline(pred(new_mutvar/2)).
|
|
:- pragma inline(pred(new_mutvar0/1)).
|
|
:- pragma inline(pred(get_mutvar/2)).
|
|
:- pragma inline(pred(set_mutvar/2)).
|
|
:- pragma inline(pred(clear_mutvar/1)).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
new_mutvar(X, Ref) :-
|
|
impure new_mutvar0(Ref0),
|
|
impure set_mutvar(Ref0, X),
|
|
Ref = unsafe_promise_unique(Ref0).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pragma foreign_code("Java",
|
|
"
|
|
public static class Mutvar implements java.io.Serializable {
|
|
public Object object;
|
|
|
|
public Mutvar() {
|
|
}
|
|
|
|
public Mutvar(Object o) {
|
|
object = o;
|
|
}
|
|
}
|
|
").
|
|
|
|
% This type is a builtin type whose operations are implemented in C.
|
|
%
|
|
:- type mutvar(T)
|
|
---> mutvar(private_builtin.ref(T)).
|
|
|
|
:- pragma foreign_type("C#", mutvar(T), "object[]").
|
|
:- pragma foreign_type("Java", mutvar(T), "mutvar.Mutvar").
|
|
|
|
%---------------------%
|
|
|
|
:- pragma foreign_proc("C",
|
|
new_mutvar0(Ref::uo),
|
|
[will_not_call_mercury, thread_safe],
|
|
"
|
|
MR_offset_incr_hp_msg(Ref, MR_SIZE_SLOT_SIZE, MR_SIZE_SLOT_SIZE + 1,
|
|
MR_ALLOC_ID, ""mutvar.mutvar/1"");
|
|
MR_define_size_slot(0, Ref, 1);
|
|
").
|
|
:- pragma foreign_proc("C#",
|
|
new_mutvar0(Ref::uo),
|
|
[will_not_call_mercury, thread_safe],
|
|
"
|
|
Ref = new object[1];
|
|
").
|
|
:- pragma foreign_proc("Java",
|
|
new_mutvar0(Ref::uo),
|
|
[will_not_call_mercury, thread_safe],
|
|
"
|
|
Ref = new mutvar.Mutvar();
|
|
").
|
|
|
|
%---------------------%
|
|
|
|
:- pragma foreign_proc("C",
|
|
get_mutvar(Ref::in, X::uo),
|
|
[will_not_call_mercury, thread_safe],
|
|
"
|
|
X = * (MR_Word *) Ref;
|
|
").
|
|
:- pragma foreign_proc("C#",
|
|
get_mutvar(Ref::in, X::uo),
|
|
[will_not_call_mercury, thread_safe],
|
|
"
|
|
X = Ref[0];
|
|
").
|
|
:- pragma foreign_proc("Java",
|
|
get_mutvar(Ref::in, X::uo),
|
|
[will_not_call_mercury, thread_safe],
|
|
"
|
|
X = Ref.object;
|
|
").
|
|
|
|
%---------------------%
|
|
|
|
:- pragma foreign_proc("C",
|
|
set_mutvar(Ref::in, X::in),
|
|
[will_not_call_mercury, thread_safe],
|
|
"
|
|
*(MR_Word *) Ref = X;
|
|
").
|
|
:- pragma foreign_proc("C#",
|
|
set_mutvar(Ref::in, X::in),
|
|
[will_not_call_mercury, thread_safe],
|
|
"
|
|
Ref[0] = X;
|
|
").
|
|
:- pragma foreign_proc("Java",
|
|
set_mutvar(Ref::in, X::in),
|
|
[will_not_call_mercury, thread_safe],
|
|
"
|
|
Ref.object = X;
|
|
").
|
|
|
|
%---------------------%
|
|
|
|
:- pragma foreign_proc("C",
|
|
clear_mutvar(Ref::in),
|
|
[will_not_call_mercury, thread_safe],
|
|
"
|
|
*(MR_Word *) Ref = 0;
|
|
").
|
|
:- pragma foreign_proc("C#",
|
|
clear_mutvar(Ref::in),
|
|
[will_not_call_mercury, thread_safe],
|
|
"
|
|
Ref[0] = null;
|
|
").
|
|
:- pragma foreign_proc("Java",
|
|
clear_mutvar(Ref::in),
|
|
[will_not_call_mercury, thread_safe],
|
|
"
|
|
Ref.object = null;
|
|
").
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module mutvar.
|
|
%---------------------------------------------------------------------------%
|