[m-rev.] Add `:- initialise' directive to the language.

Ralph Becket rafe at cs.mu.OZ.AU
Wed Aug 17 15:04:44 AEST 2005


Estimated hours taken: 16
Branches: main

Add support for initialisation predicates to be called before main/2 is
invoked.  The new directive is `:- initialise initpredname.'

NEWS:
	Mention the new functionality.

compiler/export.m:
	`:- pragma export' also adds a C function declaration in the
	generated C wrapper code to avoid C compiler warnings about
	missing declarations.

compiler/hlds_module.m:
	Added a new user_init_preds field to the module_info to
	record the preds named in `initialise' directives.
	Added predicates to access and update the new field.
	The exported names are generated automatically.

compiler/llds.m:
	Added a new field cfile_num_user_inits to c_file structure.

compiler/llds_out.m:
	Add code to include the `REQUIRED_INIT initpredexportname' lines
	in the comment section of the generated C that is recognised
	by mkinit.

compiler/make_hlds_passes.m:
	Handle the new `initialise' directives.

compiler/mercury_compile.m:
	Make sure the number of user defined init preds is passed
	to the C code construction preds.

compiler/mercury_to_mercury.m:
	Handle the output of `initialise' directives.

compiler/module_qual.m:
compiler/modules.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
	Handle the new `initialise' item.

compiler/prog_data.m:
	Add a new `initialise(sym_name)' item.

compiler/prog_io.m:
	Add code to parse `initialise' directives.

compiler/prog_mode.m:
	Add di_mode pred and func.

compiler/transform_llds.m:
	Handle the extra field in c_file.

doc/reference_manual.texi:
	Update the operator table in the reference manual.
	Document the new `initialise' directive.

library/list.m:
	Added index[01]_of_first_occurrence preds and
	index[01]_of_first_occurrence_det funcs.  I've often
	had a need for these and they are used in looking up
	initprednames in the new module_info field.

library/ops.m:
	Add `initialise' as a prefix operator.

runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
	Add a new exported variable, MR_address_of_init_modules_required.
	Call the function pointed to by this variable at the right point
	during module initialisation.

test/hard_coded/Mmakefile:
test/hard_coded/initialise_decl.exp:
test/hard_coded/initialise_decl.m:
	Added a test case.

util/mkinit.c:
	Now always checks C files for extra inits (previously you had to
	explicitly supply the -x flag).

Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.381
diff -u -r1.381 NEWS
--- NEWS	15 Aug 2005 04:11:41 -0000	1.381
+++ NEWS	17 Aug 2005 04:45:50 -0000
@@ -5,6 +5,9 @@
 * We have added support for functional dependencies to the typeclass system.
   See the "Type classes" section of the Mercury Language Refence Manual for
   details.
+* We have added support for optional module initialisation.  See the 
+  "Optional module initialisation" section of the Mercury Language Refence
+  Manual for details.
 
 Changes to the Mercury standard library:
 * We have added an `injection' module, for reversible maps that are injective.
Index: compiler/export.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/export.m,v
retrieving revision 1.86
diff -u -r1.86 export.m
--- compiler/export.m	24 Mar 2005 13:33:32 -0000	1.86
+++ compiler/export.m	17 Aug 2005 04:06:26 -0000
@@ -147,6 +147,18 @@
 	%
 	% MR_declare_entry(<label of called proc>); /* or MR_declare_static */
 	%
+	%	/* Start with a declaration to avoid C compiler warnings. */
+	% #if SEMIDET
+	%   MR_bool
+	% #elif FUNCTION
+	%   MR_Word
+	% #else
+	%   void
+	% #endif
+	% <function name>(MR_Word Mercury__Argument1,
+	%			MR_Word *Mercury__Argument2...);
+	%			/* Word for input, Word* for output */
+	%
 	% #if SEMIDET
 	%   MR_bool
 	% #elif FUNCTION
@@ -259,6 +271,9 @@
 	string__append_list([
 		"\n",
 		DeclareString, "(", ProcLabelString, ");\n",
+		"\n",
+		C_RetType, "\n",
+		C_Function, "(", ArgDecls, ");\n",
 		"\n",
 		C_RetType, "\n",
 		C_Function, "(", ArgDecls, ")\n{\n",
Index: compiler/hlds_module.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_module.m,v
retrieving revision 1.115
diff -u -r1.115 hlds_module.m
--- compiler/hlds_module.m	8 Jul 2005 04:22:02 -0000	1.115
+++ compiler/hlds_module.m	16 Aug 2005 05:54:30 -0000
@@ -433,6 +433,17 @@
 :- pred module_info_next_aditi_top_down_proc(module_info::in, int::out,
 	module_info::out) is det.
 
+:- pred module_info_new_user_init_pred(sym_name::in, int::out, module_info::in,
+	module_info::out) is det.
+
+:- pred module_info_user_init_pred_num(module_info::in, sym_name::in, int::out)
+	is det.
+
+:- pred module_info_num_user_init_preds(module_info::in, int::out) is det.
+
+
+:- func user_init_pred_c_name(int) = string.
+
 %-----------------------------------------------------------------------------%
 
 :- pred module_info_preds(module_info::in, pred_table::out) is det.
@@ -684,8 +695,14 @@
 						% List of top-down procedures
 						% which could be called from
 						% bottom-up Aditi procedures.
-		aditi_proc_counter		:: counter
-
+		aditi_proc_counter		:: counter,
+		user_init_preds   		:: list(sym_name)
+						% From `:- initialise initpred'
+						% declarations in this module.
+						% Items are added to the end;
+						% the C export name of each
+						% initpred is taken from its
+						% position in the list.
 	).
 
 	% A predicate which creates an empty module
@@ -729,7 +746,7 @@
 		map.init, counter__init(1), ImportedModules,
 		IndirectlyImportedModules, no_aditi_compilation, TypeSpecInfo,
 		NoTagTypes, no, [], init_analysis_info(mmc),
