[m-rev.] for review: expand equivalence types fully
Simon Taylor
stayl at cs.mu.OZ.AU
Mon Dec 1 14:06:18 AEDT 2003
On 29-Nov-2003, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 29-Nov-2003, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> >
> > Make definitions of abstract types available when generating
> > code for importing modules. This is necessary for the .NET
> > back-end, and for `:- pragma export' on the C back-end.
>
> > Index: compiler/mercury_to_mercury.m
> ...
> > :- pred mercury_output_begin_type_decl(is_solver_type, io__state, io__state).
> > :- mode mercury_output_begin_type_decl(in, di, uo) is det.
> >
> > -mercury_output_begin_type_decl(solver_type) -->
> > - io__write_string(":- solver type ").
> > -mercury_output_begin_type_decl(non_solver_type) -->
> > - io__write_string(":- type ").
> > +mercury_output_begin_type_decl(IsSolverType) -->
> > + io__write_string(":- "),
> > + ( { IsSolverType = solver_type }, io__write_string("solver ")
> > + ; { IsSolverType = non_solver_type }
> > + ),
> > + io__write_string("type ").
>
> IMHO the original code is considerably easier to read.
Fixed. (This change, and the references to `type_impl' below
were left over from a previous attempt at this change).
> > Index: compiler/module_qual.m
> ...
> > +:- pred add_imports_2(list(sym_name)::in, mq_info::in, mq_info::out) is det.
> > +
> > +add_imports_2(Imports, !Info) :-
> > + mq_info_get_import_status(!.Info, Status),
> > + (
> > + ( Status = local
> > + ; Status = exported
> > + ; Status = imported(ancestor_private_interface)
> > )
> > + ->
> > + mq_info_get_imported_modules(!.Info, Modules0),
> > + set__insert_list(Modules0, Imports, Modules),
> > + mq_info_set_imported_modules(!.Info, Modules, !:Info)
> > ;
> > - Info = Info0
> > - ).
> > + true
> > + ),
> > +
> > + (
> > + Status = exported
> > + ->
> > + mq_info_get_unused_interface_modules(!.Info,
> > + UnusedIntModules0),
> > + set__insert_list(UnusedIntModules0, Imports, UnusedIntModules),
> > + mq_info_set_unused_interface_modules(!.Info,
> > + UnusedIntModules, !:Info)
> > + ;
> > + true
> > + ),
> > +
> > + (
> > + ( Status = exported
> > + ; Status = imported(ancestor_private_interface)
> > + )
> > + ->
> > + mq_info_get_interface_visible_modules(!.Info, IntModules0),
> > + set__insert_list(IntModules0, Imports, IntModules),
> > + mq_info_set_interface_visible_modules(!.Info,
> > + IntModules, !:Info)
> > + ;
> > + true
> > + ).
>
> Some comments there would be helpful.
Done.
> > @@ -513,13 +585,16 @@
> > module_qualify_item(clause(A,B,C,D,E) - Con, clause(A,B,C,D,E) - Con,
> > Info, Info, yes) --> [].
> >
> > -module_qualify_item(type_defn(A, SymName, Params, TypeDefn0, C) - Context,
> > - type_defn(A, SymName, Params, TypeDefn, C) - Context,
> > +module_qualify_item(
> > + type_defn(TVarSet, SymName, Params, TypeDefn0, C) - Context,
> > + type_defn(TVarSet, SymName, Params, TypeDefn, C) - Context,
> > Info0, Info, yes) -->
> > + { mq_info_get_types(Info0, Types0) },
> > { list__length(Params, Arity) },
> > { mq_info_set_error_context(Info0,
> > type(SymName - Arity) - Context, Info1) },
> > - qualify_type_defn(TypeDefn0, TypeDefn, Info1, Info).
> > + qualify_type_defn(TypeDefn0, TypeDefn, Info1, Info2),
> > + { mq_info_set_types(Info2, Types0, Info) }.
>
> I don't understand why you reset the types field to its old value there.
> A comment might help.
Fixed (it wasn't necessary).
> > @@ -1226,6 +1314,28 @@
> > mercury_output_bracketed_sym_name(ModuleName),
> > io__write_string("' has not been imported).\n")
> > ;
> > + { MatchingModules = [_ | MatchingModules1] }
> > + ->
> > + { MatchingModules1 = [],
> > + ModuleWord = "module ",
> > + HasWord = "has"
> > + ; MatchingModules1 = [_|_],
> > + ModuleWord = "modules ",
> > + HasWord = "have"
> > + },
> > +
> > + io__write_string("\n"),
> > + prog_out__write_context(Context),
> > + io__write_string(" (the "),
> > + io__write_string(ModuleWord),
> > + io__write_string(" "),
> > + prog_out__write_module_list(MatchingModules),
> > + io__nl,
> > + prog_out__write_context(Context),
> > + io__write_string(" "),
> > + io__write_string(HasWord),
> > + io__write_string(" not been imported in the interface).\n")
> > + ;
>
> That looks like it outputs two spaces after "module" or "modules",
> but I think it should only output one.
>
> There should be a test case for both variations (singular and plural)
> of this new error message.
Done.
> > Index: compiler/module_qual.m
> > @@ -1418,6 +1528,10 @@
> > set__init(InterfaceModules0),
> > get_implicit_dependencies(Items, Globals, ImportDeps, UseDeps),
> > set__list_to_set(ImportDeps `list__append` UseDeps, ImportedModules),
> > + set__insert_list(ImportedModules,
> > + [ModuleName | get_ancestors(ModuleName)],
> > + InterfaceVisibleModules),
>
> Why do the ancestor modules need to get included in InterfaceVisibleModules
> here?
Because they are visible without an explicit import.
> > Index: compiler/modules.m
> > @@ -520,60 +523,114 @@
> > item_list, module_imports, module_error, io__state, io__state).
> > :- mode grab_unqual_imported_modules(in, in, in, in, out, out, di, uo) is det.
> >
> > - % process_module_private_interfaces(Ancestors, DirectImports0,
> > - % DirectImports, DirectUses0, DirectUses,
> > - % Module0, Module):
> > + % process_module_private_interfaces(Ancestors,
> > + % IntStatusItem, ImpStatusItem, DirectImports0, DirectImports,
> > + % DirectUses0, DirectUses, Module0, Module):
>
> I suggest using state var notation here, i.e.
Done.
> % process_module_private_interfaces(Ancestors,
> % IntStatusItem, ImpStatusItem, !DirectImports, !DirectUses,
> % !Module):
>
> > @@ -1422,6 +1484,139 @@
> > +:- pred strip_unnecessary_impl_defns(item_list::in, item_list::out) is det.
> > +
> > +strip_unnecessary_impl_defns(Items0,
> > + promise_only_solution(strip_unnecessary_impl_defns_2(Items0))).
>
> There should be a comment explaining why that promise is safe.
Done.
> > @@ -1782,7 +1979,7 @@
> >
> > update_interface_create_file(Msg, OutputFileName,
> > TmpOutputFileName, Succeeded) -->
> > - globals__io_lookup_bool_option(verbose, Verbose),
> > + globals__io_lookup_bool_option(verbose_make, Verbose),
>
> I don't think that was mentioned in the log message.
> It appears to be unrelated to the rest of your changes
> and hence ideally should be committed separately (if at all).
Undone.
> > @@ -6509,6 +6839,43 @@
> > include_in_short_interface(module_defn(_, _)).
> > include_in_short_interface(instance(_, _, _, _, _, _)).
> >
> > +:- func item_needs_imports(item) = bool.
>
> A comment explaining the meaning of this function would be helpful.
Done.
> > +:- pred include_in_int_file_implementation(item).
> > +:- mode include_in_int_file_implementation(in) is semidet.
> > +
> > +include_in_int_file_implementation(type_defn(_, _, _, _, _)).
> > +include_in_int_file_implementation(module_defn(_, Defn)) :-
> > + Defn \= external(_).
> > +include_in_int_file_implementation(typeclass(_, _, _, _, _)).
>
> It would be nice to put a comment explaining why typeclass declarations
> need to be included, but instance declarations don't.
Done.
> > +++ compiler/prog_data.m 26 Nov 2003 08:46:41 -0000
> > @@ -56,8 +56,15 @@
> > cl_body :: goal
> > )
> >
> > - % `:- type ...':
> > + % `:- type ...' or `:- type_impl':
> > % a definition of a type, or a declaration of an abstract type.
> > + % The compiler places `:- type_impl' declarations in `.int'
> > + % and `.int2' files to propagate definitions of abstract
> > + % foreign types and equivalence types which should not be
> > + % visible to importing modules (and shouldn't be used when
> > + % typechecking those modules), but which are necessary for
> > + % code generation. For examples the MS Common Language Runtime
> > + % doesn't support equivalence types.
> > ; type_defn(
>
> Is the comment about ":- type_impl" correct?
> It doesn't match the description in the log message.
Fixed.
> > @@ -1234,6 +1233,11 @@
> > % `:- use_module', and items from `.opt'
> > % and `.int2' files. It also records from which
> > % section the module was imported.
> > + ; abstract_imported
> > + % This is used internally by the compiler,
> > + % to identify items which originally
> > + % came from the implementation section
> > + % of an interface file.
>
> It would be good to just mention here what implementation sections
> in interface files are for.
Done.
> > ; opt_imported
> > % This is used internally by the compiler,
> > % to identify items which originally
> > @@ -1270,7 +1274,8 @@
> > :- type import_locn
> > ---> implementation
> > ; interface
> > - ; ancestor.
> > + ; ancestor
> > + ; ancestor_private_interface.
>
> It would be helpful to have a comment here explaining what that new
> alternative means.
Done.
> > Index: compiler/recompilation.usage.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/compiler/recompilation.usage.m,v
> > retrieving revision 1.10
> > diff -u -u -r1.10 recompilation.usage.m
> > --- compiler/recompilation.usage.m 24 Oct 2003 06:17:47 -0000 1.10
> > +++ compiler/recompilation.usage.m 26 Nov 2003 04:45:01 -0000
> > @@ -79,6 +79,7 @@
> > %-----------------------------------------------------------------------------%
> > :- implementation.
> >
> > +:- import_module check_hlds.
> > :- import_module check_hlds__type_util.
> > :- import_module hlds__hlds_data.
> > :- import_module hlds__hlds_out.
>
> IMHO that declaration should go in recompilation.m
> rather than here and in recompilation.version.m.
Done.
> > +++ compiler/notes/compiler_design.html 24 Nov 2003 14:33:23 -0000
> > @@ -689,6 +689,20 @@
> >
> > (Is there any good reason why lambda.m comes after table_gen.m?)
> >
> > +
> > +<p>
> > +
> > +Expansion of equivalence types (equiv_type_hlds.m)
> > +
> > +<ul>
> > +<li>
> > + This pass expands equivalences which are not meant to
> > + be visible to the user of imported modules. This
> > + is necessary for the IL back-end and in some cases
> > + for `:- pragma export' involving foreign types on
> > + the C back-end.
> > +</ul>
>
> It's also needed by the MLDS->C back-end, for either --high-level-data,
> or for cases involving abstract equivalence types which are defined
> as "float".
Done.
> > @@ -104,17 +104,29 @@
> > :- mode multi_map__values(in, out) is det.
> >
> > % convert a multi_map to an association list
> > -:- pred multi_map__to_assoc_list(multi_map(K,V), assoc_list(K,list(V))).
> > +:- pred multi_map__to_assoc_list(multi_map(K,V), assoc_list(K, V)).
> > :- mode multi_map__to_assoc_list(in, out) is det.
>
> I don't think that this is worth breaking backwards compatibility for.
> The new predicate could be named e.g. multi_map__to_flat_assoc_list.
> If you think the old name is confusing, you could rename it and keep
> a version with the original name but use pragma obsolete to deprecate it.
See the separate change I posted and committed.
> > +++ tests/hard_coded/Mercury.options 28 Nov 2003 12:24:05 -0000
> > @@ -4,6 +4,7 @@
> > MCFLAGS-constraint = --constraint-propagation --enable-termination
> > MCFLAGS-constraint_order = --constraint-propagation --enable-termination
> > MCFLAGS-deforest_cc_bug = --deforestation
> > +MCFLAGS-export_test2 = --no-intermodule-optimization
>
> Is that needed? The test will normally run without intermodule optimization
> anyway. Is there anything wrong with also testing it with intermodule
> optimization occaisionally?
OK.
> > +++ tests/invalid/missing_interface_import.err_exp 25 Nov 2003 15:48:55 -0000
> > @@ -1,9 +1,14 @@
> > missing_interface_import.m:007: In definition of type `missing_interface_import.bar'/0:
> > -missing_interface_import.m:007: error: undefined type `map'/2.
> > +missing_interface_import.m:007: error: undefined type `map'/2
> > +missing_interface_import.m:007: (the module `map'
> > +missing_interface_import.m:007: has not been imported in the interface).
>
> s/module `map'/module `map'/
Fixed.
> > 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:009: (the module `std_util' has not been imported).
> > +missing_interface_import.m:009: (the module `std_util'
> > +missing_interface_import.m:009: has not been imported in the interface).
>
> Why is there a line wrap before the "has not been ..."?
> Is that deliberate, or accidental?
Fixed.
Simon.
reverted:
--- NEWS 28 Nov 2003 10:55:39 -0000
+++ NEWS 31 Oct 2003 03:27:13 -0000 1.320
@@ -55,11 +55,6 @@
* exception.m now contains a predicate finally/6 which can be used to
ensure that resources are released whether a called closure exits
normally or throws an exception.
-* The behaviour of multi_map__to_assoc_list and multi_map.from_assoc_list
- has changed to use assoc_lists where each key-value in the multi_map
- has an entry in the assoc_list, rather than just and entry for each key.
- The old behaviour is available using multi_map.to_multi_assoc_list
- and multi_map.from_multi_assoc_list.
Portability improvements:
* Nothing yet.
@@ -149,12 +144,6 @@
* exception.m now contains a predicate finally/6 which can be used to
ensure that resources are released whether a called closure exits
normally or throws an exception.
-
-* The behaviour of multi_map__to_assoc_list and multi_map.from_assoc_list
- has changed to use assoc_lists where each key-value in the multi_map
- has an entry in the assoc_list, rather than just and entry for each key.
- The old behaviour is available using multi_map.to_multi_assoc_list
- and multi_map.from_multi_assoc_list.
* Several new functions have been added to the string module, namely
elem/2, unsafe_elem/2, chomp/1, lstrip/1, lstrip/2, rstrip/1, rstrip/2,
diff -u compiler/hlds_out.m compiler/hlds_out.m
--- compiler/hlds_out.m
+++ compiler/hlds_out.m
@@ -3192,8 +3192,7 @@
hlds_out__write_superclasses(Indent, SuperClassTable) -->
hlds_out__write_indent(Indent),
io__write_string("%-------- Super Classes --------\n"),
- { multi_map__to_multi_assoc_list(SuperClassTable,
- SuperClassTableList) },
+ { multi_map__to_assoc_list(SuperClassTable, SuperClassTableList) },
io__write_list(SuperClassTableList, "\n\n",
hlds_out__write_superclass(Indent)),
io__nl.
diff -u compiler/mercury_to_mercury.m compiler/mercury_to_mercury.m
--- compiler/mercury_to_mercury.m
+++ compiler/mercury_to_mercury.m
@@ -1756,12 +1756,10 @@
:- pred mercury_output_begin_type_decl(is_solver_type, io__state, io__state).
:- mode mercury_output_begin_type_decl(in, di, uo) is det.
-mercury_output_begin_type_decl(IsSolverType) -->
- io__write_string(":- "),
- ( { IsSolverType = solver_type }, io__write_string("solver ")
- ; { IsSolverType = non_solver_type }
- ),
- io__write_string("type ").
+mercury_output_begin_type_decl(solver_type) -->
+ io__write_string(":- solver type ").
+mercury_output_begin_type_decl(non_solver_type) -->
+ io__write_string(":- type ").
:- pred mercury_output_equality_compare_preds(maybe(unify_compare)::in,
io__state::di, io__state::uo) is det.
diff -u compiler/module_qual.m compiler/module_qual.m
--- compiler/module_qual.m
+++ compiler/module_qual.m
@@ -396,6 +396,12 @@
add_imports_2(Imports, !Info) :-
mq_info_get_import_status(!.Info, Status),
+
+ %
+ % Modules imported from the the private interface of ancestors of
+ % the current module are treated as if they were directly imported
+ % by the current module.
+ %
(
( Status = local
; Status = exported
@@ -409,6 +415,10 @@
true
),
+ %
+ % We check that all modules imported in the interface are
+ % used in the interface.
+ %
(
Status = exported
->
@@ -421,6 +431,10 @@
true
),
+ %
+ % Only modules imported in the interface or in the private
+ % interface of ancestor modules may be used in the interface.
+ %
(
( Status = exported
; Status = imported(ancestor_private_interface)
@@ -589,12 +603,10 @@
type_defn(TVarSet, SymName, Params, TypeDefn0, C) - Context,
type_defn(TVarSet, SymName, Params, TypeDefn, C) - Context,
Info0, Info, yes) -->
- { mq_info_get_types(Info0, Types0) },
{ list__length(Params, Arity) },
{ mq_info_set_error_context(Info0,
type(SymName - Arity) - Context, Info1) },
- qualify_type_defn(TypeDefn0, TypeDefn, Info1, Info2),
- { mq_info_set_types(Info2, Types0, Info) }.
+ qualify_type_defn(TypeDefn0, TypeDefn, Info1, Info).
module_qualify_item(inst_defn(A, SymName, Params, InstDefn0, C) - Context,
inst_defn(A, SymName, Params, InstDefn, C) - Context,
@@ -1318,21 +1330,17 @@
->
{ MatchingModules1 = [],
ModuleWord = "module ",
- HasWord = "has"
+ HasWord = " has"
; MatchingModules1 = [_|_],
ModuleWord = "modules ",
- HasWord = "have"
+ HasWord = " have"
},
io__write_string("\n"),
prog_out__write_context(Context),
io__write_string(" (the "),
io__write_string(ModuleWord),
- io__write_string(" "),
prog_out__write_module_list(MatchingModules),
- io__nl,
- prog_out__write_context(Context),
- io__write_string(" "),
io__write_string(HasWord),
io__write_string(" not been imported in the interface).\n")
;
@@ -1528,6 +1536,8 @@
set__init(InterfaceModules0),
get_implicit_dependencies(Items, Globals, ImportDeps, UseDeps),
set__list_to_set(ImportDeps `list__append` UseDeps, ImportedModules),
+
+ % Ancestor modules are visible without being explicitly imported.
set__insert_list(ImportedModules,
[ModuleName | get_ancestors(ModuleName)],
InterfaceVisibleModules),
diff -u compiler/modules.m compiler/modules.m
--- compiler/modules.m
+++ compiler/modules.m
@@ -524,8 +524,8 @@
:- mode grab_unqual_imported_modules(in, in, in, in, out, out, di, uo) is det.
% process_module_private_interfaces(Ancestors,
- % IntStatusItem, ImpStatusItem, DirectImports0, DirectImports,
- % DirectUses0, DirectUses, Module0, Module):
+ % IntStatusItem, ImpStatusItem, !DirectImports,
+ % !DirectUses, !Module):
%
% Read the complete private interfaces for modules in Ancestors,
% and append any imports/uses in the ancestors to the
@@ -1489,6 +1489,9 @@
:- pred strip_unnecessary_impl_defns(item_list::in, item_list::out) is det.
strip_unnecessary_impl_defns(Items0,
+ % strip_unnecessary_impl_defns_2 is cc_multi because of the
+ % call to std_util.unsorted_aggregate. The order in which
+ % items are deleted from a multi_map does not matter.
promise_only_solution(strip_unnecessary_impl_defns_2(Items0))).
:- pred strip_unnecessary_impl_defns_2(item_list::in,
@@ -1979,7 +1982,7 @@
update_interface_create_file(Msg, OutputFileName,
TmpOutputFileName, Succeeded) -->
- globals__io_lookup_bool_option(verbose_make, Verbose),
+ globals__io_lookup_bool_option(verbose, Verbose),
maybe_write_string(Verbose, "% `"),
maybe_write_string(Verbose, OutputFileName),
maybe_write_string(Verbose, "' has "),
@@ -6839,6 +6842,7 @@
include_in_short_interface(module_defn(_, _)).
include_in_short_interface(instance(_, _, _, _, _, _)).
+ % Could this item use items from imported modules.
:- func item_needs_imports(item) = bool.
item_needs_imports(clause(_, _, _, _, _)) = yes.
@@ -6874,6 +6878,11 @@
include_in_int_file_implementation(type_defn(_, _, _, _, _)).
include_in_int_file_implementation(module_defn(_, Defn)) :-
Defn \= external(_).
+
+ % `:- typeclass declarations' may be referred to
+ % by the constructors in type declarations.
+ % Since these constructors are abstractly exported,
+ % we won't need the local instance declarations.
include_in_int_file_implementation(typeclass(_, _, _, _, _)).
:- pred make_abstract_defn(item, short_interface_kind, item).
diff -u compiler/prog_data.m compiler/prog_data.m
--- compiler/prog_data.m
+++ compiler/prog_data.m
@@ -56,15 +56,8 @@
cl_body :: goal
)
- % `:- type ...' or `:- type_impl':
+ % `:- type ...':
% a definition of a type, or a declaration of an abstract type.
- % The compiler places `:- type_impl' declarations in `.int'
- % and `.int2' files to propagate definitions of abstract
- % foreign types and equivalence types which should not be
- % visible to importing modules (and shouldn't be used when
- % typechecking those modules), but which are necessary for
- % code generation. For examples the MS Common Language Runtime
- % doesn't support equivalence types.
; type_defn(
td_tvarset :: tvarset,
td_ctor_name :: sym_name,
@@ -1237,7 +1230,10 @@
% This is used internally by the compiler,
% to identify items which originally
% came from the implementation section
- % of an interface file.
+ % of an interface file; usually type
+ % declarations (especially equivalence types)
+ % which should be used in code generation
+ % but not in type checking.
; opt_imported
% This is used internally by the compiler,
% to identify items which originally
@@ -1271,11 +1267,22 @@
---> implementation
; interface.
+ % An import_locn is used to describe the place where an item was
+ % imported from.
:- type import_locn
- ---> implementation
+ --->
+ % The item is from a module imported in the implementation.
+ implementation
+
+ % The item is from a module imported in the interface.
; interface
+
+ % The item is from a module imported by an ancestor.
; ancestor
- ; ancestor_private_interface.
+
+ % The item is from the private interface of an ancestor module.
+ ; ancestor_private_interface
+ .
:- type sym_list
---> sym(list(sym_specifier))
reverted:
--- compiler/recompilation.usage.m 26 Nov 2003 04:45:01 -0000
+++ compiler/recompilation.usage.m 24 Oct 2003 06:17:47 -0000 1.10
@@ -79,7 +79,6 @@
%-----------------------------------------------------------------------------%
:- implementation.
-:- import_module check_hlds.
:- import_module check_hlds__type_util.
:- import_module hlds__hlds_data.
:- import_module hlds__hlds_out.
diff -u compiler/recompilation.version.m compiler/recompilation.version.m
--- compiler/recompilation.version.m
+++ compiler/recompilation.version.m
@@ -36,7 +36,6 @@
%-----------------------------------------------------------------------------%
:- implementation.
-:- import_module check_hlds.
:- import_module check_hlds__mode_util.
:- import_module check_hlds__type_util.
:- import_module hlds__hlds_out.
diff -u compiler/notes/compiler_design.html compiler/notes/compiler_design.html
--- compiler/notes/compiler_design.html
+++ compiler/notes/compiler_design.html
@@ -701,6 +701,12 @@
is necessary for the IL back-end and in some cases
for `:- pragma export' involving foreign types on
the C back-end.
+
+ <p>
+
+ It's also needed by the MLDS->C back-end, for
+ --high-level-data, and for cases involving abstract
+ equivalence types which are defined as "float".
</ul>
<p>
reverted:
--- library/multi_map.m 24 Nov 2003 14:33:23 -0000
+++ library/multi_map.m 26 May 2003 09:00:30 -0000 1.10
@@ -104,29 +104,17 @@
:- mode multi_map__values(in, out) is det.
% convert a multi_map to an association list
+:- pred multi_map__to_assoc_list(multi_map(K,V), assoc_list(K,list(V))).
-:- pred multi_map__to_assoc_list(multi_map(K,V), assoc_list(K, V)).
:- mode multi_map__to_assoc_list(in, out) is det.
% convert an association list to a multi_map
+:- pred multi_map__from_assoc_list(assoc_list(K,list(V)), multi_map(K,V)).
-:- pred multi_map__from_assoc_list(assoc_list(K, V), multi_map(K,V)).
:- mode multi_map__from_assoc_list(in, out) is det.
- % convert a multi_map to an association list, with all the
- % values for each key in one element of the association list.
-:- pred multi_map__to_multi_assoc_list(multi_map(K, V),
- assoc_list(K, list(V))).
-:- mode multi_map__to_multi_assoc_list(in, out) is det.
-
- % convert an association list with all the values for each
- % key in one element of the list to a multi_map
-:- pred multi_map__from_multi_assoc_list(assoc_list(K, list(V)),
- multi_map(K,V)).
-:- mode multi_map__from_multi_assoc_list(in, out) is det.
-
% convert a sorted association list to a multi_map
+:- pred multi_map__from_sorted_assoc_list(assoc_list(K, list(V)),
+ multi_map(K, V)).
+:- mode multi_map__from_sorted_assoc_list(in, out) is det.
-:- pred multi_map__from_sorted_multi_assoc_list(assoc_list(K, list(V)),
- multi_map(K, V)).
-:- mode multi_map__from_sorted_multi_assoc_list(in, out) is det.
% delete a key and data from a multi_map
% if the key is not present, leave the multi_map unchanged
@@ -264,31 +252,15 @@
map__values(MultiMap, KeyList0),
list__condense(KeyList0, KeyList).
-multi_map__from_assoc_list(AList, MultiMap) :-
- MultiMap = list__foldl(
- (func(Key - Value, Map0) = Map :-
- multi_map__set(Map0, Key, Value, Map)
- ),
- AList, map__init).
-
multi_map__to_assoc_list(MultiMap, AList) :-
+ map__to_assoc_list(MultiMap, AList).
- AList = list__reverse(map__foldl(
- (func(Key, Values, AL) =
- list__reverse(
- list__map((func(Value) = Key - Value), Values)
- ) ++ AL
- ),
- MultiMap, [])).
+multi_map__from_assoc_list(AList, MultiMap) :-
-multi_map__from_multi_assoc_list(AList, MultiMap) :-
map__from_assoc_list(AList, MultiMap).
+multi_map__from_sorted_assoc_list(AList, MultiMap) :-
-multi_map__from_sorted_multi_assoc_list(AList, MultiMap) :-
map__from_sorted_assoc_list(AList, MultiMap).
-multi_map__to_multi_assoc_list(MultiMap, AList) :-
- map__to_assoc_list(MultiMap, AList).
-
multi_map__delete(MultiMap0, Key, MultiMap) :-
map__delete(MultiMap0, Key, MultiMap).
@@ -334,8 +306,18 @@
% XXX inefficient
multi_map__inverse_search(MultiMap, Value, Key) :-
+ map__to_assoc_list(MultiMap, AssocList),
+ multi_map__assoc_list_member(Value, AssocList, Key).
+
+:- pred multi_map__assoc_list_member(Value, assoc_list(Key, list(Value)), Key).
+:- mode multi_map__assoc_list_member(in, in, out) is nondet.
+multi_map__assoc_list_member(Value, [(AKey - AValues) | AList], Key) :-
+ (
+ list__member(Value, AValues),
+ Key = AKey
+ ;
+ multi_map__assoc_list_member(Value, AList, Key)
+ ).
- map__member(MultiMap, Key, ValueList),
- list__member(Value, ValueList).
%-----------------------------------------------------------------------------%
@@ -368,10 +350,10 @@
%-----------------------------------------------------------------------------%
multi_map__merge(M0, M1, M) :-
+ multi_map__to_assoc_list(M0, ML0),
+ multi_map__to_assoc_list(M1, ML1),
- multi_map__to_multi_assoc_list(M0, ML0),
- multi_map__to_multi_assoc_list(M1, ML1),
multi_map__assoc_list_merge(ML0, ML1, ML),
+ multi_map__from_sorted_assoc_list(ML, M).
- multi_map__from_sorted_multi_assoc_list(ML, M).
:- pred multi_map__assoc_list_merge(assoc_list(K, list(V)),
assoc_list(K, list(V)), assoc_list(K, list(V))).
reverted:
--- tests/hard_coded/Mercury.options 28 Nov 2003 12:24:05 -0000
+++ tests/hard_coded/Mercury.options 22 Jul 2003 07:04:26 -0000 1.7
@@ -4,7 +4,6 @@
MCFLAGS-constraint = --constraint-propagation --enable-termination
MCFLAGS-constraint_order = --constraint-propagation --enable-termination
MCFLAGS-deforest_cc_bug = --deforestation
-MCFLAGS-export_test2 = --no-intermodule-optimization
MCFLAGS-lp = --intermodule-optimization -O3
MCFLAGS-boyer = --infer-all
MCFLAGS-float_consistency = --optimize-constant-propagation
diff -u tests/hard_coded/export_test2.exp tests/invalid/missing_interface_import3.m
--- tests/hard_coded/export_test2.exp
+++ tests/invalid/missing_interface_import3.m
@@ -1 +1,4 @@
-42
+:- module missing_interface_import3.
+:- interface.
+
+:- type key == int.
diff -u tests/hard_coded/export_test2.m tests/invalid/missing_interface_import3.m
--- tests/hard_coded/export_test2.m
+++ tests/invalid/missing_interface_import3.m
@@ -1,50 +1,4 @@
-:- module export_test2.
-
+:- module missing_interface_import3.
:- interface.
-:- import_module int, io.
-
-:- pred main(io__state::di, io__state::uo) is det.
-
-:- pred foo(io__output_stream::in, io__output_stream::out,
- int::in, int::out) is det.
-
-:- pred bar(io__output_stream::in, io__output_stream::out,
- int::in, int::out) is det.
-
-
-:- implementation.
-
-main -->
- io__stdout_stream(Stream0),
- { bar(Stream0, Stream, 41, X) },
- io__write(Stream, X),
- io__write_char(Stream, '\n').
-
-foo(S, S, X, X+1).
-
-:- pragma foreign_decl("C",
-"#include ""mercury_library_types.h""
-
-/*
-** Make sure the foreign type definition of io__input_stream
-** is available here. If it is not, the automatically generated
-** definition of foo() will be
-** void foo(MR_Word, MR_Word *, MR_Integer, MR_Integer *);
-*/
-void foo(MercuryFilePtr, MercuryFilePtr *, MR_Integer, MR_Integer *);
-
-").
-
-
-:- pragma export(foo(in, out, in, out), "foo").
-
-:- pragma foreign_proc("C", bar(S::in, T::out, X::in, Y::out),
- [may_call_mercury, promise_pure],
-"
- foo(S, &T, X, &Y);
-").
-:- pragma foreign_proc("C#", bar(S::in, T::out, X::in, Y::out),
- [may_call_mercury, promise_pure], "
- export_test2.mercury_code.foo(S, ref T, X, ref Y);
-").
+:- type key == int.
diff -u tests/invalid/Mmakefile tests/invalid/Mmakefile
--- tests/invalid/Mmakefile
+++ tests/invalid/Mmakefile
@@ -21,6 +21,7 @@
ho_default_func_2.sub \
import_in_parent \
imported_mode \
+ missing_interface_import2 \
missing_parent_import \
partial_implied_mode \
sub_c \
@@ -87,7 +88,6 @@
method_impl \
missing_det_decls \
missing_interface_import \
- missing_interface_import2 \
mode_inf \
modes_erroneous \
mostly_uniq1 \
diff -u tests/invalid/missing_interface_import2.err_exp tests/invalid/missing_interface_import3.m
--- tests/invalid/missing_interface_import2.err_exp
+++ tests/invalid/missing_interface_import3.m
@@ -1,10 +1,4 @@
-missing_interface_import2.m:007: In definition of predicate `missing_interface_import2.main'/2:
-missing_interface_import2.m:007: error: undefined type `io.state'/0
-missing_interface_import2.m:007: (the module `io'
-missing_interface_import2.m:007: has not been imported in the interface).
-missing_interface_import2.m:007: In definition of predicate `missing_interface_import2.main'/2:
-missing_interface_import2.m:007: error: undefined type `io.state'/0
-missing_interface_import2.m:007: (the module `io'
-missing_interface_import2.m:007: has not been imported in the interface).
-`missing_interface_import2.int' not written.
-For more information, try recompiling with `-E'.
+:- module missing_interface_import3.
+:- interface.
+
+:- type key == int.
diff -u tests/invalid/missing_interface_import2.err_exp2 tests/invalid/missing_interface_import3.m
--- tests/invalid/missing_interface_import2.err_exp2
+++ tests/invalid/missing_interface_import3.m
@@ -1,10 +1,4 @@
-missing_interface_import2.m:007: In definition of predicate `missing_interface_import2.main'/2:
-missing_interface_import2.m:007: error: undefined type `io.state'/0
-missing_interface_import2.m:007: (the module `io'
-missing_interface_import2.m:007: has not been imported in the interface).
-missing_interface_import2.m:007: In definition of predicate `missing_interface_import2.main'/2:
-missing_interface_import2.m:007: error: undefined type `io.state'/0
-missing_interface_import2.m:007: (the module `io'
-missing_interface_import2.m:007: has not been imported in the interface).
-`Mercury/ints/missing_interface_import2.int' not written.
-For more information, try recompiling with `-E'.
+:- module missing_interface_import3.
+:- interface.
+
+:- type key == int.
diff -u tests/invalid/missing_interface_import2.m tests/invalid/missing_interface_import3.m
--- tests/invalid/missing_interface_import2.m
+++ tests/invalid/missing_interface_import3.m
@@ -1,11 +1,4 @@
-:- module missing_interface_import2.
-
-:- import_module io.
-
+:- module missing_interface_import3.
:- interface.
-:- pred main(io__state::di, io__state::uo) is det.
-
-main -->
- io__write_string("ok\n").
-
+:- type key == int.
only in patch2:
--- compiler/recompilation.m 15 Mar 2003 03:09:08 -0000 1.7
+++ compiler/recompilation.m 30 Nov 2003 11:36:25 -0000
@@ -24,6 +24,7 @@
:- interface.
+:- import_module check_hlds.
:- import_module hlds.
:- import_module libs.
:- import_module parse_tree.
--------------------------------------------------------------------------
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