[m-rev.] for reviews: support impure initalise and finalise predicates

Julien Fischer juliensf at cs.mu.OZ.AU
Fri Sep 30 19:34:07 AEST 2005


For review by anyone.

Estimated hours taken: 4
Branches: main

Support impure initialise and finalise predicates in user code.  In order to
support this the arity of the initialise or finalise predicate can no longer be
optionally omitted from the declaration.  Supporting impure arity zero
initialise/finalise declarations removes the restriction that every module that
has an initialise/finalise declaration must import the io module.

Allow initialize/finalize to be used as synonyms for initialise/finalise.

Improve the documentation of initialise/finalise declarations.
In particular:

	- mention the above changes.
	- mention that they may be cc_multi.
	- specify the order in which they invoked with respect to
	  standard library initialisation/finalisation.
	- mention that these declarations are not currently available
	  on non-C backends.

compiler/make_hlds_passes.m:
	Support impure user initialise/finalise predicates.

compiler/mercury_to_mercury.m:
	Write out the arities of the predicates specified in
	initialise and finalise declarations.

compiler/prog_data.m:
	Add an arity field to the initialise and finalise items.

compiler/prog_io.m:
	Don't allow the arity to be omitted in initialise and finalise
	declarations.

compiler/module_qual.m:
compiler/modules.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
	Conform to the changes in the initialise and finalise items.

library/ops.m:
	Add the alternate spellings of initialise and finalise to the ops
	table.

doc/reference_manual.texi:
	Update the ops table.

	Mention that initialise and finalise predicates may be cc_multi.

	Document impure initialisation and finalisation predicates.

	Add some disclaimers: mutable, initialise and finalise declarations
	are not implemented for the non-C backends.

tests/hard_coded/Mmakefile:
tests/hard_coded/impure_init_and_final.m:
tests/hard_coded/impure_init_and_final.exp:
	Test impure initialise and finalise declarations.

tests/hard_coded/finalise_decl.m:
tests/hard_coded/intialise_decl.m:
	Conform to the above changes.  Also test the versions of the
	declarations that use the -ize ending.

tests/hard_coded/sub-modules/finalise_parent.m:
tests/hard_coded/sub-modules/initialise_child.m:
tests/hard_coded/sub-modules/initialise_parent.m:
	Conform to the above changes.

tests/invalid/bad_finalise.m:
tests/invalid/bad_finalise.err_exp:
tests/invalid/bad_initialise.m:
tests/invalid/bad_initialise.err_exp:
	Extend these tests to check for missing or bad arities
	in intialise or finalise declarations.

vim/syntax/mercury.vim:
	Highlight recently added syntax appropriately.

Index: compiler/make_hlds_passes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds_passes.m,v
retrieving revision 1.13
diff -u -r1.13 make_hlds_passes.m
--- compiler/make_hlds_passes.m	30 Sep 2005 08:08:25 -0000	1.13
+++ compiler/make_hlds_passes.m	30 Sep 2005 08:22:09 -0000
@@ -443,10 +443,10 @@
     Item = instance(_, _, _, _, _,_).
 add_item_decl_pass_1(Item, _, !Status, !ModuleInfo, no, !IO) :-
     % We add initialise declarations on the third pass.
-    Item = initialise(_, _).
+    Item = initialise(_, _, _).
 add_item_decl_pass_1(Item, _, !Status, !ModuleInfo, no, !IO) :-
     % We add finalise declarations on the third pass.
-    Item = finalise(_, _).
+    Item = finalise(_, _, _).
 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.
@@ -543,7 +543,7 @@
 add_item_decl_pass_2(Item, Context, !Status, !ModuleInfo, !IO) :-
     % These are processed properly during pass 3, we just do some
     % error checking at this point.