-		[], counter__init(1)),
+		[], counter__init(1), []),
 	ModuleInfo = module(ModuleSubInfo, PredicateTable, Requests,
 		UnifyPredMap, QualifierInfo, Types, Insts, Modes, Ctors,
 		ClassTable, SuperClassTable, InstanceTable, AssertionTable,
@@ -821,6 +838,23 @@
 	Counter0 = MI0 ^ sub_info ^ aditi_proc_counter,
 	counter__allocate(Proc, Counter0, Counter),
 	MI = MI0 ^ sub_info ^ aditi_proc_counter := Counter.
+
+module_info_new_user_init_pred(SymName, UserInitPredNo, MI0, MI) :-
+	InitPreds = MI0 ^ sub_info ^ user_init_preds ++ [SymName],
+	UserInitPredNo = list__length(InitPreds),
+	MI = MI0 ^ sub_info ^ user_init_preds := InitPreds.
+
+module_info_user_init_pred_num(MI, SymName, UserInitPredNo) :-
+	InitPreds = MI ^ sub_info ^ user_init_preds,
+	UserInitPredNo =
+		list__index1_of_first_occurrence_det(InitPreds, SymName).
+
+module_info_num_user_init_preds(MI, NumUserInitPreds) :-
+	NumUserInitPreds = list__length(MI ^ sub_info ^ user_init_preds).
+
+
+user_init_pred_c_name(UserInitPredNo) =
+	string.format("user_init_pred_%d", [i(UserInitPredNo)]).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.313
diff -u -r1.313 llds.m
--- compiler/llds.m	15 Aug 2005 07:18:30 -0000	1.313
+++ compiler/llds.m	17 Aug 2005 04:21:13 -0000
@@ -70,7 +70,8 @@
                 cfile_foreign_export    :: list(foreign_export),
                 cfile_vars              :: list(comp_gen_c_var),
                 cfile_data              :: list(comp_gen_c_data),
-                cfile_code              :: list(comp_gen_c_module)
+                cfile_code              :: list(comp_gen_c_module),
+                cfile_num_user_inits    :: int
             ).
 
     % Global variables generated by the compiler.
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.250
diff -u -r1.250 llds_out.m
--- compiler/llds_out.m	8 Jul 2005 04:22:04 -0000	1.250
+++ compiler/llds_out.m	16 Aug 2005 01:46:03 -0000
@@ -221,17 +221,19 @@
 %-----------------------------------------------------------------------------%
 
 output_llds(C_File, ComplexityProcs, StackLayoutLabels, MaybeRLFile, !IO) :-
+	C_File = c_file(ModuleName, C_HeaderInfo,
+		UserForeignCodes, Exports, Vars, Datas, Modules,
+		NumUserInitPreds),
 	globals__io_lookup_bool_option(split_c_files, SplitFiles, !IO),
 	(
 		SplitFiles = yes,
-		C_File = c_file(ModuleName, C_HeaderInfo,
-			UserForeignCodes, Exports, Vars, Datas, Modules),
 		module_name_to_file_name(ModuleName, ".dir", yes, ObjDirName,
 			!IO),
 		dir__make_directory(ObjDirName, _, !IO),
 
 		output_split_c_file_init(ModuleName, Modules, Datas, Vars,
-			ComplexityProcs, StackLayoutLabels, MaybeRLFile, !IO),
+			ComplexityProcs, StackLayoutLabels, MaybeRLFile, 
+			NumUserInitPreds, !IO),
 		output_split_user_foreign_codes(UserForeignCodes, ModuleName,
 			C_HeaderInfo, ComplexityProcs, StackLayoutLabels,
 			1, Num1, !IO),
@@ -272,7 +274,7 @@
 		ModuleName, C_HeaderLines, ComplexityProcs, StackLayoutLabels,
 		!Num, !IO) :-
 	CFile = c_file(ModuleName, C_HeaderLines, [UserForeignCode],
-		[], [], [], []),
+		[], [], [], [], 0),
 	output_single_c_file(CFile, yes(!.Num), ComplexityProcs,
 		StackLayoutLabels, no, !IO),
 	!:Num = !.Num + 1,
@@ -286,7 +288,7 @@
 output_split_c_exports([], _, _, _, _, !Num, !IO).
 output_split_c_exports([Export | Exports], ModuleName, C_HeaderLines,
 		ComplexityProcs, StackLayoutLabels, !Num, !IO) :-
-	CFile = c_file(ModuleName, C_HeaderLines, [], [Export], [], [], []),
+	CFile = c_file(ModuleName, C_HeaderLines, [], [Export], [], [], [], 0),
 	output_single_c_file(CFile, yes(!.Num), ComplexityProcs,
 		StackLayoutLabels, no, !IO),
 	!:Num = !.Num + 1,
@@ -301,7 +303,7 @@
 output_split_comp_gen_c_vars([], _, _, _, _, !Num, !IO).
 output_split_comp_gen_c_vars([Var | Vars], ModuleName, C_HeaderLines,
 		ComplexityProcs, StackLayoutLabels, !Num, !IO) :-
-	CFile = c_file(ModuleName, C_HeaderLines, [], [], [Var], [], []),
+	CFile = c_file(ModuleName, C_HeaderLines, [], [], [Var], [], [], 0),
 	output_single_c_file(CFile, yes(!.Num), ComplexityProcs,
 		StackLayoutLabels, no, !IO),
 	!:Num = !.Num + 1,
@@ -316,7 +318,7 @@
 output_split_comp_gen_c_datas([], _, _, _, _, !Num, !IO).
 output_split_comp_gen_c_datas([Data | Datas], ModuleName, C_HeaderLines,
 		ComplexityProcs, StackLayoutLabels, !Num, !IO) :-
-	CFile = c_file(ModuleName, C_HeaderLines, [], [], [], [Data], []),
+	CFile = c_file(ModuleName, C_HeaderLines, [], [], [], [Data], [], 0),
 	output_single_c_file(CFile, yes(!.Num), ComplexityProcs,
 		StackLayoutLabels, no, !IO),
 	!:Num = !.Num + 1,
@@ -331,7 +333,7 @@
 output_split_comp_gen_c_modules([], _, _, _, _, !Num, !IO).
 output_split_comp_gen_c_modules([Module | Modules], ModuleName, C_HeaderLines,
 		ComplexityProcs, StackLayoutLabels, !Num, !IO) :-
-	CFile = c_file(ModuleName, C_HeaderLines, [], [], [], [], [Module]),
+	CFile = c_file(ModuleName, C_HeaderLines, [], [], [], [], [Module], 0),
 	output_single_c_file(CFile, yes(!.Num), ComplexityProcs,
 		StackLayoutLabels, no, !IO),
 	!:Num = !.Num + 1,
