[m-rev.] for review: pure mutable access predicates
Julien Fischer
juliensf at cs.mu.OZ.AU
Wed Oct 5 02:52:14 AEST 2005
For review by Ralph or Ian.
Estimated hours taken: 7
Branches: main
Add optional support for generating a pure interface to mutables. This is
done by adding a new mutable attribute, `pure'. If this attribute is
specified in the mutable declaration then in addition to the usual non-pure
access predicates, the compiler will also add a pair of access predicates that
take the IO state.
compiler/prog_data.m:
Add the `pure' mutable attribute.
Add the necessary access predicates for the mutable_var_attributes
structure.
compiler/prog_io.m:
Parse the `pure' attribute.
compiler/prog_mutable.m:
Shift some of the code for constructing items related to mutables to
this module from make_hlds_passes. This reduces unnecessary clutter in
the latter.
Remove the XXX comment about needing to mangle the names of the
globals - we now do that.
compiler/make_hlds_passes.m:
If a mutable has the `pure` attribute specified then create the pure
access predicates in addition to the non-pure ones.
compiler/modules.m:
If we are generating the pure access predicates then output the
declarations for these predicates in private interfaces.
compiler/type_util.m:
Replace the use of ':' as a module qualifier in some comments.
doc/reference_manual.texi:
Document the `pure' mutable attribute.
vim/syntax/mercury.vim:
Highlight various mutable attributes appropriately.
tests/hard_coded/Mmakefile:
tests/hard_coded/pure_mutable.m:
tests/hard_coded/pure_mutable.exp:
Test mutables with pure access predicates.
tests/hard_coded/ppc_bug.m:
Unrelated change: update the comments in this test case so
they describe what the cause of the bug and the fix were.
Julien.
Index: compiler/make_hlds_passes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds_passes.m,v
retrieving revision 1.14
diff -u -r1.14 make_hlds_passes.m
--- compiler/make_hlds_passes.m 4 Oct 2005 07:20:17 -0000 1.14
+++ compiler/make_hlds_passes.m 4 Oct 2005 16:43:50 -0000
@@ -450,18 +450,42 @@
add_item_decl_pass_1(Item, Context, !Status, !ModuleInfo, no, !IO) :-
% We add the initialise decl and the foreign_decl on the second pass and
% the foreign_proc clauses on the third pass.
- Item = mutable(Name, Type, _InitValue, Inst, _Attrs),
+ Item = mutable(Name, Type, _InitValue, Inst, Attrs),
!.Status = item_status(ImportStatus, _),
( status_defined_in_this_module(ImportStatus, yes) ->
module_info_get_name(!.ModuleInfo, ModuleName),
- GetPredDecl = prog_mutable.get_pred_decl(ModuleName, Name,
- Type, Inst),
- add_item_decl_pass_1(GetPredDecl, Context, !Status, !ModuleInfo, _,
- !IO),
- SetPredDecl = prog_mutable.set_pred_decl(ModuleName, Name,
- Type, Inst),
- add_item_decl_pass_1(SetPredDecl, Context, !Status, !ModuleInfo, _,
- !IO),
+ %
+ % Create the non-pure access predicates. These are always
+ % created, even if the `pure' attribute has been specified.
+ %
+ NonPureGetPredDecl = prog_mutable.nonpure_get_pred_decl(ModuleName,
+ Name, Type, Inst),
+ add_item_decl_pass_1(NonPureGetPredDecl, Context, !Status, !ModuleInfo,
+ _, !IO),
+ NonPureSetPredDecl = prog_mutable.nonpure_set_pred_decl(ModuleName,
+ Name, Type, Inst),
+ add_item_decl_pass_1(NonPureSetPredDecl, Context, !Status, !ModuleInfo,
+ _, !IO),
+ %
+ % If requested, create the pure access predicates as well.
+ %
+ CreatePureInterface = mutable_var_pure_interface(Attrs),
+ (
+ CreatePureInterface = yes,
+ PureGetPredDecl = prog_mutable.pure_get_pred_decl(ModuleName,
+ Name, Type, Inst),
+ add_item_decl_pass_1(PureGetPredDecl, Context, !Status,
+ !ModuleInfo, _, !IO),
+ PureSetPredDecl = prog_mutable.pure_set_pred_decl(ModuleName,
+ Name, Type, Inst),
+ add_item_decl_pass_1(PureSetPredDecl, Context, !Status,
+ !ModuleInfo, _, !IO)
+ ;
+ CreatePureInterface = no
+ ),
+ %
+ % Create the initialisation predicate.
+ %
InitPredDecl = prog_mutable.init_pred_decl(ModuleName, Name),
add_item_decl_pass_1(InitPredDecl, Context, !Status, !ModuleInfo, _,
!IO)
@@ -620,12 +644,9 @@
% XXX We don't currently support languages other than C.
%
module_info_get_name(!.ModuleInfo, ModuleName),
- ForeignDecl = pragma(compiler(mutable_decl),
- foreign_decl(c, foreign_decl_is_exported,
- "extern MR_Word " ++ TargetMutableName ++ ";")),
+ ForeignDecl = get_global_foreign_decl(TargetMutableName),
add_item_decl_pass_2(ForeignDecl, Context, !Status, !ModuleInfo, !IO),
- ForeignCode = pragma(compiler(mutable_decl),
- foreign_code(c, "MR_Word " ++ TargetMutableName ++ ";")),
+ ForeignCode = get_global_foreign_defn(TargetMutableName),
add_item_decl_pass_2(ForeignCode, Context, !Status, !ModuleInfo, !IO)
;
true
@@ -1099,7 +1120,7 @@
Item = mutable(Name, _Type, InitTerm, Inst, MutAttrs),
( status_defined_in_this_module(!.Status, yes) ->
module_info_get_name(!.ModuleInfo, ModuleName),
- varset__new_named_var(varset__init, "X", X, VarSet),
+ varset__new_named_var(varset.init, "X", X, VarSet0),
Attrs0 = default_attributes(c),
set_may_call_mercury(will_not_call_mercury, Attrs0, Attrs1),
( mutable_var_thread_safe(MutAttrs) = thread_safe ->
@@ -1107,6 +1128,10 @@
;
Attrs = Attrs1
),
+ %
+ % Add the `:- initialise' declaration and clause for the
+ % initialise predicate.
+ %
add_item_clause(initialise(compiler(mutable_decl),
mutable_init_pred_sym_name(ModuleName, Name), 0 /* Arity */),
!Status, Context, !ModuleInfo, !QualInfo, !IO),
@@ -1127,12 +1152,12 @@
ModuleName, Name, ForeignNames, TargetMutableName, !IO)
),
set_purity((semipure), Attrs, GetAttrs),
- GetClause = pragma(compiler(mutable_decl), foreign_proc(GetAttrs,
+ NonPureGetClause = pragma(compiler(mutable_decl), foreign_proc(GetAttrs,
mutable_get_pred_sym_name(ModuleName, Name), predicate,
- [pragma_var(X, "X", out_mode(Inst))], VarSet,
+ [pragma_var(X, "X", out_mode(Inst))], VarSet0,
ordinary("X = " ++ TargetMutableName ++ ";", yes(Context)))),
- add_item_clause(GetClause, !Status, Context, !ModuleInfo, !QualInfo,
- !IO),
+ add_item_clause(NonPureGetClause, !Status, Context, !ModuleInfo,
+ !QualInfo, !IO),
TrailMutableUpdates = mutable_var_trailed(MutAttrs),
(
TrailMutableUpdates = untrailed,
@@ -1160,13 +1185,63 @@
TrailCode = ""
)
),
- SetClause = pragma(compiler(mutable_decl), foreign_proc(Attrs,
+ NonPureSetClause = pragma(compiler(mutable_decl), foreign_proc(Attrs,
mutable_set_pred_sym_name(ModuleName, Name), predicate,
- [pragma_var(X, "X", in_mode(Inst))], VarSet,
+ [pragma_var(X, "X", in_mode(Inst))], VarSet0,
ordinary(TrailCode ++ TargetMutableName ++ " = X;",
yes(Context)))),
- add_item_clause(SetClause, !Status, Context, !ModuleInfo, !QualInfo,
- !IO)
+ add_item_clause(NonPureSetClause, !Status, Context, !ModuleInfo, !QualInfo,
+ !IO),
+ %
+ % Create pure access predicates for the mutable if requested.
+ %
+ % XXX We don't define these directly in terms of the non-pure
+ % access predicates because I/O tabling doesn't currently work
+ % for impure/semipure predicates. At the moment we just generate
+ % another pair of foreign_procs.
+ %
+ ( mutable_var_pure_interface(MutAttrs) = yes ->
+ set_tabled_for_io(tabled_for_io, Attrs0, PureIntAttrs0),
+ set_purity(pure, PureIntAttrs0, PureIntAttrs),
+ varset.new_named_var(VarSet0, "IO0", IO0, VarSet1),
+ varset.new_named_var(VarSet1, "IO", IO, VarSet),
+ PureSetClause = pragma(compiler(mutable_decl),
+ foreign_proc(PureIntAttrs,
+ mutable_set_pred_sym_name(ModuleName, Name), predicate,
+ [
+ pragma_var(X, "X", in_mode(Inst)),
+ pragma_var(IO0, "IO0", di_mode),
+ pragma_var(IO, "IO", uo_mode)
+ ], VarSet,
+ ordinary(
+ TargetMutableName ++ " = X; " ++
+ "IO = IO0;",
+ yes(Context)
+ )
+ )
+ ),
+ add_item_clause(PureSetClause, !Status, Context, !ModuleInfo,
+ !QualInfo, !IO),
+ PureGetClause = pragma(compiler(mutable_decl),
+ foreign_proc(PureIntAttrs,
+ mutable_get_pred_sym_name(ModuleName, Name), predicate,
+ [
+ pragma_var(X, "X", out_mode(Inst)),
+ pragma_var(IO0, "IO0", di_mode),
+ pragma_var(IO, "IO", uo_mode)
+ ], VarSet,
+ ordinary(
+ "X = " ++ TargetMutableName ++ ";" ++
+ "IO = IO0;",
+ yes(Context)
+ )
+ )
+ ),
+ add_item_clause(PureGetClause, !Status, Context, !ModuleInfo,
+ !QualInfo, !IO)
+ ;
+ true
+ )
;
true
).
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.348
diff -u -r1.348 modules.m
--- compiler/modules.m 4 Oct 2005 07:20:18 -0000 1.348
+++ compiler/modules.m 4 Oct 2005 07:20:36 -0000
@@ -1331,13 +1331,27 @@
item_and_context::in, item_list::in, item_list::out) is det.
handle_mutable_in_private_interface(ModuleName, Item - Context, !Items) :-
- ( Item = mutable(MutableName, Type, _Value, Inst, _Attrs) ->
- GetPredDecl = prog_mutable.get_pred_decl(ModuleName, MutableName,
- Type, Inst),
- list.cons(GetPredDecl - Context, !Items),
- SetPredDecl = prog_mutable.set_pred_decl(ModuleName, MutableName,
- Type, Inst),
- list.cons(SetPredDecl - Context, !Items)
+ ( Item = mutable(MutableName, Type, _Value, Inst, Attrs) ->
+ NonPureGetPredDecl =
+ prog_mutable.nonpure_get_pred_decl(ModuleName, MutableName,
+ Type, Inst),
+ list.cons(NonPureGetPredDecl - Context, !Items),
+ NonPureSetPredDecl =
+ prog_mutable.nonpure_set_pred_decl(ModuleName, MutableName,
+ Type, Inst),
+ list.cons(NonPureSetPredDecl - Context, !Items),
+ ( mutable_var_pure_interface(Attrs) = yes ->
+ PureGetPredDecl =
+ prog_mutable.pure_get_pred_decl(ModuleName, MutableName,
+ Type, Inst),
+ list.cons(PureGetPredDecl - Context, !Items),
+ PureSetPredDecl =
+ prog_mutable.pure_set_pred_decl(ModuleName, MutableName,
+ Type, Inst),
+ list.cons(PureSetPredDecl - Context, !Items)
+ ;
+ true
+ )
;
list.cons(Item - Context, !Items)
).
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.140
diff -u -r1.140 prog_data.m
--- compiler/prog_data.m 4 Oct 2005 07:20:19 -0000 1.140
+++ compiler/prog_data.m 4 Oct 2005 15:07:12 -0000
@@ -220,14 +220,31 @@
% used for items that should be ignored (for the
% purposes of backwards compatibility etc)
+ % Attributes that a mutable can have (part of the `:- mutable'
+ % declaration).
+ %
+:- type mutable_attr
+ ---> untrailed % Updates are not trailed (default).
+
+ ; trailed % Updates are trailed.
+
+ ; thread_safe % Access is considered thread safe.
+
+ ; not_thread_safe % Access is considered not thread safe
+ % (default).
+ %
+ ; pure. % Generate a pure version of the
+ % mutable access predicates that take
+ % the IO state.
+
% Indicates the type of information the compiler should get from the
% declaration's clause.
%
:- type promise_type
% promise ex declarations
- ---> exclusive % each disjunct is mutually exclusive
- ; exhaustive % disjunction cannot fail
- ; exclusive_exhaustive % both of the above
+ ---> exclusive % Each disjunct is mutually exclusive.
+ ; exhaustive % Disjunction cannot fail.
+ ; exclusive_exhaustive % Both of the above.
% assertions
; true. % promise goal is true
@@ -310,6 +327,7 @@
:- func mutable_var_trailed(mutable_var_attributes) = trailed.
:- func mutable_var_maybe_foreign_names(mutable_var_attributes)
= maybe(list(foreign_name)).
+:- func mutable_var_pure_interface(mutable_var_attributes) = bool.
:- pred set_mutable_var_thread_safe(thread_safe::in,
mutable_var_attributes::in, mutable_var_attributes::out) is det.
@@ -320,6 +338,9 @@
:- pred set_mutable_add_foreign_name(foreign_name::in,
mutable_var_attributes::in, mutable_var_attributes::out) is det.
+:- pred set_mutable_var_pure_interface(bool::in,
+ mutable_var_attributes::in, mutable_var_attributes::out) is det.
+
%-----------------------------------------------------------------------------%
%
% Pragmas
@@ -2091,17 +2112,19 @@
%
:- type mutable_var_attributes
---> mutable_var_attributes(
- mutable_trailed :: trailed,
- mutable_thread_safe :: thread_safe,
- mutable_foreign_names :: maybe(list(foreign_name))
+ mutable_trailed :: trailed,
+ mutable_thread_safe :: thread_safe,
+ mutable_foreign_names :: maybe(list(foreign_name)),
+ mutable_pure_interface :: bool
).
default_mutable_attributes =
- mutable_var_attributes(trailed, not_thread_safe, no).
+ mutable_var_attributes(trailed, not_thread_safe, no, no).
mutable_var_thread_safe(MVarAttrs) = MVarAttrs ^ mutable_thread_safe.
mutable_var_trailed(MVarAttrs) = MVarAttrs ^ mutable_trailed.
mutable_var_maybe_foreign_names(MVarAttrs) = MVarAttrs ^ mutable_foreign_names.
+mutable_var_pure_interface(MVarAttrs) = MVarAttrs ^ mutable_pure_interface.
set_mutable_var_thread_safe(ThreadSafe, !Attributes) :-
!:Attributes = !.Attributes ^ mutable_thread_safe := ThreadSafe.
@@ -2119,6 +2142,8 @@
),
!:Attributes =
!.Attributes ^ mutable_foreign_names := MaybeForeignNames.
+set_mutable_var_pure_interface(CreatePureInterface, !Attributes) :-
+ !:Attributes = !.Attributes ^ mutable_pure_interface := CreatePureInterface.
%-----------------------------------------------------------------------------%
Index: compiler/prog_io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io.m,v
retrieving revision 1.253
diff -u -r1.253 prog_io.m
--- compiler/prog_io.m 4 Oct 2005 07:20:19 -0000 1.253
+++ compiler/prog_io.m 4 Oct 2005 07:20:36 -0000
@@ -1983,7 +1983,8 @@
:- type collected_mutable_attribute
---> trailed(trailed)
; thread_safe(thread_safe)
- ; foreign_name(foreign_name).
+ ; foreign_name(foreign_name)
+ ; pure(bool).
:- pred parse_mutable_attrs(term::in,
maybe1(mutable_var_attributes)::out) is det.
@@ -2032,6 +2033,8 @@
set_mutable_var_trailed(Trailed, !Attributes).
process_mutable_attribute(foreign_name(ForeignName), !Attributes) :-
set_mutable_add_foreign_name(ForeignName, !Attributes).
+process_mutable_attribute(pure(CreatePureInterface), !Attributes) :-
+ set_mutable_var_pure_interface(CreatePureInterface, !Attributes).
:- pred parse_mutable_attr(term::in,
maybe1(collected_mutable_attribute)::out) is det.
@@ -2045,8 +2048,11 @@
;
String = "trailed",
MutAttr = trailed(trailed)
+ ;
+ String = "pure",
+ MutAttr = pure(yes)
;
- String = "thread_safe",
+ String = "thread_safe",
MutAttr = thread_safe(thread_safe)
;
String = "not_thread_safe",
Index: compiler/prog_mutable.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_mutable.m,v
retrieving revision 1.2
diff -u -r1.2 prog_mutable.m
--- compiler/prog_mutable.m 28 Sep 2005 09:02:14 -0000 1.2
+++ compiler/prog_mutable.m 4 Oct 2005 15:12:52 -0000
@@ -20,16 +20,40 @@
%-----------------------------------------------------------------------------%
-:- func prog_mutable.get_pred_decl(module_name, string, (type), (inst))
- = item.
+ % Create a predmode declaration for a non-pure mutable get predicate.
+ % (This is the default get predicate.)
+ %
+:- func nonpure_get_pred_decl(module_name, string, (type), (inst)) = item.
+
+ % Create a predmode declaration for a non-pure mutable set predicate.
+ % (This is the default set predicate.)
+ %
+:- func nonpure_set_pred_decl(module_name, string, (type), (inst)) = item.
+
+ % Create a predmode declaration for a pure mutable get predicate.
+ % (This is only created if the `pure' mutable attribute is given.)
+ %
+:- func pure_get_pred_decl(module_name, string, (type), (inst)) = item.
+
+ % Create a predmode declaration for a pure mutable set predicate.
+ % (This is only create the `pure' mutable attribute is give.)
+ %
+:- func pure_set_pred_decl(module_name, string, (type), (inst)) = item.
+
+ % Create a predmode declaration for the mutable initialisation
+ % predicate.
+ %
+:- func init_pred_decl(module_name, string) = item.
+
+ % Create the foreign_decl for the mutable.
+ %
+:- func get_global_foreign_decl(string) = item.
+
+ % Create the foreign_code that defines the mutable.
+ %
+:- func get_global_foreign_defn(string) = item.
-:- func prog_mutable.set_pred_decl(module_name, string, (type), (inst))
- = item.
-:- func prog_mutable.init_pred_decl(module_name, string) = item.
-
- % XXX We should probably mangle Name for safety...
- %
:- func mutable_get_pred_sym_name(sym_name, string) = sym_name.
:- func mutable_set_pred_sym_name(sym_name, string) = sym_name.
@@ -43,6 +67,7 @@
:- implementation.
+:- import_module libs.globals.
:- import_module parse_tree.prog_foreign.
:- import_module parse_tree.prog_mode.
:- import_module list.
@@ -51,7 +76,7 @@
%-----------------------------------------------------------------------------%
-get_pred_decl(ModuleName, Name, Type, Inst) = GetPredDecl :-
+nonpure_get_pred_decl(ModuleName, Name, Type, Inst) = GetPredDecl :-
VarSet = varset__init,
InstVarSet = varset__init,
ExistQVars = [],
@@ -62,7 +87,7 @@
no /* with_type */, no /* with_inst */, yes(det),
true /* condition */, (semipure), Constraints).
-set_pred_decl(ModuleName, Name, Type, Inst) = SetPredDecl :-
+nonpure_set_pred_decl(ModuleName, Name, Type, Inst) = SetPredDecl :-
VarSet = varset__init,
InstVarSet = varset__init,
ExistQVars = [],
@@ -73,6 +98,43 @@
no /* with_type */, no /* with_inst */, yes(det),
true /* condition */, (impure), Constraints).
+pure_get_pred_decl(ModuleName, Name, Type, Inst) = GetPredDecl :-
+ VarSet = varset__init,
+ InstVarSet = varset__init,
+ ExistQVars = [],
+ Constraints = constraints([], []),
+ GetPredDecl = pred_or_func(VarSet, InstVarSet, ExistQVars, predicate,
+ mutable_get_pred_sym_name(ModuleName, Name),
+ [
+ type_and_mode(Type, out_mode(Inst)),
+ type_and_mode(io_state_type, di_mode),
+ type_and_mode(io_state_type, uo_mode)
+ ],
+ no /* with_type */, no /* with_inst */, yes(det),
+ true /* condition */, pure, Constraints).
+
+pure_set_pred_decl(ModuleName, Name, Type, Inst) = SetPredDecl :-
+ VarSet = varset__init,
+ InstVarSet = varset__init,
+ ExistQVars = [],
+ Constraints = constraints([], []),
+ SetPredDecl = pred_or_func(VarSet, InstVarSet, ExistQVars, predicate,
+ mutable_set_pred_sym_name(ModuleName, Name),
+ [
+ type_and_mode(Type, in_mode(Inst)),
+ type_and_mode(io_state_type, di_mode),
+ type_and_mode(io_state_type, uo_mode)
+ ],
+ no /* with_type */, no /* with_inst */, yes(det),
+ true /* condition */, pure, Constraints).
+
+ % Return the type io.state.
+ % XXX Perhaps this should be in prog_type?
+ %
+:- func io_state_type = (type).
+
+io_state_type = defined(qualified(unqualified("io"), "state"), [], star).
+
init_pred_decl(ModuleName, Name) = InitPredDecl :-
VarSet = varset__init,
InstVarSet = varset__init,
@@ -83,6 +145,19 @@
[], no /* with_type */, no /* with_inst */, yes(det),
true /* condition */, (impure), Constraints).
+%-----------------------------------------------------------------------------%
+
+get_global_foreign_decl(TargetMutableName) =
+ pragma(compiler(mutable_decl),
+ foreign_decl(c, foreign_decl_is_exported,
+ "extern MR_Word " ++ TargetMutableName ++ ";")).
+
+get_global_foreign_defn(TargetMutableName) =
+ pragma(compiler(mutable_decl),
+ foreign_code(c, "MR_Word " ++ TargetMutableName ++ ";")).
+
+%-----------------------------------------------------------------------------%
+
mutable_get_pred_sym_name(ModuleName, Name) =
qualified(ModuleName, "get_" ++ Name).
Index: compiler/type_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/type_util.m,v
retrieving revision 1.156
diff -u -r1.156 type_util.m
--- compiler/type_util.m 30 Sep 2005 08:08:36 -0000 1.156
+++ compiler/type_util.m 30 Sep 2005 09:40:19 -0000
@@ -786,9 +786,9 @@
% The list of dummy types should be kept in sync with MR_is_dummy_type
% in trace/mercury_trace.c.
%
-% XXX should we include aditi:state/0 in this list?
-type_util__is_dummy_argument_type_2("io", "state", 0). % io:state/0
-type_util__is_dummy_argument_type_2("store", "store", 1). % store:store/1.
+% XXX should we include aditi.state/0 in this list?
+type_util__is_dummy_argument_type_2("io", "state", 0). % io.state/0
+type_util__is_dummy_argument_type_2("store", "store", 1). % store.store/1.
type_util__constructors_are_dummy_argument_type([Ctor]) :-
Ctor = ctor([], [], qualified(unqualified("io"), "state"), [_]).
Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.332
diff -u -r1.332 reference_manual.texi
--- doc/reference_manual.texi 4 Oct 2005 07:20:20 -0000 1.332
+++ doc/reference_manual.texi 4 Oct 2005 15:31:44 -0000
@@ -4671,7 +4671,7 @@
@end example
This constructs a new mutable variable with access predicates that have the
-following signatures.
+following signatures:
@example
:- semipure get_varname(vartype::out(varinst)) is det.
@@ -4700,6 +4700,18 @@
the effects of @samp{set_varname/1} can be undone on backtracking. The
default, in case none is specified, is @samp{trailed}.
+ at item @samp{pure}
+This attribute cause the compiler to also construct pure access predicates
+for the mutable. The pure access predicates have the following signatures:
+
+ at example
+:- pred get_varname(vartype::out(varinst), io::di, io::uo) is det.
+:- pred set_varname(vartype::in(varinst), io::di, io::uo) is det.
+ at end example
+
+The pure access predicates will not be constructed unless the @samp{pure}
+attribute is specified.
+
@end table
The Melbourne Mercury compiler also supports the following attribute.
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.270
diff -u -r1.270 Mmakefile
--- tests/hard_coded/Mmakefile 4 Oct 2005 07:20:21 -0000 1.270
+++ tests/hard_coded/Mmakefile 4 Oct 2005 16:26:48 -0000
@@ -141,6 +141,7 @@
pretty_printing \
promise_equivalent_solutions_test \
promise_equiv_with_svars \
+ pure_mutable \
qual_adv_test \
qual_basic_test \
qual_is_test \
Index: tests/hard_coded/ppc_bug.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/ppc_bug.m,v
retrieving revision 1.1
diff -u -r1.1 ppc_bug.m
--- tests/hard_coded/ppc_bug.m 2 Dec 2004 07:51:28 -0000 1.1
+++ tests/hard_coded/ppc_bug.m 4 Oct 2005 16:33:35 -0000
@@ -1,10 +1,13 @@
-% The following program compiles incorrectly on PPC/MacOS X
-% in grade reg.gc. find_nth_yes/4 ends up throwing an
-% exception instead of returning `YesPos = 3'. Passing
-% `--no-optimize-fulljumps' causes the test to pass.
+% The following program compiles incorrectly on PPC/MacOS X in grade reg.gc.
+% find_nth_yes/4 ends up throwing an exception instead of returning `YesPos =
+% 3'. Passing `--no-optimize-fulljumps' causes the test to pass.
%
-% The test passes with gcc 2.95.2 (Apple version)
-% but fails with gcc 3.3 (Apple version).
+% The test passes with gcc 2.95.2 (Apple version) but fails with gcc 3.3
+% (Apple version).
+%
+% The problem was that gcc's `-floop-optimize' options was incompatible
+% with our use of global registers. The fix is to make sure that option
+% is disabled on powerpc-apple-darwin.
:- module ppc_bug.
Index: tests/hard_coded/pure_mutable.exp
===================================================================
RCS file: tests/hard_coded/pure_mutable.exp
diff -N tests/hard_coded/pure_mutable.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/pure_mutable.exp 4 Oct 2005 15:49:18 -0000
@@ -0,0 +1,2 @@
+Initial value of global = 561
+Final value of global = 562
Index: tests/hard_coded/pure_mutable.m
===================================================================
RCS file: tests/hard_coded/pure_mutable.m
diff -N tests/hard_coded/pure_mutable.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/pure_mutable.m 4 Oct 2005 15:49:18 -0000
@@ -0,0 +1,22 @@
+:- module pure_mutable.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module int.
+:- import_module list.
+:- import_module string.
+
+:- mutable(global, int, 561, ground, [untrailed, thread_safe, pure]).
+
+main(!IO) :-
+ get_global(X0, !IO),
+ io.format("Initial value of global = %d\n", [i(X0)], !IO),
+ set_global(X0 + 1, !IO),
+ get_global(X, !IO),
+ io.format("Final value of global = %d\n", [i(X)], !IO).
Index: vim/syntax/mercury.vim
===================================================================
RCS file: /home/mercury1/repository/mercury/vim/syntax/mercury.vim,v
retrieving revision 1.16
diff -u -r1.16 mercury.vim
--- vim/syntax/mercury.vim 4 Oct 2005 07:20:24 -0000 1.16
+++ vim/syntax/mercury.vim 4 Oct 2005 07:20:53 -0000
@@ -52,7 +52,7 @@
syn keyword mercuryCInterface may_call_mercury will_not_call_mercury
syn keyword mercuryCInterface thread_safe not_thread_safe maybe_thread_safe
syn keyword mercuryCInterface promise_pure promise_semipure
-syn keyword mercuryCInterface tabled_for_io local untrailed
+syn keyword mercuryCInterface tabled_for_io local untrailed trailed pure
syn keyword mercuryCInterface can_pass_as_mercury_type stable
syn keyword mercuryCInterface will_not_throw_exception
syn keyword mercuryCInterface export import
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list