-    Item = initialise(Origin, _),
+    Item = initialise(Origin, _, _),
     !.Status = item_status(ImportStatus, _),
     ( ImportStatus = exported ->
         (
@@ -571,7 +571,7 @@
 add_item_decl_pass_2(Item, Context, !Status, !ModuleInfo, !IO) :-
     % There are processed properly during pass 3, we just do some error
     % checking at this point.
-    Item = finalise(Origin, _),
+    Item = finalise(Origin, _, _),
     !.Status = item_status(ImportStatus, _),
     ( ImportStatus = exported ->
         (
@@ -720,11 +720,10 @@
             (
                 % Ignore clauses that are introduced as a result of
                 % `intialise', `finalise' or `mutable' declarations.
-                Details = initialise_decl
-            ;
-                Details = mutable_decl
-            ;
-                Details = finalise_decl
+                ( Details = initialise_decl
+                ; Details = mutable_decl
+                ; Details = finalise_decl
+                )
             ;
                 ( Details = solver_type ; Details = foreign_imports ),
                 unexpected(this_file, "Bad introduced clauses.")
@@ -903,19 +902,19 @@
         !QualInfo, !IO).
 add_item_clause(instance(_, _, _, _, _, _), !Status, _, !ModuleInfo, !QualInfo,
         !IO).
-add_item_clause(initialise(user, SymName), !Status, Context, !ModuleInfo,
-        !QualInfo, !IO) :-
+add_item_clause(initialise(user, SymName, Arity), !Status, Context,
+        !ModuleInfo, !QualInfo, !IO) :-
     %
     % To handle a `:- initialise initpred.' declaration we need to:
     % (1) construct a new C function name, CName, to use to export initpred,
-    % (2) add `:- pragma export(initpred(di, uo), CName).',
+    % (2) add the export pragma that does this
     % (3) record the initpred/cname pair in the ModuleInfo so that
     % code generation can ensure cname is called during module initialisation.
     %
     module_info_get_predicate_table(!.ModuleInfo, PredTable),
     (
         predicate_table_search_pred_sym_arity(PredTable,
-            may_be_partially_qualified, SymName, 2 /* Arity */, PredIds)
+            may_be_partially_qualified, SymName, Arity, PredIds)
     ->
         (
             PredIds = [PredId]
@@ -926,15 +925,17 @@
             ProcInfos = map.values(ProcTable),
             (
                 ArgTypes = [Arg1Type, Arg2Type],
-                type_util__type_is_io_state(Arg1Type),
-                type_util__type_is_io_state(Arg2Type),
+                type_util.type_is_io_state(Arg1Type),
+                type_util.type_is_io_state(Arg2Type),
                 list.member(ProcInfo, ProcInfos),
                 proc_info_maybe_declared_argmodes(ProcInfo, MaybeHeadModes),
                 MaybeHeadModes = yes(HeadModes),
                 HeadModes = [ di_mode, uo_mode ],
                 proc_info_declared_determinism(ProcInfo, MaybeDetism),
                 MaybeDetism = yes(Detism),
-                ( Detism = det ; Detism = cc_multidet )
+                ( Detism = det ; Detism = cc_multidet ),
+                pred_info_get_purity(PredInfo, Purity),
+                Purity = pure
             ->
                 module_info_new_user_init_pred(SymName, CName, !ModuleInfo),
                 PragmaExportItem =
@@ -943,39 +944,57 @@
                 add_item_clause(PragmaExportItem, !Status, Context,
                     !ModuleInfo, !QualInfo, !IO)
             ;
+                ArgTypes = [],
+                list.member(ProcInfo, ProcInfos),
+                proc_info_maybe_declared_argmodes(ProcInfo, MaybeHeadModes),
+                MaybeHeadModes = yes(HeadModes),
+                HeadModes = [],
+                proc_info_declared_determinism(ProcInfo, MaybeDetism),
+                MaybeDetism = yes(Detism),
+                ( Detism = det; Detism = cc_multidet ),
+                pred_info_get_purity(PredInfo, Purity),
+                Purity = (impure)
+            ->
+                module_info_new_user_init_pred(SymName, CName, !ModuleInfo),
+                PragmaExportedItem =
+                    pragma(compiler(initialise_decl),
+                        export(SymName, predicate, [], CName)),
+                add_item_clause(PragmaExportedItem, !Status, Context,
+                    !ModuleInfo, !QualInfo, !IO)
+            ;
                 write_error_pieces(Context, 0,
                     [
                         words("Error:"),
-                        sym_name_and_arity(SymName/2),
-                        words("used in initialise declaration does not"),
-                        words("have signature"),
-                        fixed("`pred(io::di, io::uo) is det'")
+                        sym_name_and_arity(SymName/Arity),
+                        words("used in initialise declaration has"),
+                        words("invalid signature.")
                     ], !IO),
+                %
+                % TODO: provide verbose error information here.
+                %
                 module_info_incr_errors(!ModuleInfo)
             )
         ;
             write_error_pieces(Context, 0, [words("Error:"),
-                sym_name_and_arity(SymName/2),
+                sym_name_and_arity(SymName/Arity),
                 words(" used in initialise declaration has " ++
                 "multiple pred declarations.")], !IO),
             module_info_incr_errors(!ModuleInfo)
         )
     ;
         write_error_pieces(Context, 0, [words("Error:"),
-            sym_name_and_arity(SymName/2),
+            sym_name_and_arity(SymName/Arity),
             words(" used in initialise declaration does " ++
             "not have a corresponding pred declaration.")], !IO),
         module_info_incr_errors(!ModuleInfo)
     ).
-add_item_clause(initialise(compiler(Details), SymName), !Status, Context,
-        !ModuleInfo, !QualInfo, !IO) :-
+add_item_clause(initialise(compiler(Details), SymName, _Arity),
+        !Status, Context, !ModuleInfo, !QualInfo, !IO) :-
     %
     % The compiler introduces initialise declarations that call
     % impure predicates as part of the source-to-source transformation
     % for mutable variables.  These predicates *must* be impure in order
-    % to prevent the compiler optimizing them away.  We only allow
-    % the compiler to introduce impure initialisers - it is an error
-    % for the user to do so.
+    % to prevent the compiler optimizing them away.
     %
     ( Details = mutable_decl ->
         module_info_new_user_init_pred(SymName, CName, !ModuleInfo),
@@ -987,8 +1006,8 @@
     ;
         unexpected(this_file, "Bad introduced initialise declaration.")
     ).
-add_item_clause(finalise(Origin, SymName), !Status, Context, !ModuleInfo,
-        !QualInfo, !IO) :-
+add_item_clause(finalise(Origin, SymName, Arity),
+        !Status, Context, !ModuleInfo, !QualInfo, !IO) :-
     %
     % To handle a `:- finalise finalpred.' declaration we need to:
     % (1) construct a new C function name, CName, to use to export finalpred,
@@ -1004,7 +1023,7 @@
     module_info_get_predicate_table(!.ModuleInfo, PredTable),
     (
         predicate_table_search_pred_sym_arity(PredTable,
-            may_be_partially_qualified, SymName, 2 /* Arity */, PredIds)
+            may_be_partially_qualified, SymName, Arity, PredIds)
     ->
         (
             PredIds = [PredId]
@@ -1015,15 +1034,17 @@
             ProcInfos = map.values(ProcTable),
             (
                 ArgTypes = [Arg1Type, Arg2Type],
-                type_util__type_is_io_state(Arg1Type),
-                type_util__type_is_io_state(Arg2Type),
+                type_util.type_is_io_state(Arg1Type),
+                type_util.type_is_io_state(Arg2Type),
                 list.member(ProcInfo, ProcInfos),
                 proc_info_maybe_declared_argmodes(ProcInfo, MaybeHeadModes),
                 MaybeHeadModes = yes(HeadModes),
                 HeadModes = [ di_mode, uo_mode ],
                 proc_info_declared_determinism(ProcInfo, MaybeDetism),
                 MaybeDetism = yes(Detism),
-                ( Detism = det ; Detism = cc_multidet )
+                ( Detism = det ; Detism = cc_multidet ),
+                pred_info_get_purity(PredInfo, Purity),
+                Purity = pure
             ->
                 module_info_new_user_final_pred(SymName, CName, !ModuleInfo),
                 PragmaExportItem =
@@ -1032,26 +1053,44 @@
                 add_item_clause(PragmaExportItem, !Status, Context,
                     !ModuleInfo, !QualInfo, !IO)
             ;
+                ArgTypes = [],
+                list.member(ProcInfo, ProcInfos),
+                proc_info_maybe_declared_argmodes(ProcInfo, MaybeHeadModes),
+                MaybeHeadModes = yes(HeadModes),
+                HeadModes = [],
+                proc_info_declared_determinism(ProcInfo, MaybeDetism),
+                MaybeDetism = yes(Detism),
+                ( Detism = det; Detism = cc_multidet ),
+                pred_info_get_purity(PredInfo, Purity),
+                Purity = (impure)
+            ->
+                module_info_new_user_final_pred(SymName, CName, !ModuleInfo),
+                PragmaExportItem =
+                    pragma(compiler(finalise_decl),
+                        export(SymName, predicate, [], CName)),
+                add_item_clause(PragmaExportItem, !Status, Context,
+                    !ModuleInfo, !QualInfo, !IO)
+            ;
+
                 write_error_pieces(Context, 0,
                     [
                         words("Error:"),
-                        sym_name_and_arity(SymName/2),
-                        words("used in finalise declaration does not"),
-                        words("have signature"),
-                        fixed("`pred(io::di, io::uo) is det'")
+                        sym_name_and_arity(SymName/Arity),
+                        words("used in finalise declaration has"),
+                        words("invalid signature.")
                     ], !IO),
                 module_info_incr_errors(!ModuleInfo)
             )
         ;
             write_error_pieces(Context, 0, [words("Error:"),
-                sym_name_and_arity(SymName/2),
+                sym_name_and_arity(SymName/Arity),
                 words(" used in finalise declaration has " ++
                 "multiple pred declarations.")], !IO),
             module_info_incr_errors(!ModuleInfo)
         )
     ;
         write_error_pieces(Context, 0, [words("Error:"),
-            sym_name_and_arity(SymName/2),
+            sym_name_and_arity(SymName/Arity),
             words(" used in finalise declaration does " ++
             "not have a corresponding pred declaration.")], !IO),
         module_info_incr_errors(!ModuleInfo)