@@ -341,10 +343,10 @@
 :- pred output_split_c_file_init(module_name::in, list(comp_gen_c_module)::in,
 	list(comp_gen_c_data)::in, list(comp_gen_c_var)::in,
 	list(complexity_proc_info)::in, map(label, data_addr)::in,
-	maybe(rl_file)::in, io::di, io::uo) is det.
+	maybe(rl_file)::in, int::in, io::di, io::uo) is det.
 
 output_split_c_file_init(ModuleName, Modules, Datas, Vars, ComplexityProcs,
-		StackLayoutLabels, MaybeRLFile, !IO) :-
+		StackLayoutLabels, MaybeRLFile, NumUserInitPreds, !IO) :-
 	module_name_to_file_name(ModuleName, ".m", no, SourceFileName, !IO),
 	module_name_to_split_c_file_name(ModuleName, 0, ".c", FileName, !IO),
 
@@ -354,7 +356,7 @@
 		library__version(Version),
 		io__set_output_stream(FileStream, OutputStream, !IO),
 		output_c_file_intro_and_grade(SourceFileName, Version, !IO),
-		output_init_comment(ModuleName, !IO),
+		output_init_comment(ModuleName, NumUserInitPreds, !IO),
 		output_c_file_mercury_headers(!IO),
 		io__write_string("\n", !IO),
 		decl_set_init(DeclSet0),
@@ -408,7 +410,7 @@
 
 output_single_c_file(CFile, SplitFiles, ComplexityProcs, StackLayoutLabels,
 		MaybeRLFile, !IO) :-
-	CFile = c_file(ModuleName, _, _, _, _, _, _),
+	CFile = c_file(ModuleName, _, _, _, _, _, _, _),
 	( SplitFiles = yes(Num) ->
 		module_name_to_split_c_file_name(ModuleName, Num, ".c",
 			FileName, !IO)
@@ -420,8 +422,8 @@
 		Result = ok(FileStream),
 		decl_set_init(DeclSet0),
 		do_output_single_c_file(CFile, SplitFiles, ComplexityProcs,
-			StackLayoutLabels, MaybeRLFile, FileStream,
-			DeclSet0, _, !IO),
+			StackLayoutLabels, MaybeRLFile, 
+			FileStream, DeclSet0, _, !IO),
 		io__close_output(FileStream, !IO)
 	;
 		Result = error(Error),
@@ -443,8 +445,8 @@
 
 do_output_single_c_file(CFile, SplitFiles, ComplexityProcs, StackLayoutLabels,
 		MaybeRLFile, FileStream, !DeclSet, !IO) :-
-	CFile = c_file(ModuleName, C_HeaderLines,
-		UserForeignCode, Exports, Vars, Datas, Modules),
+	CFile = c_file(ModuleName, C_HeaderLines, UserForeignCode, Exports,
+		Vars, Datas, Modules, NumUserInitPreds),
 	library__version(Version),
 	io__set_output_stream(FileStream, OutputStream, !IO),
 	module_name_to_file_name(ModuleName, ".m", no, SourceFileName,
@@ -454,7 +456,7 @@
 		SplitFiles = yes(_)
 	;
 		SplitFiles = no,
-		output_init_comment(ModuleName, !IO)
+		output_init_comment(ModuleName, NumUserInitPreds, !IO)
 	),
 	output_c_file_mercury_headers(!IO),
 
@@ -946,9 +948,9 @@
 
 	% Output a comment to tell mkinit what functions to
 	% call from <module>_init.c.
-:- pred output_init_comment(module_name::in, io::di, io::uo) is det.
+:- pred output_init_comment(module_name::in, int::in, io::di, io::uo) is det.
 
-output_init_comment(ModuleName, !IO) :-
+output_init_comment(ModuleName, NumUserInitPreds, !IO) :-
 	io__write_string("/*\n", !IO),
 	io__write_string("INIT ", !IO),
 	output_init_name(ModuleName, !IO),
@@ -963,8 +965,23 @@
 	;
 		Aditi = no
 	),
+	output_required_user_init_comments(NumUserInitPreds, !IO),
 	io__write_string("ENDINIT\n", !IO),
 	io__write_string("*/\n\n", !IO).
+
+:- pred output_required_user_init_comments(int::in, io::di, io::uo) is det.
+
+output_required_user_init_comments(N, !IO) :-
+	(
+		N > 0
+	->
+		output_required_user_init_comments(N - 1, !IO),
+		io__write_string("REQUIRED_INIT ", !IO),
+		io__write_string(user_init_pred_c_name(N), !IO),
+		io__nl(!IO)
+	;
+		true
+	).
 
 :- pred output_bunch_name(module_name::in, string::in, int::in, io::di, io::uo)
 	is det.
Index: compiler/make_hlds_passes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds_passes.m,v
retrieving revision 1.3
diff -u -r1.3 make_hlds_passes.m
--- compiler/make_hlds_passes.m	14 Aug 2005 03:20:39 -0000	1.3
+++ compiler/make_hlds_passes.m	17 Aug 2005 04:19:57 -0000
@@ -112,6 +112,7 @@
 :- import_module libs__options.
 :- import_module parse_tree__error_util.
 :- import_module parse_tree__prog_data.
+:- import_module parse_tree__prog_mode.
 :- import_module parse_tree__prog_out.
 :- import_module parse_tree__prog_type.
 :- import_module parse_tree__prog_util.
@@ -276,6 +277,9 @@
     % Check that the declarations for field extraction
     % and update functions are sensible.
     %
