for review: add nested modules
Fergus Henderson
fjh at cs.mu.OZ.AU
Mon Mar 2 16:38:29 AEDT 1998
On 02-Mar-1998, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> >Add support for nested modules.
>
> This looks pretty good. Just a few minor comments:
Thanks for your comments, Simon.
Here's a new diff which addresses all of Simon's and DJ's comments.
it is relative to my previous one, except for the
tests/invalid and tests/warning directories, where it is
relative to the main branch (since that was simpler).
The log message is the same as before, with the following addition:
tests/invalid/Mmakefile:
tests/invalid/missing_interface_import.m:
tests/invalid/missing_interface_import.err_exp:
Regression test to check that the compiler reports
errors for missing `import_module' in the interface section.
I will commit this today.
diff -u old2/compiler/dead_proc_elim.m compiler/dead_proc_elim.m
--- old2/compiler/dead_proc_elim.m Thu Feb 26 23:08:03 1998
+++ compiler/dead_proc_elim.m Mon Mar 2 14:49:57 1998
@@ -39,10 +39,11 @@
:- pred dead_pred_elim(module_info, module_info).
:- mode dead_pred_elim(in, out) is det.
-:- type entity ---> proc(pred_id, proc_id)
- ; base_gen_info(module_name, string, int).
+:- type entity
+ ---> proc(pred_id, proc_id)
+ ; base_gen_info(module_name, string, int).
-:- type needed_map == map(entity, maybe(int)).
+:- type needed_map == map(entity, maybe(int)).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
diff -u old2/compiler/intermod.m compiler/intermod.m
--- old2/compiler/intermod.m Thu Feb 26 23:08:07 1998
+++ compiler/intermod.m Mon Mar 2 16:15:06 1998
@@ -18,7 +18,6 @@
% - pragma declarations for the exported preds.
% - pragma c_header declarations if any pragma_c_code preds are written.
% All these items should be module qualified.
-% Constructors should be explicitly type qualified. (XXX why?)
%
% This module also contains predicates to read in the .opt files and
% to adjust the import status of local predicates which are exported for
@@ -350,6 +349,9 @@
call(PredId0, B, Args, D, MaybeUnifyContext, PredName0) - Info,
call(PredId, B, Args, D, MaybeUnifyContext, PredName) - Info, DoWrite)
-->
+ %
+ % Fully module-qualify the pred name
+ %
intermod_info_get_module_info(ModuleInfo),
intermod_info_get_var_types(VarTypes),
intermod_info_get_tvarset(TVarSet),
@@ -360,15 +362,14 @@
{ PredId = PredId0 },
{ PredName1 = PredName0 }
),
- (
- { PredName1 = qualified(_, _) },
- { PredName = PredName1 }
- ;
- { PredName1 = unqualified(Name) },
- { module_info_pred_info(ModuleInfo, PredId, PredInfo) },
- { pred_info_module(PredInfo, PredModule) },
- { PredName = qualified(PredModule, Name) }
- ),
+ { unqualify_name(PredName1, UnqualPredName) },
+ { module_info_pred_info(ModuleInfo, PredId, PredInfo) },
+ { pred_info_module(PredInfo, PredModule) },
+ { PredName = qualified(PredModule, UnqualPredName) },
+
+ %
+ % Ensure that the called predicate will be exported.
+ %
(
% We don't need to export complicated unification
% pred declarations, since they will be recreated when
@@ -512,8 +513,7 @@
intermod__gather_proc_modes(ModuleInfo, ModeDefns,
UserInstDefns, Modes).
- % Check if the functor is a function call, a higher-order
- % term, or an unqualified symbol. If so, module qualify.
+ % Fully module-qualify the right-hand-side of a unification.
% For function calls and higher-order terms, call intermod__add_proc
% so that the predicate or function will be exported if necessary.
intermod__module_qualify_unify_rhs(LVar, functor(Functor0, Vars),
@@ -549,7 +549,7 @@
->
%
% Yes, it is a function call.
- % Module-qualify it.
+ % Fully module-qualify it.
% Make sure that the called function will be exported.
%
{ Functor = cons(QualifiedFuncName, Arity) },
@@ -574,7 +574,7 @@
TVarSet, ArgTypes, ModuleInfo, PredId, _ProcId) },
intermod_info_add_proc(PredId, DoWrite),
%
- % Module-qualify it.
+ % Fully module-qualify it.
%
{ unqualify_name(PredName, UnqualPredName) },
{ predicate_module(ModuleInfo, PredId, Module) },
@@ -582,18 +582,24 @@
{ Functor = cons(QualifiedPredName, Arity) }
;
%
- % Is it an unqualified functor symbol?
+ % Is it a functor symbol for which we can add
+ % a module qualifier?
%
- { Functor0 = cons(unqualified(ConsName), ConsArity) },
+ { Functor0 = cons(ConsName, ConsArity) },
{ map__lookup(VarTypes, LVar, VarType) },
{ type_to_type_id(VarType, TypeId, _) },
{ TypeId = qualified(TypeModule, _) - _ }
->
- { Functor = cons(qualified(TypeModule, ConsName), ConsArity) },
+ %
+ % Fully module-qualify it
+ %
+ { unqualify_name(ConsName, UnqualConsName) },
+ { Functor = cons(qualified(TypeModule, UnqualConsName),
+ ConsArity) },
{ DoWrite = yes }
;
- % XXX for (perhaps partially) qualified functor symbols,
- % should we still add the module qualifier from the type?
+ % It is a constant of a builtin type.
+ % No module qualification needed.
{ Functor = Functor0 },
{ DoWrite = yes }
).
diff -u old2/compiler/mercury_compile.m compiler/mercury_compile.m
--- old2/compiler/mercury_compile.m Thu Feb 26 23:08:08 1998
+++ compiler/mercury_compile.m Mon Mar 2 15:34:37 1998
@@ -149,11 +149,11 @@
% command-line arguments, because it would confuse
% the mapping between module names and file names.
io__progname("mercury_compile", ProgName),
- io__write_string(ProgName),
- io__write_string(": Error in command-line argument `"),
- io__write_string(PathName),
- io__write_string("':\n"),
- io__write_string("arguments may not contain directory names.\n")
+ io__write_strings([
+ ProgName, ": Error in command-line argument `",
+ PathName, "':\n",
+ "arguments may not contain directory names.\n"]),
+ io__set_exit_status(1)
).
:- pred process_module_2(module_name, io__state, io__state).
@@ -402,7 +402,14 @@
"dependencies for module `",
ModuleString, "'.\n",
" Run `mmake ", BaseFileName, ".depend' ",
- "to remake the dependencies.\n"])
+ "to remake the dependencies.\n"]),
+ globals__io_lookup_bool_option(halt_at_warn,
+ Halt),
+ ( { Halt = yes } ->
+ io__set_exit_status(1)
+ ;
+ []
+ )
;
[]
)
diff -u old2/compiler/options.m compiler/options.m
--- old2/compiler/options.m Thu Feb 26 23:08:10 1998
+++ compiler/options.m Mon Mar 2 15:35:40 1998
@@ -1256,7 +1256,6 @@
io__write_string("\t--make-priv-int, --make-private-interface\n"),
io__write_string("\t\tWrite the private interface to `<module>.int0'.\n"),
io__write_string("\t\tThis option should only be used by mmake.\n"),
- io__write_string("\t--make-opt-int, --make-optimization-interface\n"),
io__write_string("\t--make-short-int, --make-short-interface\n"),
io__write_string("\t\tWrite the unqualified short interface to `<module>.int3'.\n"),
io__write_string("\t\tThis option should only be used by mmake.\n"),
diff -u old2/compiler/prog_io.m compiler/prog_io.m
--- old2/compiler/prog_io.m Thu Feb 26 23:08:10 1998
+++ compiler/prog_io.m Mon Mar 2 16:20:39 1998
@@ -455,11 +455,19 @@
% then issue a warning (if warning enabled), and
% insert an implicit `:- module ModuleName' decl.
%
- { term__context_init(SourceFileName, 1, FirstContext) },
- { maybe_add_warning(WarnMissing, MaybeFirstTerm, FirstContext,
- "module should start with a `:- module' declaration",
- [], Messages0) },
-
+ { MaybeFirstItem = ok(_FirstItem, FirstContext0) ->
+ FirstContext = FirstContext0
+ ;
+ term__context_init(SourceFileName, 1, FirstContext)
+ },
+ { WarnMissing = yes ->
+ dummy_term_with_context(FirstContext, FirstTerm),
+ add_warning(
+ "module should start with a `:- module' declaration",
+ FirstTerm, [], Messages0)
+ ;
+ Messages0 = []
+ },
{ ModuleName = DefaultModuleName },
{ make_module_decl(ModuleName, FirstContext, FixedFirstItem) },
diff -u old2/compiler/type_util.m compiler/type_util.m
--- old2/compiler/type_util.m Thu Feb 26 23:08:13 1998
+++ compiler/type_util.m Mon Mar 2 15:52:43 1998
@@ -368,11 +368,16 @@
%-----------------------------------------------------------------------------%
- % the checks for type_info and base_type_info
+ % The checks for type_info and base_type_info
% are needed because those types lie about their
% arity; it might be cleaner to change that in
% mercury_builtin.m, but that would cause some
% bootstrapping difficulties.
+ % It might be slightly better to check for mercury_builtin:type_info
+ % etc. rather than just checking the unqualified type name,
+ % but I found it difficult to verify that the constructors
+ % would always be fully module-qualified at points where
+ % type_is_no_tag_type/3 is called.
type_is_no_tag_type(Ctors, Ctor, Type) :-
Ctors = [Ctor - [_FieldName - Type]],
diff -u old2/doc/reference_manual.texi doc/reference_manual.texi
--- old2/doc/reference_manual.texi Thu Feb 26 23:08:56 1998
+++ doc/reference_manual.texi Mon Mar 2 16:01:14 1998
@@ -2457,9 +2457,9 @@
A @samp{:- interface.} declaration indicates
the start of the module's interface section:
this section specifies the entities that are exported by this module.
-Mercury provides support for abstract data types, since the
-definition of a type may be kept hidden, with only the type
-name being exported.
+Mercury provides support for abstract data types, by allowing the
+definition of a type to be kept hidden, with the interface
+only exporting the type name.
The interface section can contain declarations or definitions of types,
definitions of typeclasses, typeclass instances, data constructors,
instantiation states, and modes,
@@ -2474,11 +2474,11 @@
The implementation section must contain definitions
for all abstract data types, functions, predicates, and
sub-modules exported by the module,
-as well for all local types, functions, predicates, and sub-modules.
+as well as for all local types, functions, predicates, and sub-modules.
The implementation section can be omitted if it is empty.
The module may optionally end with a @samp{:- end_module @var{ModuleName}}
-declaration; the name specified in the @samp{end_module} be the
+declaration; the name specified in the @samp{end_module} must be the
same as that in the corresponding @samp{module} declaration.
@c should we mention multipart interfaces and implementations?
@@ -2488,7 +2488,7 @@
then it must explicitly import those modules using one or more
@samp{:- import_module @var{Modules}} or @samp{:- use_module @var{Modules}}
declarations. In both cases, @var{Modules} is a comma-separated list of
-(fully-qualified) module names.
+fully-qualified module names.
These declarations may occur either in the interface or the implementation
section. If the imported entities are used in the interface section,
then the corresponding @code{import_module} or @code{use_module}
@@ -2613,7 +2613,7 @@
@node Nested sub-modules
@subsection Nested sub-modules
-Nested sub-modules within an module are delimited by
+Nested sub-modules within a module are delimited by
matching @samp{:- module} and @samp{:- end_module} declarations.
(Note that @samp{:- end_module} for nested sub-modules
are mandatory, not optional, even if the nested sub-module
@@ -2637,7 +2637,7 @@
then there is an implicit definition with an empty implementation section
for that sub-module (this will result in an error, if the interface
section includes declarations but not definitions for any types,
-preds, modes, or (doubly) nested sub-modules).
+predicates, modes, or (doubly) nested sub-modules).
@node Separate sub-modules
@subsection Separate sub-modules
@@ -2685,7 +2685,11 @@
However, declarations in a child module are not visible in the parent
module or in "sibling" modules (other children of the same parent)
unless the child is explicitly imported using a @samp{:- import_module}
-or @samp{:- use_module} declaration.
+or @samp{:- use_module} declaration.
+
+Note that as mentioned previously, all @samp{:- import_module} and
+ at samp{:- use_module} declarations must use fully-qualified module
+names.
@node Implementation bugs and limitations
@subsection Implementation bugs and limitations
cvs diff: Diffing .
Index: unused_args_test.exp
===================================================================
RCS file: /home/mercury1/repository/tests/warnings/unused_args_test.exp,v
retrieving revision 1.4
diff -u -u -r1.4 unused_args_test.exp
--- unused_args_test.exp 1997/01/20 03:33:42 1.4
+++ unused_args_test.exp 1998/02/16 06:46:35
@@ -1,4 +1,4 @@
-unused_args_test.m:009: In predicate `unused_args_test:recursive'/3:
+unused_args_test.m:009: In predicate `unused_args_test:recursive/3':
unused_args_test.m:009: warning: argument 1 is unused.
-unused_args_test.m:011: In predicate `unused_args_test:nonrecursive'/1:
+unused_args_test.m:011: In predicate `unused_args_test:nonrecursive/1':
unused_args_test.m:011: warning: argument 1 is unused.
Index: unused_import.exp
===================================================================
RCS file: /home/mercury1/repository/tests/warnings/unused_import.exp,v
retrieving revision 1.3
diff -u -u -r1.3 unused_import.exp
--- unused_import.exp 1997/06/01 19:35:32 1.3
+++ unused_import.exp 1998/02/25 05:16:33
@@ -1,3 +1,4 @@
-unused_import.m:001: Warning: modules `float' and `list'
+unused_import.m:001: In module `unused_import':
+unused_import.m:001: warning: modules `float' and `list'
unused_import.m:001: are imported in the interface, but are not
unused_import.m:001: used in the interface.
cvs diff: Diffing .
Index: Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.12
diff -u -u -r1.12 Mmakefile
--- Mmakefile 1998/02/03 08:01:54 1.12
+++ Mmakefile 1998/03/02 04:25:04
@@ -24,6 +24,7 @@
inline_conflict.m \
io_in_ite_cond.m \
missing_det_decls.m \
+ missing_interface_import.m \
modes_erroneous.m \
mostly_uniq1.m \
mostly_uniq2.m \
@@ -59,6 +60,7 @@
MCFLAGS-multisoln_func = --infer-types
MCFLAGS-any_mode = --infer-types
MCFLAGS-duplicate_modes = --verbose-error-messages
+MCFLAGS-missing_interface_import = --make-interface
DEPS= $(SOURCES:%.m=%.dep)
DEPENDS= $(SOURCES:%.m=%.depend)
Index: errors.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/errors.err_exp,v
retrieving revision 1.3
diff -u -u -r1.3 errors.err_exp
--- errors.err_exp 1997/06/29 23:24:35 1.3
+++ errors.err_exp 1998/03/02 05:18:48
@@ -1,8 +1,8 @@
-errors.m:001: Warning: module should start with a `:- module' declaration.
+errors.m:010: Warning: module should start with a `:- module' declaration.
errors.m:060: Error: free type parameter in RHS of type definition: f(_0).
errors.m:061: Error: free type parameter in RHS of type definition: f(_0).
-errors.m:000: Warning: module `int' is imported using both
-errors.m:000: `:- import_module' and `:- use_module' declarations.
+errors.m:001: Warning: module `int' is imported using both
+errors.m:001: `:- import_module' and `:- use_module' declarations.
errors.m:051: In definition of type `errors:du_type_which_references_undefined_type'/0:
errors.m:051: error: undefined type `undefined_type'/0.
errors.m:053: In definition of type `errors:eqv_type_which_references_undefined_type'/0:
Index: missing_interface_import.err_exp
===================================================================
RCS file: missing_interface_import.err_exp
diff -N missing_interface_import.err_exp
--- /dev/null Mon Mar 2 16:28:13 1998
+++ missing_interface_import.err_exp Mon Mar 2 15:25:31 1998
@@ -0,0 +1,8 @@
+missing_interface_import.m:007: In definition of type `missing_interface_import:bar'/0:
+missing_interface_import.m:007: error: undefined type `tree234'/2.
+missing_interface_import.m:009: In definition of predicate `missing_interface_import:p'/1:
+missing_interface_import.m:009: error: undefined type `std_util:univ'/0.
+missing_interface_import.m:010: In definition of predicate `missing_interface_import:q'/1:
+missing_interface_import.m:010: error: undefined type `list'/1.
+`missing_interface_import.int' not written.
+For more information, try recompiling with `-E'.
Index: missing_interface_import.m
===================================================================
RCS file: missing_interface_import.m
diff -N missing_interface_import.m
--- /dev/null Mon Mar 2 16:28:13 1998
+++ missing_interface_import.m Mon Mar 2 15:26:45 1998
@@ -0,0 +1,20 @@
+% Regression test: the Mercury compiler of Mon Mar 2, 1998
+% failed to report an error for this test case.
+
+:- module missing_interface_import.
+:- interface.
+
+:- type bar == map(int, int).
+
+:- pred p(std_util__univ::in) is det.
+:- pred q(list(int)::in) is det.
+
+:- implementation.
+
+% These import_module and use_module declarations should be in the
+% interface section.
+:- import_module list, map.
+:- use_module std_util.
+
+p(_).
+q(_).
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list