@@ -1069,7 +1108,7 @@
             Attrs = Attrs1
         ),
         add_item_clause(initialise(compiler(mutable_decl),
-                mutable_init_pred_sym_name(ModuleName, Name)),
+                mutable_init_pred_sym_name(ModuleName, Name), 0 /* Arity */),
             !Status, Context, !ModuleInfo, !QualInfo, !IO),
         InitClause = clause(compiler(mutable_decl), varset.init, predicate,
             mutable_init_pred_sym_name(ModuleName, Name), [],
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.269
diff -u -r1.269 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m	29 Sep 2005 06:33:08 -0000	1.269
+++ compiler/mercury_to_mercury.m	29 Sep 2005 06:55:49 -0000
@@ -761,13 +761,17 @@
         io__write_string("\n]", !IO)
     ),
     io__write_string(".\n", !IO).
-mercury_output_item(_, initialise(_, PredSymName), _, !IO) :-
-    io__write_string(":- initialise ", !IO),
+mercury_output_item(_, initialise(_, PredSymName, Arity), _, !IO) :-
+    io.write_string(":- initialise ", !IO),
     mercury_output_sym_name(PredSymName, !IO),
-    io__write_string(".\n", !IO).
-mercury_output_item(_, finalise(_, PredSymName), _, !IO) :-
+    io.write_string("/", !IO),
+    io.write_int(Arity, !IO),
+    io.write_string(".\n", !IO).
+mercury_output_item(_, finalise(_, PredSymName, Arity), _, !IO) :-
     io.write_string(":- finalise ", !IO),
     mercury_output_sym_name(PredSymName, !IO),