+    % Check that predicates listed in `:- initialise' declarations
+    % exist and have the right signature.
+    %
 :- pred add_item_list_clauses(item_list::in, import_status::in,
     module_info::in, module_info::out, qual_info::in, qual_info::out,
     io::di, io::uo) is det.
@@ -425,6 +429,9 @@
     % We add instance declarations on the second pass so that we don't add
     % an instance declaration before its class declaration.
     Item = instance(_, _, _, _, _,_).
+add_item_decl_pass_1(Item, _, !Status, !ModuleInfo, no, !IO) :-
+    % We add initialise declarations on the second pass.
+    Item = initialise(_).
 
 %-----------------------------------------------------------------------------%
 
@@ -497,8 +504,23 @@
     ),
     module_add_instance_defn(InstanceModuleName, Constraints, Name, Types,
         Body, VarSet, BodyStatus, Context, !ModuleInfo, !IO).
+add_item_decl_pass_2(Item, Context, !Status, !ModuleInfo, !IO) :-
+    Item = initialise(SymName),
+    % 
+    % To handle a `:- initialise(initpred).' declaration we need to
+    % (1) construct a new C function name, CName, to use to export initpred,
+    % (2) add `:- export(initpred(di, uo), CName).',
+    % (3) record the initpred/cname pair in the ModuleInfo so that
+    % code generation can ensure cname is called during module
+    % initialisation.
+    %
+    module_info_new_user_init_pred(SymName, UserInitPredNo, !ModuleInfo),
+    CName = user_init_pred_c_name(UserInitPredNo),
+    PragmaExportItem =
+        pragma(export(SymName, predicate, [di_mode, uo_mode], CName)),
+    add_item_decl_pass_2(PragmaExportItem, Context, !Status, !ModuleInfo, !IO).
 
-%------------------------------------------------------------------------------
+%-----------------------------------------------------------------------------%
 
 add_item_clause(Item, !Status, Context, !ModuleInfo, !QualInfo, !IO) :-
     Item = clause(VarSet, PredOrFunc, PredName, Args, Body),
@@ -668,9 +690,55 @@
         !.Status, !ModuleInfo, !QualInfo, !IO).
 add_item_clause(nothing(_), !Status, _, !ModuleInfo, !QualInfo, !IO).
 add_item_clause(typeclass(_, _, _, _, _, _), !Status, _, !ModuleInfo,
-    !QualInfo, !IO).
+        !QualInfo, !IO).
 add_item_clause(instance(_, _, _, _, _, _), !Status, _, !ModuleInfo, !QualInfo,
-    !IO).
+        !IO).
+add_item_clause(initialise(SymName), !Status, Context, !ModuleInfo, !QualInfo,
+        !IO) :-
+    module_info_get_predicate_table(!.ModuleInfo, PredTable),
+    (
+        predicate_table_search_pred_sym_arity(PredTable,
+            may_be_partially_qualified, SymName, 2 /* Arity */, PredIds)
+    ->
+        (
+            PredIds = [PredId]
+        ->
+            module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
+            pred_info_arg_types(PredInfo, ArgTypes),
+            (
+                ArgTypes = [Arg1Type, Arg2Type],
+                type_util__type_is_io_state(Arg1Type),
+                type_util__type_is_io_state(Arg2Type)
+                % XXX We should check the arg modes and detism are correct
+                % here.  For now the arg modes and detism will be checked by
+                % the implicit `:- pragma export(...).' added for this pred.
+            ->
+                module_info_user_init_pred_num(!.ModuleInfo, SymName,
+                    UserInitPredNo),
+                CExportName = user_init_pred_c_name(UserInitPredNo),
+                PragmaExportItem =
+                    pragma(export(SymName, predicate, [di_mode, uo_mode],
+                    CExportName)),
+                add_item_clause(PragmaExportItem, !Status, Context,
+                    !ModuleInfo, !QualInfo, !IO)
+            ;
+                write_error_pieces(Context, 0, [sym_name_and_arity(SymName/2),
+                    words(" used in initialise declaration does not have " ++
+                    "signature `pred(io::di, io::uo) is det'")], !IO),
+                module_info_incr_errors(!ModuleInfo)
+            )
+        ;
+            write_error_pieces(Context, 0, [sym_name_and_arity(SymName/2),
+                words(" used in initialise declaration has " ++
+                "multiple pred declarations.")], !IO),
+            module_info_incr_errors(!ModuleInfo)
+        )
+    ;
+        write_error_pieces(Context, 0, [sym_name_and_arity(SymName/2),
+            words(" used in initialise declaration does " ++
+            "not have a corresponding pred declaration.")], !IO),
+        module_info_incr_errors(!ModuleInfo)
+    ).
 
     % If a module_defn updates the import_status, return the new status
     % and whether uses of the following items must be module qualified,
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.341
diff -u -r1.341 mercury_compile.m
--- compiler/mercury_compile.m	16 Aug 2005 07:11:28 -0000	1.341
+++ compiler/mercury_compile.m	17 Aug 2005 04:15:48 -0000
@@ -4132,7 +4132,7 @@
     list(comp_gen_c_var)::in, list(comp_gen_c_data)::in,
     c_file::out, int::out, io::di, io::uo) is det.
 
-mercury_compile__construct_c_file(_Module, C_InterfaceInfo, Procedures,
+mercury_compile__construct_c_file(ModuleInfo, C_InterfaceInfo, Procedures,
         GlobalVars, AllData, CFile, ComponentCount, !IO) :-
     C_InterfaceInfo = foreign_interface_info(ModuleSymName, C_HeaderCode0,
         C_Includes, C_BodyCode0, _C_ExportDecls, C_ExportDefns),
@@ -4163,8 +4163,10 @@
     C_HeaderCode = list__reverse(C_IncludeHeaderCode) ++
         C_LocalHeaderCode ++ [Start | C_ExportedHeaderCode] ++ [End],
 
+    module_info_num_user_init_preds(ModuleInfo, NumUserInitPreds),
+
     CFile = c_file(ModuleSymName, C_HeaderCode, C_BodyCode,
-        C_ExportDefns, GlobalVars, AllData, ChunkedModules),
+        C_ExportDefns, GlobalVars, AllData, ChunkedModules, NumUserInitPreds),
     list__length(C_BodyCode, UserCCodeCount),
     list__length(C_ExportDefns, ExportCount),
     list__length(GlobalVars, CompGenVarCount),
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.261
diff -u -r1.261 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m	14 Aug 2005 03:20:39 -0000	1.261
+++ compiler/mercury_to_mercury.m	17 Aug 2005 04:15:48 -0000
@@ -758,6 +758,9 @@
         io__write_string("\n]", !IO)
     ),
     io__write_string(".\n", !IO).
