[m-rev.] Add `:- initialise' directive to the language.
Julien Fischer
juliensf at cs.mu.OZ.AU
Wed Aug 17 16:18:34 AEST 2005
On Wed, 17 Aug 2005, Ralph Becket wrote:
> 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).
>
...
> :- 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.
I suggest: Modules that interact ... may require ...
> +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.
It's probably worth mentioning that duplicate initialisation predicate
are executed twice. (Actually, I'm not convinced that this is such
a good idea - I can think of some (foreign) libraries that should
only be initialised once and it would be preferable if the compiler
could pick up accidental attempts to do it twice).
> 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)();
>
What's the ellipses for?
> #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).
> +
> +%-----------------------------------------------------------------------------%
> +%-----------------------------------------------------------------------------%
If we're going to support multiple instances of the same intialiser then
you should test that here as well.
You should add a test to tests/invalid to test what happens when the
predicate in the initialise declaration doesn't exist.
There should be a similar test case for when an :- initialise declartion
occurs in the interface of a module.
Julien.
--------------------------------------------------------------------------
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