+    io.write_string("/", !IO),
+    io.write_int(Arity, !IO),
     io.write_string(".\n", !IO).
 mercury_output_item(_, mutable(Name, Type, InitTerm, Inst, Attrs), _, !IO) :-
     io__write_string(":- mutable(", !IO),
Index: compiler/module_qual.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.115
diff -u -r1.115 module_qual.m
--- compiler/module_qual.m	29 Sep 2005 06:33:11 -0000	1.115
+++ compiler/module_qual.m	29 Sep 2005 06:57:49 -0000
@@ -334,8 +334,8 @@
         mq_info_set_classes(Classes, !Info)
     ).
 collect_mq_info_2(instance(_, _, _, _, _, _), !Info).
-collect_mq_info_2(initialise(_, _), !Info).
-collect_mq_info_2(finalise(_, _), !Info).
+collect_mq_info_2(initialise(_, _, _), !Info).
+collect_mq_info_2(finalise(_, _, _), !Info).
 collect_mq_info_2(mutable(_, _, _, _, _), !Info).

 :- pred collect_mq_info_qualified_symname(sym_name::in,
@@ -721,13 +721,13 @@
     qualify_instance_body(Name, Body0, Body).

 module_qualify_item(
-        initialise(Origin, PredSymName) - Context,
-        initialise(Origin, PredSymName) - Context,
+        initialise(Origin, PredSymName, Arity) - Context,
+        initialise(Origin, PredSymName, Arity) - Context,
         !Info, yes, !IO).

 module_qualify_item(
-        finalise(Origin, PredSymName) - Context,
-        finalise(Origin, PredSymName) - Context,
+        finalise(Origin, PredSymName, Arity) - Context,
+        finalise(Origin, PredSymName, Arity) - Context,
         !Info, yes, !IO).

 module_qualify_item(
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.346
diff -u -r1.346 modules.m
--- compiler/modules.m	29 Sep 2005 06:33:11 -0000	1.346
+++ compiler/modules.m	29 Sep 2005 06:59:41 -0000
@@ -2049,9 +2049,9 @@
             Item0 = pragma(_, Pragma),
             pragma_allowed_in_interface(Pragma, no)
         ;
-            Item0 = initialise(_, _)
+            Item0 = initialise(_, _, _)
         ;
-            Item0 = finalise(_, _)
+            Item0 = finalise(_, _, _)
         )
      ->
          split_clauses_and_decls(Items0, ClauseItems1, InterfaceItems),
@@ -7347,8 +7347,8 @@
     ).
 item_needs_imports(instance(_, _, _, _, _, _)) = yes.
 item_needs_imports(promise(_, _, _, _)) = yes.
-item_needs_imports(initialise(_, _)) = yes.
-item_needs_imports(finalise(_, _)) = yes.
+item_needs_imports(initialise(_, _, _)) = yes.
+item_needs_imports(finalise(_, _, _)) = yes.
 item_needs_imports(mutable(_, _, _, _, _)) = yes.
 item_needs_imports(nothing(_)) = no.

@@ -7694,8 +7694,8 @@
 reorderable_item(nothing(_)) = no.
 reorderable_item(pred_or_func(_, _, _, _, _, _, _, _, _, _, _, _)) = no.
 reorderable_item(pred_or_func_mode(_, _, _, _, _, _, _)) = no.
-reorderable_item(initialise(_, _)) = no.
-reorderable_item(finalise(_, _)) = no.
+reorderable_item(initialise(_, _, _)) = no.
+reorderable_item(finalise(_, _, _)) = no.
 reorderable_item(mutable(_, _, _, _, _)) = no.

 :- pred is_chunkable(item_and_context::in) is semidet.
@@ -7781,8 +7781,8 @@
 chunkable_item(typeclass(_, _, _, _, _, _)) = yes.
 chunkable_item(instance(_, _, _, _, _, _)) = yes.
 chunkable_item(clause(_, _, _, _, _, _)) = yes.
-chunkable_item(initialise(_, _)) = yes.
-chunkable_item(finalise(_, _)) = yes.
+chunkable_item(initialise(_, _, _)) = yes.
+chunkable_item(finalise(_, _, _)) = yes.
 chunkable_item(mutable(_, _, _, _, _)) = no.
 chunkable_item(nothing(_)) = yes.

Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.139
diff -u -r1.139 prog_data.m
--- compiler/prog_data.m	29 Sep 2005 06:33:12 -0000	1.139
+++ compiler/prog_data.m	29 Sep 2005 06:47:40 -0000
@@ -200,10 +200,10 @@
 		)

 		% :- initialise pred_name.
-	;	initialise(item_origin, sym_name)
+	;	initialise(item_origin, sym_name, arity)

 		% :- finalise pred_name.
-	;	finalise(item_origin, sym_name)
+	;	finalise(item_origin, sym_name, arity)

 		% :- mutable(var_name, type, inst, value, attrs).
 	;	mutable(
Index: compiler/prog_io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io.m,v
retrieving revision 1.252
diff -u -r1.252 prog_io.m
--- compiler/prog_io.m	29 Sep 2005 06:33:12 -0000	1.252
+++ compiler/prog_io.m	30 Sep 2005 09:05:12 -0000
@@ -1422,11 +1422,13 @@
 		)
 	).