+mercury_output_item(_, initialise(PredSymName), _, !IO) :-
+    io__write_string(":- initialise ", !IO),
+    mercury_output_sym_name(PredSymName, !IO).
 
 :- func mercury_to_string_promise_type(promise_type) = string.
 
Index: compiler/module_qual.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.108
diff -u -r1.108 module_qual.m
--- compiler/module_qual.m	13 Jul 2005 11:41:44 -0000	1.108
+++ compiler/module_qual.m	15 Aug 2005 04:43:44 -0000
@@ -334,6 +334,7 @@
         mq_info_set_classes(Classes, !Info)
     ).
 collect_mq_info_2(instance(_, _, _, _, _, _), !Info).
+collect_mq_info_2(initialise(_), !Info).
 
 :- pred collect_mq_info_qualified_symname(sym_name::in,
     mq_info::in, mq_info::out) is det.
@@ -715,6 +716,11 @@
     qualify_class_name(Id, Name - _, !Info, !IO),
     qualify_type_list(Types0, Types, !Info, !IO),
     qualify_instance_body(Name, Body0, Body).
+
+module_qualify_item(
+        initialise(PredSymName) - Context,
+        initialise(PredSymName) - Context,
+        !Info, yes, !IO).
 
 :- pred update_import_status(module_defn::in, mq_info::in, mq_info::out,
     bool::out) is det.
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.335
diff -u -r1.335 modules.m
--- compiler/modules.m	13 Jul 2005 11:41:44 -0000	1.335
+++ compiler/modules.m	15 Aug 2005 05:00:01 -0000
@@ -7282,6 +7282,7 @@
     ).
 item_needs_imports(instance(_, _, _, _, _, _)) = yes.
 item_needs_imports(promise(_, _, _, _)) = yes.
+item_needs_imports(initialise(_)) = yes.
 item_needs_imports(nothing(_)) = no.
 
 :- pred item_needs_foreign_imports(item::in, foreign_language::out) is nondet.
@@ -7626,6 +7627,7 @@
 reorderable_item(nothing(_)) = no.
 reorderable_item(pred_or_func(_, _, _, _, _, _, _, _, _, _, _, _)) = no.
 reorderable_item(pred_or_func_mode(_, _, _, _, _, _, _)) = no.
+reorderable_item(initialise(_)) = no.
 
 :- pred is_chunkable(item_and_context::in) is semidet.
 
@@ -7710,6 +7712,7 @@
 chunkable_item(typeclass(_, _, _, _, _, _)) = yes.
 chunkable_item(instance(_, _, _, _, _, _)) = yes.
 chunkable_item(clause(_, _, _, _, _)) = yes.
+chunkable_item(initialise(_)) = yes.
 chunkable_item(nothing(_)) = yes.
 
     % Given a list of items for which symname_ordered succeeds, we need to keep
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.132
diff -u -r1.132 prog_data.m
--- compiler/prog_data.m	14 Aug 2005 03:20:40 -0000	1.132
+++ compiler/prog_data.m	17 Aug 2005 04:15:51 -0000
@@ -163,6 +163,9 @@
 			ci_module_containing_instance :: module_name
 		)
 
+		% :- initialise(pred_name).
+	;	initialise(sym_name)
+
 	;	nothing(
 			nothing_maybe_warning	:: maybe(item_warning)
 		).
Index: compiler/prog_io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io.m,v
retrieving revision 1.243
diff -u -r1.243 prog_io.m
--- compiler/prog_io.m	13 May 2005 02:24:08 -0000	1.243
+++ compiler/prog_io.m	15 Aug 2005 05:16:15 -0000
@@ -1422,6 +1422,10 @@
 		)
 	).
 
+process_decl(ModuleName, VarSet, "initialise", Args, Attributes, Result):-
+	parse_initialise_decl(ModuleName, VarSet, Args, Result0),
+	check_no_attributes(Result0, Attributes, Result).
+
 :- pred parse_decl_attribute(string::in, list(term)::in, decl_attribute::out,
 	term::out) is semidet.
 
@@ -1763,6 +1767,35 @@
 	;
 		MaybeDeterminism0 = error(E, T),
 		Result = error(E, T)
+	).
+
+%-----------------------------------------------------------------------------%
+
+:- pred parse_initialise_decl(module_name::in, varset::in, list(term)::in,
+	maybe1(item)::out) is semidet.
+
+parse_initialise_decl(_ModuleName, _VarSet, [Term], Result) :-
+	parse_symbol_name_specifier(Term, MaybeSymNameSpecifier),
+	(
+		MaybeSymNameSpecifier = error(ErrMsg, Trm),
+		Result = error(ErrMsg, Trm)
+	;
+		MaybeSymNameSpecifier = ok(SymNameSpecifier),
+		(
+			SymNameSpecifier = name(SymName),
+			Result = ok(initialise(SymName))
+		;
+			SymNameSpecifier = name_arity(SymName, Arity),
+			(
+				Arity = 2
+			->
+				Result = ok(initialise(SymName))
+			;
+				Result = error("an initialise " ++
+				"declaration can only apply to " ++
+				"an arity 2 predicate", Term)
+			)
+		)
 	).
 
 %-----------------------------------------------------------------------------%
Index: compiler/prog_mode.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_mode.m,v
retrieving revision 1.6
diff -u -r1.6 prog_mode.m
--- compiler/prog_mode.m	26 Jul 2005 01:56:25 -0000	1.6
+++ compiler/prog_mode.m	12 Aug 2005 05:13:47 -0000
@@ -26,6 +26,8 @@
 :- pred out_mode((mode)::out) is det.
 :- func out_mode = (mode).
 :- func out_mode(inst) = (mode).
+:- pred di_mode((mode)::out) is det.
+:- func di_mode = (mode).
 :- pred uo_mode((mode)::out) is det.
 :- func uo_mode = (mode).
 :- pred unused_mode((mode)::out) is det.
@@ -143,6 +145,7 @@
 
 in_mode(in_mode).
 out_mode(out_mode).
+di_mode(di_mode).
 uo_mode(uo_mode).
 unused_mode(unused_mode).
 
@@ -150,6 +153,7 @@
 in_mode(I) = make_std_mode("in", [I]).
 out_mode = make_std_mode("out", []).
 out_mode(I) = make_std_mode("out", [I]).
+di_mode = make_std_mode("di", []).
 uo_mode = make_std_mode("uo", []).
 unused_mode = make_std_mode("unused", []).
 in_any_mode = make_std_mode("in", [any_inst]).
Index: compiler/recompilation.check.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/recompilation.check.m,v
retrieving revision 1.13
diff -u -r1.13 recompilation.check.m
--- compiler/recompilation.check.m	20 Apr 2005 12:57:16 -0000	1.13
+++ compiler/recompilation.check.m	15 Aug 2005 05:19:31 -0000
@@ -956,6 +956,7 @@
 check_for_ambiguities(_, _, _, promise(_, _, _, _) - _, !Info).
 check_for_ambiguities(_, _, _, module_defn(_, _) - _, !Info).
 check_for_ambiguities(_, _, _, instance(_, _, _, _, _, _) - _, !Info).
+check_for_ambiguities(_, _, _, initialise(_) - _, !Info).
 check_for_ambiguities(_, _, _, nothing(_) - _, !Info).
 
 :- pred item_is_new_or_changed(timestamp::in, item_version_numbers::in,
Index: compiler/recompilation.version.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/recompilation.version.m,v
retrieving revision 1.20
diff -u -r1.20 recompilation.version.m
--- compiler/recompilation.version.m	13 Jul 2005 11:41:45 -0000	1.20
+++ compiler/recompilation.version.m	15 Aug 2005 05:21:53 -0000
@@ -576,6 +576,7 @@
 	% 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(nothing(_), no).
 
 :- type maybe_pred_or_func_id == pair(maybe(pred_or_func), sym_name_and_arity).
@@ -733,6 +734,8 @@
 		Result = no
 	).
 item_is_unchanged(nothing(A), Item2) = ( Item2 = nothing(A) -> yes ; no ).