-process_decl(ModuleName, VarSet, "initialise", Args, Attributes, Result) :-
+process_decl(ModuleName, VarSet, InitDecl, Args, Attributes, Result) :-
+	( InitDecl = "initialise" ; InitDecl = "initialize" ),
 	parse_initialise_decl(ModuleName, VarSet, Args, Result0),
 	check_no_attributes(Result0, Attributes, Result).

-process_decl(ModuleName, VarSet, "finalise", Args, Attributes, Result) :-
+process_decl(ModuleName, VarSet, FinalDecl, Args, Attributes, Result) :-
+	( FinalDecl = "finalise" ; FinalDecl = "finalize" ),
 	parse_finalise_decl(ModuleName, VarSet, Args, Result0),
 	check_no_attributes(Result0, Attributes, Result).

@@ -1801,20 +1803,21 @@
 		MaybeSymNameSpecifier = error(ErrMsg, Trm),
 		Result = error(ErrMsg, Trm)
 	;
-		MaybeSymNameSpecifier = ok(SymNameSpecifier),
-		(
-			SymNameSpecifier = name(SymName),
-			Result = ok(initialise(user, SymName))
+		MaybeSymNameSpecifier = ok(SymNameSpecifier),
+		(
+			SymNameSpecifier = name(_),
+			Result = error("`initialise' " ++
+				"declaration requires arity", Term)
 		;
 			SymNameSpecifier = name_arity(SymName, Arity),
 			(
-				Arity = 2
+				( Arity = 2 ; Arity = 0 )
 			->
-				Result = ok(initialise(user, SymName))
+				Result = ok(initialise(user, SymName, Arity))
 			;
-				Result = error("an initialise " ++
-				"declaration can only apply to " ++
-				"an arity 2 predicate", Term)
+				Result = error("`initialise' " ++
+				"declaration specifies a predicate " ++
+				"whose arity is not zero or two", Term)
 			)
 		)
 	).
@@ -1832,18 +1835,19 @@
 	;
 		MaybeSymNameSpecifier = ok(SymNameSpecifier),
 		(
-			SymNameSpecifier = name(SymName),
-			Result = ok(finalise(user, SymName))
+			SymNameSpecifier = name(_),
+			Result = error("`finalise' " ++
+				"declaration requires arity", Term)
 		;
 			SymNameSpecifier = name_arity(SymName, Arity),
 			(
-				Arity = 2
+				( Arity = 2 ; Arity = 0)
 			->
-				Result = ok(finalise(user, SymName))
+				Result = ok(finalise(user, SymName, Arity))
 			;
-				Result = error("a finalise " ++
-				"declaration can only apply to " ++
-				"an arity 2 predicate", Term)
+				Result = error("`finalise' " ++
+				"declaration specifies a predicate " ++
+				"whose arity is not zero or two", Term)
 			)
 		)
 	).
Index: compiler/recompilation.check.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/recompilation.check.m,v
retrieving revision 1.20
diff -u -r1.20 recompilation.check.m
--- compiler/recompilation.check.m	29 Sep 2005 06:33:12 -0000	1.20
+++ compiler/recompilation.check.m	29 Sep 2005 07:01:09 -0000
@@ -956,8 +956,8 @@
 check_for_ambiguities(_, _, _, promise(_, _, _, _) - _, !Info).
 check_for_ambiguities(_, _, _, module_defn(_, _) - _, !Info).
 check_for_ambiguities(_, _, _, instance(_, _, _, _, _, _) - _, !Info).
-check_for_ambiguities(_, _, _, initialise(_, _) - _, !Info).
-check_for_ambiguities(_, _, _, finalise(_, _) - _, !Info).
+check_for_ambiguities(_, _, _, initialise(_, _, _) - _, !Info).
+check_for_ambiguities(_, _, _, finalise(_, _, _) - _, !Info).
 check_for_ambiguities(_, _, _, mutable(_, _, _, _, _) - _, !Info).
 check_for_ambiguities(_, _, _, nothing(_) - _, !Info).

Index: compiler/recompilation.version.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/recompilation.version.m,v
retrieving revision 1.26
diff -u -r1.26 recompilation.version.m
--- compiler/recompilation.version.m	29 Sep 2005 06:33:12 -0000	1.26
+++ compiler/recompilation.version.m	29 Sep 2005 07:02:26 -0000
@@ -577,8 +577,8 @@
 	% qualifier on an instance declaration is the module containing
 	% the class, not the module containing the instance).
 item_to_item_id_2(instance(_, _, _, _, _, _), no).
-item_to_item_id_2(initialise(_, _), no).
-item_to_item_id_2(finalise(_, _), no).
+item_to_item_id_2(initialise(_, _, _), no).
+item_to_item_id_2(finalise(_, _, _), no).
 item_to_item_id_2(mutable(_, _, _, _, _), no).
 item_to_item_id_2(nothing(_), no).

@@ -742,10 +742,10 @@
 		Result = no
 	).
 item_is_unchanged(nothing(A), Item2) = ( Item2 = nothing(A) -> yes ; no ).