+item_is_unchanged(initialise(A), Item2) =
+	( Item2 = initialise(A) -> yes ; no ).
 
 item_is_unchanged(Item1, Item2) = Result :-
 	Item1 = pred_or_func(TVarSet1, _, ExistQVars1, PredOrFunc,
Index: compiler/transform_llds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/transform_llds.m,v
retrieving revision 1.15
diff -u -r1.15 transform_llds.m
--- compiler/transform_llds.m	22 Mar 2005 06:40:29 -0000	1.15
+++ compiler/transform_llds.m	15 Aug 2005 04:02:55 -0000
@@ -60,7 +60,7 @@
 :- pred transform_c_file(c_file::in, c_file::out, globals::in) is det.
 
 transform_c_file(CFile0, CFile, Globals) :-
-	CFile0 = c_file(ModuleName, _, _, _, _, _, Modules0),
+	CFile0 = c_file(ModuleName, _, _, _, _, _, Modules0, _),
 	% split up large computed gotos
 	globals__lookup_int_option(Globals, max_jump_table_size, MaxSize),
 	( MaxSize = 0 ->
Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.320
diff -u -r1.320 reference_manual.texi
--- doc/reference_manual.texi	14 Aug 2005 05:44:58 -0000	1.320
+++ doc/reference_manual.texi	17 Aug 2005 04:44:22 -0000
@@ -415,98 +415,113 @@
 
 @example
 
-Operator          Specifier Priority
+Operator                        Specifier         Priority
 
-.                 yfx       10
-@@                 xfx       50
-^                 xfy       99
-^                 fx        100
-`@var{op}`              yfx       120       @footnote{Operator term (@pxref{Terms}).}
-**                xfy       200
--                 fx        200
-\                 fx        200
-*                 yfx       400
-//                yfx       400
-/                 yfx       400
-<<                yfx       400
->>                yfx       400
-div               yfx       400
-mod               xfx       400
-rem               xfx       400
-++                xfy       500
-+                 yfx       500
-+                 fx        500
---                yfx       500
--                 yfx       500
-/\                yfx       500
-\/                yfx       500
-aditi_bottom_up   fx        500
-aditi_top_down    fx        500
-..                xfx       550
-:                 yfx       600
-:=                xfx       650
-=^                xfx       650
-<                 xfx       700
-=..               xfx       700
-=:=               xfx       700
-=<                xfx       700
-==                xfx       700
-=\=               xfx       700
-=                 xfx       700
->=                xfx       700
->                 xfx       700
-@@<                xfx       700
-@@=<               xfx       700
-@@>=               xfx       700
-@@>                xfx       700
-\==               xfx       700
-\=                xfx       700
-~=                xfx       700
-is                xfx       701
-and               xfy       720
-or                xfy       740
-func              fx        800
-impure            fy        800
-pred              fx        800
-semipure          fy        800
-\+                fy        900
-not               fy        900
-when              xfx       900
-~                 fy        900
-<=>               xfy       920
-<=                xfy       920
-=>                xfy       920
-all               fxy       950
-lambda            fxy       950
-some              fxy       950
-,                 xfy       1000
-&                 xfy       1025
-->                xfy       1050
-;                 xfy       1100
-then              xfx       1150
-if                fx        1160
-else              xfy       1170
-::                xfx       1175
-==>               xfx       1175
-where             xfx       1175
---->              xfy       1179
-type              fx        1180
-end_module        fx        1199
-import_module     fx        1199
-include_module    fx        1199
-instance          fx        1199
-inst              fx        1199
-mode              fx        1199
-module            fx        1199
-pragma            fx        1199
-promise           fx        1199
-rule              fx        1199
-typeclass         fx        1199
-use_module        fx        1199
--->               xfx       1200
-:-                xfx       1200
-:-                fx        1200
-?-                fx        1200
+.                               yfx               10
+!                               fx                40
+!.                              fx                40
+!:                              fx                40
+@@                               xfx               90
+^                               xfy               99
+^                               fx                100
+`@var{op}`                      yfx               120       @footnote{Operator term (@pxref{Terms}).}
+**                              xfy               200
+-                               fx                200
+\\                              fx                200
+*                               yfx               400
+/                               yfx               400
+//                              yfx               400
+<<                              yfx               400
+>>                              yfx               400
+div                             yfx               400
+mod                             xfx               400
+rem                             xfx               400
++                               fx                500
++                               yfx               500
+++                              xfy               500
+-                               yfx               500
+--                              yfx               500
+/\\                             yfx               500
+\\/                             yfx               500
+aditi_bottom_up                 fx                500
+aditi_top_down                  fx                500
+..                              xfx               550
+:                               yfx               600
+:=                              xfx               650
+=^                              xfx               650
+<                               xfx               700
+=                               xfx               700
+=..                             xfx               700
+=:=                             xfx               700
+=<                              xfx               700
+==                              xfx               700
+=\\=                            xfx               700
+>                               xfx               700
+>=                              xfx               700
+@@<                              xfx               700
+@@=<                             xfx               700
+@@>                              xfx               700
+@@>=                             xfx               700
+\\=                             xfx               700
+\\==                            xfx               700
+~=                              xfx               700
+is                              xfx               701
+and                             xfy               720
+or                              xfy               740
+func                            fx                800
+impure                          fy                800
+pred                            fx                800
+semipure                        fy                800
+\\+                             fy                900
+not                             fy                900
+when                            xfx               900
+~                               fy                900
+<=                              xfy               920
+<=>                             xfy               920
+=>                              xfy               920
+all                             fxy               950
+lambda                          fxy               950
+promise_equivalent_solutions    fxy               950
+promise_exclusive               fy                950
+promise_exclusive_exhaustive    fy                950
+promise_exhaustive              fy                950
+promise_impure                  fx                950
+promise_impure_implicit         fx                950
+promise_pure                    fx                950
+promise_pure_implicit           fx                950
+promise_semipure                fx                950
+promise_semipure_implicit       fx                950
+some                            fxy               950
+,                               xfy               1000
+&                               xfy               1025
+->                              xfy               1050
+;                               xfy               1100
+then                            xfx               1150
+if                              fx                1160
+else                            xfy               1170
+::                              xfx               1175
+==>                             xfx               1175
+where                           xfx               1175
+--->                            xfy               1179
+type                            fx                1180
+solver                          fy                1181
+end_module                      fx                1199
+import_module                   fx                1199
+include_module                  fx                1199
+initialise                      fx                1199
+inst                            fx                1199
+instance                        fx                1199
+mode                            fx                1199
+module                          fx                1199
+pragma                          fx                1199
+promise                         fx                1199
+rule                            fx                1199
+typeclass                       fx                1199
+use_module                      fx                1199
+-->                             xfx               1200
+:-                              fx                1200
+:-                              xfx               1200
+?-                              fx                1200
 
 @end example
 
@@ -533,6 +548,7 @@
 
 @example
 :- type
+:- solver type
 :- pred
 :- func
 :- inst
@@ -541,6 +557,7 @@
 :- instance
 :- pragma
 :- promise
+:- initialise
 :- module
 :- interface
 :- implementation
@@ -4219,6 +4236,7 @@
 * The module system::
 * An example module::
 * Sub-modules::
+* Optional module initialisation::
 @end menu
 
 @node The module system
@@ -4537,6 +4555,32 @@
 (The work-around is to use separate sub-modules instead of nested
 sub-modules, i.e.@: to put the sub-modules in separate source files.)
 @end itemize
+
+ at node Optional module initialisation
+ at section Optional module initialisation
+
+Some modules that interact with foreign libraries or services
+require special initialisation before use.
+Such modules may include any number of @samp{initialise} directives
+in their implementation sections.
+An @samp{initialise} directive takes the following form:
+
+ at example
+:- initialise initpredname.
+ at end example
+
+where the predicate @samp{initpredname} must be declared with the following
+signature:
+
+ at example
+:- pred initpredname(io::di, io::uo) is det.
+ at end example
+
+The effect of the @samp{initialise} declaration is to ensure that
+ at samp{initpredname} 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 submodules.
 
 @node Type classes
 @chapter Type classes
Index: library/list.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/list.m,v
retrieving revision 1.140
diff -u -r1.140 list.m
--- library/list.m	22 Jul 2005 12:32:07 -0000	1.140
+++ library/list.m	16 Aug 2005 01:55:34 -0000
@@ -339,6 +339,18 @@
 :- func list__det_index0(list(T), int) = T.
 :- func list__det_index1(list(T), int) = T.
 
+	% list__index*_of_first_occurrence(List, Elem, Position):
+	% 	Computes the least value of Position such that
+	% 	list_index*(List, Position, Elem).  The `_det' funcs
+	% 	call error/1 if Elem is not a member of List.
+	%
+:- pred list__index0_of_first_occurrence(list(T)::in, T::in, int::out)
+	is semidet.
+:- pred list__index1_of_first_occurrence(list(T)::in, T::in, int::out)
+	is semidet.
+:- func list__index0_of_first_occurrence_det(list(T), T) = int.
+:- func list__index1_of_first_occurrence_det(list(T), T) = int.
+
 	% list__zip(ListA, ListB, List):
 	%	List is the result of alternating the elements
 	%	of ListA and ListB, starting with the first element
@@ -1179,6 +1191,39 @@
 
 list__index1_det(List, N, Elem) :-
 	list__index0_det(List, N - 1, Elem).
+
+%-----------------------------------------------------------------------------%
+
+list__index0_of_first_occurrence(List, Elem, N) :-
+	list__index0_of_first_occurrence_2(List, Elem, 0, N).
+
+
+:- pred list__index0_of_first_occurrence_2(list(T)::in, T::in,
+	int::in, int::out) is semidet.
+
+list__index0_of_first_occurrence_2([X | Xs], Y, N0, N) :-
+	( Y = X -> N = N0
+	        ;  list__index0_of_first_occurrence_2(Xs, Y, N0 + 1, N)
+	).
+
+
+list__index1_of_first_occurrence(List, Elem, N + 1) :-
+	list__index0_of_first_occurrence(List, Elem, N).
+
+
+list__index0_of_first_occurrence_det(List, Elem) = N :-
+	( list__index0_of_first_occurrence(List, Elem, N0) ->
+		N = N0
+	;
+		error("list__index0_of_first_occurrence_det: item not found")
+	).
+
+list__index1_of_first_occurrence_det(List, Elem) = N :-
+	( list__index1_of_first_occurrence(List, Elem, N0) ->
+		N = N0
+	;
+		error("list__index1_of_first_occurrence_det: item not found")
+	).
 
 %-----------------------------------------------------------------------------%
 
Index: library/ops.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/ops.m,v
retrieving revision 1.50
diff -u -r1.50 ops.m
--- library/ops.m	26 Apr 2005 07:38:02 -0000	1.50
+++ library/ops.m	15 Aug 2005 04:18:29 -0000
@@ -310,6 +310,7 @@
 ops__op_table("import_module", before, fx, 1199). % Mercury extension
 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("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: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.149
diff -u -r1.149 mercury_wrapper.c
--- runtime/mercury_wrapper.c	1 Aug 2005 02:26:18 -0000	1.149
+++ runtime/mercury_wrapper.c	17 Aug 2005 03:10:36 -0000
@@ -339,6 +339,7 @@
 #ifdef	MR_DEEP_PROFILING
 void	(*MR_address_of_write_out_proc_statics)(FILE *fp);
 #endif
+void	(*MR_address_of_init_modules_required)(void);
 
 MR_TypeCtorInfo	MR_type_ctor_info_for_univ;
 MR_TypeInfo	MR_type_info_for_type_info;
@@ -609,6 +610,9 @@
 
 	/* initialize the Mercury library */
 	(*MR_library_initializer)();
+
+	/* run any ...*/
+	(*MR_address_of_init_modules_required)();
 
 #ifndef MR_HIGHLEVEL_CODE
   #ifndef __LCC__
Index: runtime/mercury_wrapper.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.68
diff -u -r1.68 mercury_wrapper.h
--- runtime/mercury_wrapper.h	1 Aug 2005 02:26:18 -0000	1.68
+++ runtime/mercury_wrapper.h	16 Aug 2005 08:13:08 -0000
@@ -102,6 +102,7 @@
 #ifdef	MR_DEEP_PROFILING
 extern	void		(*MR_address_of_write_out_proc_statics)(FILE *fp);
 #endif
+extern	void		(*MR_address_of_init_modules_required)(void);
 
 extern	MR_TypeCtorInfo	MR_type_ctor_info_for_univ;
 extern	MR_TypeInfo	MR_type_info_for_type_info;
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.261
diff -u -r1.261 Mmakefile
--- tests/hard_coded/Mmakefile	10 Aug 2005 09:21:50 -0000	1.261
+++ tests/hard_coded/Mmakefile	17 Aug 2005 04:28:11 -0000
@@ -97,6 +97,7 @@
 	impure_foreign2 \
 	impure_foreign3 \
 	impure_prune \
+	initialise_decl \
 	integer_test \
 	intermod_c_code \
 	intermod_foreign_type \
Index: tests/hard_coded/initialise_decl.exp
===================================================================
RCS file: tests/hard_coded/initialise_decl.exp
diff -N tests/hard_coded/initialise_decl.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/initialise_decl.exp	17 Aug 2005 04:27:58 -0000
@@ -0,0 +1,3 @@
+This is the first initialise pred, i1/2.
+This is the second initialise pred, i2/2.
+This is main/2.
Index: tests/hard_coded/initialise_decl.m
===================================================================
RCS file: tests/hard_coded/initialise_decl.m
diff -N tests/hard_coded/initialise_decl.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/initialise_decl.m	17 Aug 2005 04:27:10 -0000
@@ -0,0 +1,38 @@
+%-----------------------------------------------------------------------------%
+% initialise_decl.m
+% Ralph Becket <rafe at cs.mu.oz.au>
+% Wed Aug 17 14:25:01 EST 2005
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%
+% Test the `:- initialise initpred' directive.
+%
+%-----------------------------------------------------------------------------%
+
+:- module initialise_decl.
+
+:- interface.
+
+:- import_module io.
+
+
+
+:- pred main(io :: di, io :: uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- initialise i1.
+:- initialise i2.
+
+:- pred i1(io::di, io::uo) is det.
+i1(!IO) :- io.print("This is the first initialise pred, i1/2.\n", !IO).
+
+:- pred i2(io::di, io::uo) is det.
+i2(!IO) :- io.print("This is the second initialise pred, i2/2.\n", !IO).
+
+main(!IO) :- io.print("This is main/2.\n", !IO).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.101
diff -u -r1.101 mkinit.c
--- util/mkinit.c	11 Aug 2005 01:12:53 -0000	1.101
+++ util/mkinit.c	17 Aug 2005 03:02:22 -0000
@@ -241,7 +241,6 @@
 static int          num_files;
 static char         **files;
 static MR_bool      output_main_func = MR_TRUE;
-static MR_bool      c_files_contain_extra_inits = MR_FALSE;
 static MR_bool      aditi = MR_FALSE;
 static MR_bool      need_initialization_code = MR_FALSE;
 static MR_bool      need_tracing = MR_FALSE;
@@ -378,6 +377,7 @@
     "   MR_address_of_write_out_proc_statics =\n"
     "       write_out_proc_statics;\n"
     "#endif\n"
+    "   MR_address_of_init_modules_required = init_modules_required;\n"
     "#ifdef MR_RECORD_TERM_SIZES\n"
     "   MR_complexity_procs = MR_complexity_proc_table;\n"
     "   MR_num_complexity_procs = %d;\n"
@@ -731,7 +731,7 @@
             break;
 
         case 'x':
-            c_files_contain_extra_inits = MR_TRUE;
+            /* We always assume this option. */
             break;
 
         case 'X':
@@ -765,7 +765,6 @@
     fputs("  -r word:\tadd word to the flags for the runtime\n", stderr);
     fputs("  -t:\t\tenable execution tracing\n", stderr);
     fputs("  -w entry:\tset the entry point to the egiven label\n", stderr);
-    fputs("  -x:\t\tscan the C files for extra initializations\n", stderr);
     fputs("  -I dir:\tadd dir to the search path for init files\n", stderr);
     exit(EXIT_FAILURE);
 }
@@ -1122,11 +1121,7 @@
 
     len = strlen(filename);
     if (len >= 2 && strcmp(filename + len - 2, ".c") == 0) {
-        if (c_files_contain_extra_inits) {
-            process_init_file(filename);
-        } else {
-            process_c_file(filename);
-        }
+        process_init_file(filename);
     } else if (len >= 5 && strcmp(filename + len - 5, ".init") == 0) {
         process_init_file(filename);
     } else {
--------------------------------------------------------------------------
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