-item_is_unchanged(initialise(O, A), Item2) =
-	( Item2 = initialise(O, A) -> yes ; no ).
-item_is_unchanged(finalise(O, A), Item2) =
-	( Item2 = finalise(O, A) -> yes ; no ).
+item_is_unchanged(initialise(O, A, B), Item2) =
+	( Item2 = initialise(O, A, B) -> yes ; no ).
+item_is_unchanged(finalise(O, A, B), Item2) =
+	( Item2 = finalise(O, A, B) -> yes ; no ).
 item_is_unchanged(mutable(A, B, C, D, E), Item2) =
 	( Item2 = mutable(A, B, C, D, E) -> yes ; no ).

Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.331
diff -u -r1.331 reference_manual.texi
--- doc/reference_manual.texi	29 Sep 2005 06:33:14 -0000	1.331
+++ doc/reference_manual.texi	30 Sep 2005 09:19:49 -0000
@@ -508,6 +508,9 @@
 import_module                   fx                1199
 include_module                  fx                1199
 initialise                      fx                1199
+initialize			fx		  1199
+finalise			fx		  1199
+finalize			fx		  1199
 inst                            fx                1199
 instance                        fx                1199
 mode                            fx                1199
@@ -4593,21 +4596,30 @@
 An @samp{initialise} directive has the following form:

 @example
-:- initialise initpredname.
+:- initialise initpredname/arity.
 @end example

-where the predicate @samp{initpredname/2} must be declared with the following
-signature:
+where the predicate @samp{initpredname} must be declared with one of the
+following signatures:

 @example
-:- pred initpredname(io::di, io::uo) is det.
+:- pred initpredname(io::di, io::uo) is @var{Det}.
+:- impure pred initpredname is @var{Det}.
 @end example

+ at var{Det} must be either @samp{det} or @samp{cc_multi}.
+
 The effect of the @samp{initialise} declaration is to ensure that
- at samp{initpredname} is invoked before the program's @samp{main}
+ at samp{initpredname/arity} is invoked before the program's @samp{main}
 predicate.  Initialisation predicates within a module are executed in the
 order in which they are specified, although no order may be assumed between
-different modules or sub-modules.
+different modules or sub-modules.  Initialisation predicates are only invoked
+after any intialisation required by the Mercury standard library.
+
+ at samp{initialize} is also allowed as a synonym for @samp{initialise}.
+
+Note: @samp{initialise} declarations are currently only supported on
+the C backends.

 @node Module finalisation
 @section Module finalisation
@@ -4619,21 +4631,31 @@
 A @samp{finalise} directive has the following form:

 @example
-:- finalise finalpredname.
+:- finalise finalpredname/arity.
 @end example

-where the predicate @samp{finalpredname/2} must be declared with the following
-signature:
+where the predicate @samp{finalpredname/arity} must be declared with
+one of the following signature:

 @example
-:- pred finalpredname(io::di, io::uo) is det.
+:- pred finalpredname(io::di, io::uo) is @var{Det}.
+:- impure pred finalpredname is @var{Det}
 @end example

+ at var{Det} must be either @samp{det} or @samp{cc_multi}.
+
 The effect of the @samp{finalise} declaration is to ensure that
- at samp{finalpredname} is invoked after the program's @samp{main}
+ at samp{finalpredname/arity} is invoked after the program's @samp{main}
 predicate.  Finalisation predicates within a module are executed in
 the order in which they are specified, although no order may be assumed between
-different modules or sub-modules.
+different modules or sub-modules.  Any finalisation required by the Mercury
+standard library will always occur after any finalisation predicates have been
+invoked.
+
+ at samp{finalize} is also allowed as a synonym for @samp{finalise}.
+
+Note: @samp{finalise} declarations are currently only supported on
+the C backends.

 @node Module-local mutable variables
 @section Module-local mutable variables
@@ -4703,6 +4725,9 @@
 interface section of a module.  The usual visibility rules for sub-modules
 apply to the mutable variable access predicates.

+Note: @samp{mutable} declarations are currently only supported on
+the C backends.
+
 @node Type classes
 @chapter Type classes

Index: library/ops.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/ops.m,v
retrieving revision 1.54
diff -u -r1.54 ops.m
--- library/ops.m	29 Sep 2005 06:33:14 -0000	1.54
+++ library/ops.m	29 Sep 2005 06:34:12 -0000
@@ -311,7 +311,9 @@
 ops__op_table("include_module", before, fx, 1199). % Mercury extension
 ops__op_table("impure", before, fy, 800).	% Mercury extension
 ops__op_table("initialise", before, fx, 1199).	% Mercury extension
+ops__op_table("initialize", before, fx, 1199).	% Mercury extension
 ops__op_table("finalise", before, fx, 1199).	% Mercury extension
+ops__op_table("finalize", before, fx, 1199).	% Mercury extension
 ops__op_table("inst", before, fx, 1199).	% Mercury extension
 ops__op_table("instance", before, fx, 1199).	% Mercury extension
 ops__op_table("is", after, xfx, 701).		% ISO Prolog says prec 700
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.269
diff -u -r1.269 Mmakefile
--- tests/hard_coded/Mmakefile	29 Sep 2005 06:33:15 -0000	1.269
+++ tests/hard_coded/Mmakefile	30 Sep 2005 09:16:39 -0000
@@ -99,6 +99,7 @@
 	impure_foreign \
 	impure_foreign2 \
 	impure_foreign3 \
+	impure_init_and_final \
 	impure_prune \
 	initialise_decl \
 	integer_test \
Index: tests/hard_coded/finalise_decl.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/finalise_decl.m,v
retrieving revision 1.1
diff -u -r1.1 finalise_decl.m
--- tests/hard_coded/finalise_decl.m	29 Sep 2005 06:33:16 -0000	1.1
+++ tests/hard_coded/finalise_decl.m	30 Sep 2005 09:02:30 -0000
@@ -18,8 +18,8 @@

 :- implementation.

-:- finalise i1.
-:- finalise i2.
+:- finalise i1/2.
+:- finalize i2/2.

 :- pred i1(io::di, io::uo) is det.
 i1(!IO) :- io.print("This is the first finalise pred, i1/2.\n", !IO).
Index: tests/hard_coded/impure_init_and_final.exp
===================================================================
RCS file: tests/hard_coded/impure_init_and_final.exp
diff -N tests/hard_coded/impure_init_and_final.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/impure_init_and_final.exp	30 Sep 2005 09:16:01 -0000
@@ -0,0 +1,3 @@
+This is init...
+This is main...
+This is final...
Index: tests/hard_coded/impure_init_and_final.m
===================================================================
RCS file: tests/hard_coded/impure_init_and_final.m
diff -N tests/hard_coded/impure_init_and_final.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/impure_init_and_final.m	30 Sep 2005 09:15:50 -0000
@@ -0,0 +1,32 @@
+:- module impure_init_and_final.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- initialise init/0.
+:- finalise final/0.
+
+main(!IO) :- io.write_string("This is main...\n", !IO).
+
+:- pragma foreign_decl("C", "#include <stdio.h>").
+
+:- impure pred puts(string::in) is det.
+:- pragma foreign_proc("C",
+	puts(S::in),
+	[will_not_call_mercury],
+"
+	puts(S);
+").
+
+:- impure pred init is det.
+
+init :- impure puts("This is init...").
+
+:- impure pred final is det.
+
+final :- impure puts("This is final...").
Index: tests/hard_coded/initialise_decl.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/initialise_decl.m,v
retrieving revision 1.1
diff -u -r1.1 initialise_decl.m
--- tests/hard_coded/initialise_decl.m	29 Aug 2005 03:22:31 -0000	1.1
+++ tests/hard_coded/initialise_decl.m	30 Sep 2005 09:02:42 -0000
@@ -23,8 +23,8 @@

 :- implementation.

-:- initialise i1.
-:- initialise i2.
+:- initialise i1/2.
+:- initialize i2/2.

 :- pred i1(io::di, io::uo) is det.
 i1(!IO) :- io.print("This is the first initialise pred, i1/2.\n", !IO).
Index: tests/hard_coded/sub-modules/finalise_parent.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/sub-modules/finalise_parent.m,v
retrieving revision 1.1
diff -u -r1.1 finalise_parent.m
--- tests/hard_coded/sub-modules/finalise_parent.m	29 Sep 2005 06:33:17 -0000	1.1
+++ tests/hard_coded/sub-modules/finalise_parent.m	30 Sep 2005 09:03:17 -0000
@@ -14,7 +14,7 @@

 :- implementation.

-:- finalise parent_final.
+:- finalise parent_final/2.

 :- pred parent_final(io::di, io::uo) is det.

Index: tests/hard_coded/sub-modules/initialise_child.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/sub-modules/initialise_child.m,v
retrieving revision 1.1
diff -u -r1.1 initialise_child.m
--- tests/hard_coded/sub-modules/initialise_child.m	31 Aug 2005 04:28:23 -0000	1.1
+++ tests/hard_coded/sub-modules/initialise_child.m	30 Sep 2005 09:03:08 -0000
@@ -6,7 +6,7 @@

 :- implementation.

-:- initialise child_init.
+:- initialise child_init/2.

 :- pred child_init(io::di, io::uo) is det.

Index: tests/hard_coded/sub-modules/initialise_parent.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/sub-modules/initialise_parent.m,v
retrieving revision 1.1
diff -u -r1.1 initialise_parent.m
--- tests/hard_coded/sub-modules/initialise_parent.m	31 Aug 2005 04:28:23 -0000	1.1
+++ tests/hard_coded/sub-modules/initialise_parent.m	30 Sep 2005 09:03:00 -0000
@@ -14,7 +14,7 @@

 :- implementation.

-:- initialise parent_init.
+:- initialise parent_init/2.

 :- pred parent_init(io::di, io::uo) is det.

Index: tests/invalid/bad_finalise_decl.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/bad_finalise_decl.err_exp,v
retrieving revision 1.1
diff -u -r1.1 bad_finalise_decl.err_exp
--- tests/invalid/bad_finalise_decl.err_exp	29 Sep 2005 06:33:17 -0000	1.1
+++ tests/invalid/bad_finalise_decl.err_exp	30 Sep 2005 09:06:22 -0000
@@ -1,7 +1,9 @@
+bad_finalise_decl.m:025: Error: `finalise' declaration requires arity: i4.
+bad_finalise_decl.m:026: Error: `finalise' declaration specifies a predicate whose arity is not zero or two: i5 / 6.
 bad_finalise_decl.m:016: Error: `finalise' declaration in module interface.
-bad_finalise_decl.m:016: Error: `i2'/2 used in finalise declaration does not
-bad_finalise_decl.m:016:   have signature `pred(io::di, io::uo) is det'
-bad_finalise_decl.m:023: Error: `i1'/2 used in finalise declaration does not
-bad_finalise_decl.m:023:   have signature `pred(io::di, io::uo) is det'
+bad_finalise_decl.m:016: Error: `i2'/2 used in finalise declaration has invalid
+bad_finalise_decl.m:016:   signature.
+bad_finalise_decl.m:023: Error: `i1'/2 used in finalise declaration has invalid
+bad_finalise_decl.m:023:   signature.
 bad_finalise_decl.m:024: Error: `i3'/2 used in finalise declaration does not
 bad_finalise_decl.m:024:   have a corresponding pred declaration.
Index: tests/invalid/bad_finalise_decl.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/bad_finalise_decl.m,v
retrieving revision 1.1
diff -u -r1.1 bad_finalise_decl.m
--- tests/invalid/bad_finalise_decl.m	29 Sep 2005 06:33:17 -0000	1.1
+++ tests/invalid/bad_finalise_decl.m	30 Sep 2005 09:04:05 -0000
@@ -13,15 +13,17 @@

 :- pred main(io::di, io::uo) is det.

-:- finalise i2.
+:- finalise i2/2.

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%

 :- implementation.

-:- finalise i1.
-:- finalise i3.
+:- finalise i1/2.
+:- finalise i3/2.
+:- finalise i4.
+:- finalise i5/6.

 :- pred i1(T::di, T::uo) is det.
 i1(X, X).
@@ -29,6 +31,13 @@
 :- pred i2(io::in, io::out) is det.
 i2(!IO).

+
+:- pred i4(io::di, io::uo) is det.
+:- pred i5(io::di, io::uo) is det.
+
+i4(!IO).
+i5(!IO).
+
 main(!IO) :- io.print("This is main/2.\n", !IO).

 %-----------------------------------------------------------------------------%
Index: tests/invalid/bad_initialise_decl.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/bad_initialise_decl.err_exp,v
retrieving revision 1.3
diff -u -r1.3 bad_initialise_decl.err_exp
--- tests/invalid/bad_initialise_decl.err_exp	14 Sep 2005 05:26:42 -0000	1.3
+++ tests/invalid/bad_initialise_decl.err_exp	30 Sep 2005 09:08:07 -0000
@@ -1,7 +1,9 @@
+bad_initialise_decl.m:028: Error: `initialise' declaration requires arity: i4.
+bad_initialise_decl.m:029: Error: `initialise' declaration specifies a predicate whose arity is not zero or two: i5 / 6.
 bad_initialise_decl.m:019: Error: `initialise' declaration in module interface.
-bad_initialise_decl.m:019: Error: `i2'/2 used in initialise declaration does
-bad_initialise_decl.m:019:   not have signature `pred(io::di, io::uo) is det'
-bad_initialise_decl.m:026: Error: `i1'/2 used in initialise declaration does
-bad_initialise_decl.m:026:   not have signature `pred(io::di, io::uo) is det'
+bad_initialise_decl.m:019: Error: `i2'/2 used in initialise declaration has
+bad_initialise_decl.m:019:   invalid signature.
+bad_initialise_decl.m:026: Error: `i1'/2 used in initialise declaration has
+bad_initialise_decl.m:026:   invalid signature.
 bad_initialise_decl.m:027: Error: `i3'/2 used in initialise declaration does
 bad_initialise_decl.m:027:   not have a corresponding pred declaration.
Index: tests/invalid/bad_initialise_decl.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/bad_initialise_decl.m,v
retrieving revision 1.2
diff -u -r1.2 bad_initialise_decl.m
--- tests/invalid/bad_initialise_decl.m	5 Sep 2005 03:45:59 -0000	1.2
+++ tests/invalid/bad_initialise_decl.m	30 Sep 2005 09:07:42 -0000
@@ -16,15 +16,17 @@

 :- pred main(io::di, io::uo) is det.

-:- initialise i2.
+:- initialise i2/2.

 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%

 :- implementation.

-:- initialise i1.
-:- initialise i3.
+:- initialise i1/2.
+:- initialise i3/2.
+:- initialise i4.
+:- initialise i5/6.

 :- pred i1(T::di, T::uo) is det.
 i1(X, X).
Index: vim/syntax/mercury.vim
===================================================================
RCS file: /home/mercury1/repository/mercury/vim/syntax/mercury.vim,v
retrieving revision 1.15
diff -u -r1.15 mercury.vim
--- vim/syntax/mercury.vim	12 Sep 2005 03:05:41 -0000	1.15
+++ vim/syntax/mercury.vim	29 Sep 2005 06:35:00 -0000
@@ -35,6 +35,7 @@
 syn keyword mercuryKeyword      module use_module import_module
 syn keyword mercuryKeyword      include_module end_module
 syn keyword mercuryKeyword      initialise mutable
+syn keyword mercuryKeyword      initialize finalize finalise
 syn keyword mercuryKeyword      interface implementation
 syn keyword mercuryKeyword      pred mode func type inst solver
 syn keyword mercuryKeyword      is semidet det nondet multi erroneous failure

--------------------------------------------------------------------------
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