diff: Mmake support for nested modules
Fergus Henderson
fjh at cs.mu.OZ.AU
Wed May 27 12:53:00 AEST 1998
Add Mmake support for nested sub-modules.
compiler/mercury_compile.m:
compiler/modules.m:
compiler/intermod.m:
Pass down the source file name to various places.
Store the source file name in the module_imports data structure.
In various places, use this source file name instead of assuming
that the source file name can be obtained from the module name.
compiler/modules.m:
Change the generated .d and .dep files to use the source file names.
Add hard-coded rules in the .d files if the source file name does not
match the form expected by the pattern rules in scripts/Mmake.rules.
XXX unfortunately the rules don't work right for parallel makes of
nested modules
scripts/Mmake.rules:
Add a comment saying that any changes here might need to
be duplicated in compiler/modules.m.
tests/hard_coded/Mmakefile:
tests/hard_coded/nested.m:
tests/hard_coded/nested2.m:
tests/hard_coded/nested.exp:
tests/hard_coded/nested2.exp:
Add a couple of test cases for nested modules (XXX not enabled,
due to the above-mentioned problem with parallel makes).
doc/reference_manual.texi:
Update the "implementation bugs and limitations" section.
NEWS:
Update the news about nested modules.
cvs diff -N compiler/intermod.m compiler/mercury_compile.m compiler/modules.m scripts/Mmake.rules tests/hard_coded/Mmakefile tests/hard_coded/nested.exp tests/hard_coded/nested.m tests/hard_coded/nested2.exp tests/hard_coded/nested2.m
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.51
diff -u -r1.51 intermod.m
--- intermod.m 1998/05/15 07:07:13 1.51
+++ intermod.m 1998/05/26 22:04:43
@@ -1283,7 +1283,7 @@
%
% Read in the .opt files for imported and ancestor modules.
%
- { Module0 = module_imports(ModuleName, Ancestors0, InterfaceDeps0,
+ { Module0 = module_imports(_, ModuleName, Ancestors0, InterfaceDeps0,
ImplementationDeps0, _, _, _, _, _) },
{ list__condense([Ancestors0, InterfaceDeps0, ImplementationDeps0],
OptFiles) },
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.91
diff -u -r1.91 mercury_compile.m
--- mercury_compile.m 1998/05/26 20:31:19 1.91
+++ mercury_compile.m 1998/05/26 22:53:41
@@ -198,7 +198,7 @@
{ ModulesToLink = [] }
; { MakeInterface = yes } ->
{ split_into_submodules(ModuleName, Items0, SubModuleList) },
- list__foldl(make_interface, SubModuleList),
+ list__foldl(make_interface(FileName), SubModuleList),
{ ModulesToLink = [] }
; { MakeShortInterface = yes } ->
{ split_into_submodules(ModuleName, Items0, SubModuleList) },
@@ -206,7 +206,7 @@
{ ModulesToLink = [] }
; { MakePrivateInterface = yes } ->
{ split_into_submodules(ModuleName, Items0, SubModuleList) },
- list__foldl(make_private_interface, SubModuleList),
+ list__foldl(make_private_interface(FileName), SubModuleList),
{ ModulesToLink = [] }
; { ConvertToMercury = yes } ->
module_name_to_file_name(ModuleName, ".ugly", yes,
@@ -218,7 +218,7 @@
{ ModulesToLink = [] }
;
{ split_into_submodules(ModuleName, Items0, SubModuleList) },
- list__foldl(compile, SubModuleList),
+ list__foldl(compile(FileName), SubModuleList),
list__map_foldl(module_to_link, SubModuleList, ModulesToLink)
% XXX it would be better to do something like
@@ -231,25 +231,26 @@
% i.e. compile nested modules to a single C file.
).
-:- pred make_interface(pair(module_name, item_list), io__state, io__state).
-:- mode make_interface(in, di, uo) is det.
+:- pred make_interface(file_name, pair(module_name, item_list),
+ io__state, io__state).
+:- mode make_interface(in, in, di, uo) is det.
-make_interface(Module - Items) -->
- make_interface(Module, Items).
+make_interface(SourceFileName, ModuleName - Items) -->
+ make_interface(SourceFileName, ModuleName, Items).
:- pred make_short_interface(pair(module_name, item_list),
io__state, io__state).
:- mode make_short_interface(in, di, uo) is det.
-make_short_interface(Module - Items) -->
- make_short_interface(Module, Items).
+make_short_interface(ModuleName - Items) -->
+ make_short_interface(ModuleName, Items).
-:- pred make_private_interface(pair(module_name, item_list),
+:- pred make_private_interface(file_name, pair(module_name, item_list),
io__state, io__state).
-:- mode make_private_interface(in, di, uo) is det.
+:- mode make_private_interface(in, in, di, uo) is det.
-make_private_interface(Module - Items) -->
- make_private_interface(Module, Items).
+make_private_interface(SourceFileName, ModuleName - Items) -->
+ make_private_interface(SourceFileName, ModuleName, Items).
:- pred module_to_link(pair(module_name, item_list), string,
io__state, io__state).
@@ -273,11 +274,13 @@
% The initial arrangement has the stage numbers increasing by three
% so that new stages can be slotted in without too much trouble.
-:- pred compile(pair(module_name, item_list), io__state, io__state).
-:- mode compile(in, di, uo) is det.
+:- pred compile(file_name, pair(module_name, item_list),
+ io__state, io__state).
+:- mode compile(in, in, di, uo) is det.
-compile(ModuleName - Items0) -->
- grab_imported_modules(ModuleName, Items0, Module, Error2),
+compile(SourceFileName, ModuleName - Items0) -->
+ grab_imported_modules(SourceFileName, ModuleName, Items0,
+ Module, Error2),
( { Error2 \= fatal } ->
mercury_compile(Module)
;
@@ -487,7 +490,7 @@
% not creating the trans opt file, then import the
% trans_opt files for all the modules that are
% imported (or used), and for all ancestor modules.
- { Imports0 = module_imports(_Module, Ancestors,
+ { Imports0 = module_imports(_File, _Module, Ancestors,
InterfaceImports, ImplementationImports,
_IndirectImports, _PublicChildren, _FactDeps,
_Items, _Error) },
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.73
diff -u -r1.73 modules.m
--- modules.m 1998/05/26 20:49:24 1.73
+++ modules.m 1998/05/27 01:58:43
@@ -125,23 +125,26 @@
%-----------------------------------------------------------------------------%
- % make_private_interface(ModuleName, Items):
- % Given a module name and the list of items in that module,
+ % make_private_interface(SourceFileName, ModuleName, Items):
+ % Given a source file name and module name,
+ % and the list of items in that module,
% output the private (`.int0') interface file for the module.
% (The private interface contains all the declarations in
% the module, including those in the `implementation'
% section; it is used when compiling sub-modules.)
%
-:- pred make_private_interface(module_name, item_list, io__state, io__state).
-:- mode make_private_interface(in, in, di, uo) is det.
+:- pred make_private_interface(file_name, module_name, item_list,
+ io__state, io__state).
+:- mode make_private_interface(in, in, in, di, uo) is det.
- % make_interface(ModuleName, Items):
- % Given a module name and the list of items in that module,
+ % make_interface(SourceFileName, ModuleName, Items):
+ % Given a source file name and module name,
+ % and the list of items in that module,
% output the long (`.int') and short (`.int2') interface files
% for the module.
%
-:- pred make_interface(module_name, item_list, io__state, io__state).
-:- mode make_interface(in, in, di, uo) is det.
+:- pred make_interface(file_name, module_name, item_list, io__state, io__state).
+:- mode make_interface(in, in, in, di, uo) is det.
% Output the unqualified short interface file to <module>.int3.
%
@@ -155,7 +158,9 @@
:- type module_imports --->
module_imports(
- module_name, % The primary module name
+ file_name, % The source file
+ module_name, % The module (or sub-module) that we
+ % are compiling.
list(module_name), % The list of ancestor modules it inherits
list(module_name), % The list of modules it directly imports
% in the interface
@@ -175,6 +180,9 @@
% Some access predicates for the module_imports structure
+:- pred module_imports_get_source_file_name(module_imports, file_name).
+:- mode module_imports_get_source_file_name(in, out) is det.
+
:- pred module_imports_get_module_name(module_imports, module_name).
:- mode module_imports_get_module_name(in, out) is det.
@@ -219,19 +227,22 @@
%-----------------------------------------------------------------------------%
- % grab_imported_modules(ModuleName, Items, Module, Error)
- % Given a module name and the list of items in that module,
+ % grab_imported_modules(SourceFileName, ModuleName,
+ % Items, Module, Error)
+ % Given a source file name and module name,
+ % and the list of items in that module,
% read in the private interface files for all the parent modules,
% the long interface files for all the imported modules,
% and the short interface files for all the indirectly imported
% modules, and return a `module_imports' structure containing the
% relevant information.
%
-:- pred grab_imported_modules(module_name, item_list, module_imports,
+:- pred grab_imported_modules(file_name, module_name, item_list, module_imports,
module_error, io__state, io__state).
-:- mode grab_imported_modules(in, in, out, out, di, uo) is det.
+:- mode grab_imported_modules(in, in, in, out, out, di, uo) is det.
- % grab_unqual_imported_modules(ModuleName, Items, Module, Error):
+ % grab_unqual_imported_modules(SourceFileName, ModuleName,
+ % Items, Module, Error):
% Similar to grab_imported_modules, but only reads in
% the unqualified short interfaces (.int3s),
% and the .int0 files for parent modules,
@@ -240,9 +251,9 @@
% Does not set the `PublicChildren' or `FactDeps'
% fields of the module_imports structure.
-:- pred grab_unqual_imported_modules(module_name, item_list, module_imports,
- module_error, io__state, io__state).
-:- mode grab_unqual_imported_modules(in, in, out, out, di, uo) is det.
+:- pred grab_unqual_imported_modules(file_name, module_name, item_list,
+ module_imports, module_error, io__state, io__state).
+:- mode grab_unqual_imported_modules(in, in, in, out, out, di, uo) is det.
% process_module_long_interfaces(Imports, Ext, IndirectImports0,
% IndirectImports, Module0, Module):
@@ -558,8 +569,9 @@
% Read in the .int3 files that the current module depends on,
% and use these to qualify all the declarations
% as much as possible. Then write out the .int0 file.
-make_private_interface(ModuleName, Items0) -->
- grab_unqual_imported_modules(ModuleName, Items0, Module, Error),
+make_private_interface(SourceFileName, ModuleName, Items0) -->
+ grab_unqual_imported_modules(SourceFileName, ModuleName, Items0,
+ Module, Error),
%
% Check whether we succeeded
%
@@ -593,13 +605,13 @@
% Read in the .int3 files that the current module depends on,
% and use these to qualify all items in the interface as much as
% possible. Then write out the .int and .int2 files.
-make_interface(ModuleName, Items0) -->
+make_interface(SourceFileName, ModuleName, Items0) -->
{ get_interface(Items0, no, InterfaceItems0) },
%
% Get the .int3 files for imported modules
%
- grab_unqual_imported_modules(ModuleName, InterfaceItems0,
- Module0, Error),
+ grab_unqual_imported_modules(SourceFileName, ModuleName,
+ InterfaceItems0, Module0, Error),
%
% Check whether we succeeded
@@ -888,7 +900,7 @@
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
-grab_imported_modules(ModuleName, Items0, Module, Error) -->
+grab_imported_modules(SourceFileName, ModuleName, Items0, Module, Error) -->
%
% Find out which modules this one depends on
%
@@ -905,8 +917,8 @@
{ get_fact_table_dependencies(Items0, FactDeps) },
{ get_interface(Items0, no, InterfaceItems) },
{ get_children(InterfaceItems, PublicChildren) },
- { init_module_imports(ModuleName, Items0, PublicChildren, FactDeps,
- Module0) },
+ { init_module_imports(SourceFileName, ModuleName, Items0,
+ PublicChildren, FactDeps, Module0) },
% If this module has any seperately-compiled sub-modules,
% then we need to make everything in this module exported.
@@ -958,7 +970,8 @@
% like grab_imported_modules, but gets the `.int3' files
% instead of the `.int' and `.int2' files.
-grab_unqual_imported_modules(ModuleName, Items0, Module, Error) -->
+grab_unqual_imported_modules(SourceFileName, ModuleName, Items0,
+ Module, Error) -->
%
% Find out which modules this one depends on
%
@@ -969,7 +982,8 @@
% Construct the initial module import structure,
% and append a `:- imported' decl to the items.
%
- { init_module_imports(ModuleName, Items0, [], [], Module0) },
+ { init_module_imports(SourceFileName, ModuleName, Items0, [], [],
+ Module0) },
{ append_pseudo_decl(Module0, imported, Module1) },
% Add `builtin' and `private_builtin' to the imported modules.
@@ -1002,44 +1016,48 @@
%-----------------------------------------------------------------------------%
-:- pred init_module_imports(module_name, item_list, list(module_name),
- list(string), module_imports).
-:- mode init_module_imports(in, in, in, in, out) is det.
-
-init_module_imports(ModuleName, Items, PublicChildren, FactDeps, Module) :-
- Module = module_imports(ModuleName, [], [], [], [],
+:- pred init_module_imports(file_name, module_name, item_list,
+ list(module_name), list(string), module_imports).
+:- mode init_module_imports(in, in, in, in, in, out) is det.
+
+init_module_imports(SourceFileName, ModuleName, Items, PublicChildren,
+ FactDeps, Module) :-
+ Module = module_imports(SourceFileName, ModuleName, [], [], [], [],
PublicChildren, FactDeps, Items, no).
+module_imports_get_source_file_name(Module, SourceFileName) :-
+ Module = module_imports(SourceFileName, _, _, _, _, _, _, _, _, _).
+
module_imports_get_module_name(Module, ModuleName) :-
- Module = module_imports(ModuleName, _, _, _, _, _, _, _, _).
+ Module = module_imports(_, ModuleName, _, _, _, _, _, _, _, _).
module_imports_get_items(Module, Items) :-
- Module = module_imports(_, _, _, _, _, _, _, Items, _).
+ Module = module_imports(_, _, _, _, _, _, _, _, Items, _).
module_imports_set_items(Module0, Items, Module) :-
- Module0 = module_imports(A, B, C, D, E, F, G, _, I),
- Module = module_imports(A, B, C, D, E, F, G, Items, I).
+ Module0 = module_imports(A, B, C, D, E, F, G, H, _, J),
+ Module = module_imports(A, B, C, D, E, F, G, H, Items, J).
module_imports_get_error(Module, Error) :-
- Module = module_imports(_, _, _, _, _, _, _, _, Error).
+ Module = module_imports(_, _, _, _, _, _, _, _, _, Error).
module_imports_set_error(Module0, Error, Module) :-
- Module0 = module_imports(A, B, C, D, E, F, G, H, _),
- Module = module_imports(A, B, C, D, E, F, G, H, Error).
+ Module0 = module_imports(A, B, C, D, E, F, G, H, I, _),
+ Module = module_imports(A, B, C, D, E, F, G, H, I, Error).
module_imports_set_indirect_deps(Module0, IndirectDeps, Module) :-
- Module0 = module_imports(A, B, C, D, _, F, G, H, I),
- Module = module_imports(A, B, C, D, IndirectDeps, F, G, H, I).
+ Module0 = module_imports(A, B, C, D, E, _, G, H, I, J),
+ Module = module_imports(A, B, C, D, E, IndirectDeps, G, H, I, J).
append_pseudo_decl(Module0, PseudoDecl, Module) :-
- Module0 = module_imports(ModuleName, Ancestors, IntDeps, ImplDeps,
- IndirectDeps, PublicChildren, FactDeps,
- Items0, Error),
+ Module0 = module_imports(FileName, ModuleName, Ancestors, IntDeps,
+ ImplDeps, IndirectDeps, PublicChildren, FactDeps,
+ Items0, Error),
make_pseudo_decl(PseudoDecl, Item),
list__append(Items0, [Item], Items),
- Module = module_imports(ModuleName, Ancestors, IntDeps, ImplDeps,
- IndirectDeps, PublicChildren, FactDeps,
- Items, Error).
+ Module = module_imports(FileName, ModuleName, Ancestors, IntDeps,
+ ImplDeps, IndirectDeps, PublicChildren, FactDeps,
+ Items, Error).
make_pseudo_decl(PseudoDecl, Item) :-
term__context_init(Context),
@@ -1183,8 +1201,9 @@
%-----------------------------------------------------------------------------%
write_dependency_file(Module, MaybeTransOptDeps) -->
- { Module = module_imports(ModuleName, ParentDeps, IntDeps, ImplDeps,
- IndirectDeps, _InclDeps, FactDeps0, _Items, _Error) },
+ { Module = module_imports(SourceFileName, ModuleName, ParentDeps,
+ IntDeps, ImplDeps, IndirectDeps, _InclDeps, FactDeps0,
+ _Items, _Error) },
globals__io_lookup_bool_option(verbose, Verbose),
{ module_name_to_make_var_name(ModuleName, MakeVarName) },
module_name_to_file_name(ModuleName, ".d", yes, DependencyFileName),
@@ -1264,17 +1283,26 @@
[]
),
+ {
+ string__remove_suffix(SourceFileName, ".m",
+ SourceFileBase)
+ ->
+ string__append(SourceFileBase, ".err", ErrFileName)
+ ;
+ error("modules.m: source file doesn't end in `.m'")
+ },
module_name_to_file_name(ModuleName, ".optdate", no,
OptDateFileName),
module_name_to_file_name(ModuleName, ".c", no, CFileName),
- module_name_to_file_name(ModuleName, ".err", no, ErrFileName),
module_name_to_file_name(ModuleName, ".o", no, ObjFileName),
- module_name_to_file_name(ModuleName, ".m", no, SourceFileName),
+ module_name_to_file_name(ModuleName, ".pic_o", no,
+ PicObjFileName),
io__write_strings(DepStream, ["\n\n",
OptDateFileName, " ",
TransOptDateFileName, " ",
CFileName, " ",
ErrFileName, " ",
+ PicObjFileName, " ",
ObjFileName, " : ",
SourceFileName
] ),
@@ -1303,6 +1331,7 @@
CFileName, " ",
TransOptDateFileName, " ",
ErrFileName, " ",
+ PicObjFileName, " ",
ObjFileName, " :"
]),
% The .c file only depends on the .opt files from
@@ -1327,6 +1356,7 @@
"\n\n",
CFileName, " ",
ErrFileName, " ",
+ PicObjFileName, " ",
ObjFileName, " :"
]),
write_dependencies_list(TransOptDeps,
@@ -1353,7 +1383,7 @@
write_dependencies_list(ParentDeps, ".int0", DepStream),
write_dependencies_list(LongDeps, ".int3", DepStream),
write_dependencies_list(ShortDeps, ".int3", DepStream),
-
+
module_name_to_file_name(ModuleName, ".dir", no, DirFileName),
module_name_to_split_c_file_name(ModuleName, 0, ".o",
SplitCObj0FileName),
@@ -1366,6 +1396,66 @@
SourceFileName, "\n"
]),
+ module_name_to_file_name(ModuleName, ".m", no,
+ ExpectedSourceFileName),
+ ( { SourceFileName \= ExpectedSourceFileName } ->
+ %
+ % The pattern rules in Mmake.rules won't work,
+ % since the source file name doesn't match the
+ % expected source file name for this module name.
+ % This can occur due to just the use of different
+ % source file names, or it can be due to the use
+ % of nested modules. So we need to output
+ % hard-coded rules in this case.
+ %
+ % The rules output below won't work in the case
+ % of nested modules with parallel makes,
+ % because it will end up invoking the same
+ % command twice (since it produces two output files)
+ % at the same time.
+ %
+ % Any changes here will require corresponding
+ % changes to scripts/Mmake.rules. See that
+ % file for documentation on these rules.
+ %
+ module_name_to_file_name(ModuleName, ".date3", no,
+ Date3FileName),
+ io__write_strings(DepStream, [
+ "\n",
+ Date0FileName, " : ", SourceFileName, "\n",
+ "\t$(MCPI) $(MCPIFLAGS) $<\n",
+ DateFileName, " : ", SourceFileName, "\n",
+ "\t$(MCI) $(MCIFLAGS) $<\n",
+ Date3FileName, " : ", SourceFileName, "\n",
+ "\t$(MCSI) $(MCSIFLAGS) $<\n",
+ OptDateFileName, " : ", SourceFileName, "\n",
+ "\t$(MCOI) $(MCOIFLAGS) $<\n",
+ TransOptDateFileName, " : ", SourceFileName,
+ "\n",
+ "\t$(MCTOI) $(MCTOIFLAGS) $<\n",
+ CFileName, " : ", SourceFileName, "\n",
+ "\trm -f ", CFileName, "\n",
+ "\t$(MCG) $(GRADEFLAGS) $(MCGFLAGS) $< ",
+ "> ", ErrFileName, " 2>&1\n",
+ "ifneq ($(RM_C),:)\n",
+ ObjFileName, " : ", SourceFileName, "\n",
+ "\t$(MMAKE_MAKE_CMD) $(MFLAGS) GRADEFLAGS=",
+ """$(GRADEFLAGS)"" ", CFileName, "\n",
+ "\t$(MGNUC) $(GRADEFLAGS) $(MGNUCFLAGS) -c ",
+ CFileName, " -o $@\n",
+ "\t$(RM_C) ", CFileName, "\n",
+ PicObjFileName, " : ", SourceFileName, "\n",
+ "\t$(MMAKE_MAKE_CMD) $(MFLAGS) GRADEFLAGS=",
+ """$(GRADEFLAGS)"" ", CFileName, "\n",
+ "\t$(MGNUC) $(GRADEFLAGS) $(MGNUCFLAGS) ",
+ "$(CFLAGS_FOR_PIC) \\\n",
+ "\t\t-c ", CFileName, " -o $@\n",
+ "endif # RM_C != :\n"
+ ])
+ ;
+ []
+ ),
+
io__close_output(DepStream),
io__rename_file(TmpDependencyFileName, DependencyFileName,
Result3),
@@ -1537,22 +1627,25 @@
%-----------------------------------------------------------------------------%
-generate_dependencies(Module) -->
+generate_dependencies(ModuleName) -->
% first, build up a map of the dependencies.
{ map__init(DepsMap0) },
- generate_deps_map([Module], DepsMap0, DepsMap),
+ generate_deps_map([ModuleName], DepsMap0, DepsMap),
%
% check whether we could read the main `.m' file
%
- { map__lookup(DepsMap, Module, deps(_, ModuleImports)) },
+ { map__lookup(DepsMap, ModuleName, deps(_, ModuleImports)) },
{ module_imports_get_error(ModuleImports, Error) },
( { Error = fatal } ->
- { prog_out__sym_name_to_string(Module, ModuleString) },
+ { prog_out__sym_name_to_string(ModuleName, ModuleString) },
{ string__append_list(["fatal error reading module `",
ModuleString, "'."], Message) },
report_error(Message)
;
- generate_dependencies_write_dep_file(Module, DepsMap),
+ { module_imports_get_source_file_name(ModuleImports,
+ SourceFileName) },
+ generate_dependencies_write_dep_file(SourceFileName, ModuleName,
+ DepsMap),
%
% compute the interface deps relation and
@@ -1571,7 +1664,7 @@
% we have (or can make) trans-opt files.
%
{ relation__atsort(ImplDepsRel, ImplDepsOrdering0) },
- maybe_output_module_order(Module, ImplDepsOrdering0),
+ maybe_output_module_order(ModuleName, ImplDepsOrdering0),
{ list__map(set__to_sorted_list, ImplDepsOrdering0,
ImplDepsOrdering) },
{ list__condense(ImplDepsOrdering, TransOptDepsOrdering0) },
@@ -1715,7 +1808,7 @@
( { Done = no } ->
{ map__set(DepsMap1, Module, deps(yes, ModuleImports),
DepsMap2) },
- { ModuleImports = module_imports(_,
+ { ModuleImports = module_imports(_, _,
ParentDeps, IntDeps, ImplDeps, _, InclDeps, _, _, _) },
{ list__condense(
[ParentDeps, IntDeps, ImplDeps, InclDeps, Modules],
@@ -1739,7 +1832,7 @@
deps_list_to_deps_rel([Deps | DepsList], DepsMap,
IntRel0, IntRel, ImplRel0, ImplRel) :-
Deps = deps(_, ModuleImports),
- ModuleImports = module_imports(ModuleName,
+ ModuleImports = module_imports(_FileName, ModuleName,
ParentDeps, IntDeps, ImplDeps,
_IndirectDeps, PublicChildren, _FactDeps, _Items, ModuleError),
( ModuleError \= fatal ->
@@ -1778,9 +1871,9 @@
%-----------------------------------------------------------------------------%
% Write out the `.dep' file, using the information collected in the
% deps_map data structure.
-:- pred generate_dependencies_write_dep_file(module_name::in, deps_map::in,
- io__state::di, io__state::uo) is det.
-generate_dependencies_write_dep_file(ModuleName, DepsMap) -->
+:- pred generate_dependencies_write_dep_file(file_name::in, module_name::in,
+ deps_map::in, io__state::di, io__state::uo) is det.
+generate_dependencies_write_dep_file(SourceFileName, ModuleName, DepsMap) -->
globals__io_lookup_bool_option(verbose, Verbose),
module_name_to_file_name(ModuleName, ".dep", yes, DepFileName),
maybe_write_string(Verbose, "% Creating auto-dependency file `"),
@@ -1788,7 +1881,8 @@
maybe_write_string(Verbose, "'...\n"),
io__open_output(DepFileName, DepResult),
( { DepResult = ok(DepStream) } ->
- generate_dep_file(ModuleName, DepsMap, DepStream),
+ generate_dep_file(SourceFileName, ModuleName, DepsMap,
+ DepStream),
io__close_output(DepStream),
maybe_write_string(Verbose, "% done.\n")
;
@@ -1798,16 +1892,21 @@
).
-:- pred generate_dep_file(module_name, deps_map, io__output_stream,
+:- pred generate_dep_file(file_name, module_name, deps_map, io__output_stream,
io__state, io__state).
-:- mode generate_dep_file(in, in, in, di, uo) is det.
+:- mode generate_dep_file(in, in, in, in, di, uo) is det.
-generate_dep_file(ModuleName, DepsMap, DepStream) -->
+generate_dep_file(SourceFileName, ModuleName, DepsMap, DepStream) -->
io__write_string(DepStream,
"# Automatically generated dependencies for module `"),
{ prog_out__sym_name_to_string(ModuleName, ModuleNameString) },
io__write_string(DepStream, ModuleNameString),
- io__write_string(DepStream, "'.\n"),
+ io__write_string(DepStream, "'\n"),
+ io__write_string(DepStream,
+ "# generated from source file `"),
+ io__write_string(DepStream, SourceFileName),
+ io__write_string(DepStream, "'\n"),
+
{ library__version(Version) },
io__write_string(DepStream,
"# Generated by the Mercury compiler, version "),
@@ -1818,15 +1917,28 @@
{ select_ok_modules(Modules0, DepsMap, Modules) },
{ module_name_to_make_var_name(ModuleName, MakeVarName) },
+ { list__map(get_source_file(DepsMap), Modules, SourceFiles0) },
+ { list__sort_and_remove_dups(SourceFiles0, SourceFiles) },
+
io__write_string(DepStream, MakeVarName),
io__write_string(DepStream, ".ms ="),
- write_dependencies_list(Modules, ".m", DepStream),
+ write_file_dependencies_list(SourceFiles, ".m", DepStream),
+ io__write_string(DepStream, "\n"),
+
+ io__write_string(DepStream, MakeVarName),
+ io__write_string(DepStream, ".errs ="),
+ write_file_dependencies_list(SourceFiles, ".err", DepStream),
+ io__write_string(DepStream, "\n"),
+
+ io__write_string(DepStream, MakeVarName),
+ io__write_string(DepStream, ".mods ="),
+ write_dependencies_list(Modules, "", DepStream),
io__write_string(DepStream, "\n\n"),
globals__io_lookup_bool_option(assume_gmake, Gmake),
( { Gmake = yes } ->
- { string__append(MakeVarName, ".ms", VarName) },
- { Basis = yes(VarName - ".m") }
+ { string__append(MakeVarName, ".mods", ModsVarName) },
+ { Basis = yes(ModsVarName - "") }
;
{ Basis = no }
),
@@ -1884,11 +1996,6 @@
io__write_string(DepStream, "\n"),
io__write_string(DepStream, MakeVarName),
- io__write_string(DepStream, ".errs = "),
- write_compact_dependencies_list(Modules, "", ".err", Basis, DepStream),
- io__write_string(DepStream, "\n"),
-
- io__write_string(DepStream, MakeVarName),
io__write_string(DepStream, ".dates = "),
write_compact_dependencies_list(Modules, "$(dates_subdir)", ".date",
Basis, DepStream),
@@ -2205,6 +2312,21 @@
"\t-rm -f $(", MakeVarName, ".qls)\n\n"
]).
+:- pred get_source_file(deps_map, module_name, file_name).
+:- mode get_source_file(in, in, out) is det.
+
+get_source_file(DepsMap, ModuleName, FileName) :-
+ map__lookup(DepsMap, ModuleName, Deps),
+ Deps = deps(_, ModuleImports),
+ module_imports_get_source_file_name(ModuleImports, SourceFileName),
+ (
+ string__remove_suffix(SourceFileName, ".m", SourceFileBase)
+ ->
+ FileName = SourceFileBase
+ ;
+ error("modules.m: source file name doesn't end in `.m'")
+ ).
+
:- pred append_to_init_list(io__output_stream, file_name, module_name,
io__state, io__state).
:- mode append_to_init_list(in, in, in, di, uo) is det.
@@ -2233,7 +2355,7 @@
get_extra_link_objects_2([Module | Modules], DepsMap,
ExtraLinkObjs0, ExtraLinkObjs) :-
map__lookup(DepsMap, Module, deps(_, ModuleImports)),
- ModuleImports = module_imports(_, _, _, _, _, _, FactDeps, _, _),
+ ModuleImports = module_imports(_, _, _, _, _, _, _, FactDeps, _, _),
list__append(FactDeps, ExtraLinkObjs0, ExtraLinkObjs1),
get_extra_link_objects_2(Modules, DepsMap, ExtraLinkObjs1,
ExtraLinkObjs).
@@ -2338,19 +2460,27 @@
{ ModuleImports0 = ModuleImports },
{ DepsMap = DepsMap0 }
;
- read_dependencies(Module, Search, ModuleImports),
- { map__det_insert(DepsMap0, Module, deps(no, ModuleImports),
- DepsMap) },
- { Done = no }
- ).
+ read_dependencies(Module, Search, ModuleImportsList),
+ { list__foldl(insert_into_deps_map, ModuleImportsList,
+ DepsMap0, DepsMap) },
+ { map__lookup(DepsMap, Module, deps(Done, ModuleImports)) }
+ ).
+
+:- pred insert_into_deps_map(module_imports, deps_map, deps_map).
+:- mode insert_into_deps_map(in, in, out) is det.
+insert_into_deps_map(ModuleImports, DepsMap0, DepsMap) :-
+ module_imports_get_module_name(ModuleImports, ModuleName),
+ map__det_insert(DepsMap0, ModuleName, deps(no, ModuleImports),
+ DepsMap).
- % Read a module to determine its (direct) dependencies
+ % Read a module to determine the (direct) dependencies
+ % of that module and any nested sub-modules it contains.
-:- pred read_dependencies(module_name, bool, module_imports,
+:- pred read_dependencies(module_name, bool, list(module_imports),
io__state, io__state).
:- mode read_dependencies(in, in, out, di, uo) is det.
-read_dependencies(ModuleName, Search, ModuleImports) -->
+read_dependencies(ModuleName, Search, ModuleImportsList) -->
read_mod_ignore_errors(ModuleName, ".m",
"Getting dependencies for module", Search, Items0, Error),
( { Items0 = [], Error = fatal } ->
@@ -2360,32 +2490,41 @@
;
{ Items = Items0 }
),
-
- { get_ancestors(ModuleName, ParentDeps) },
-
- { get_dependencies(Items, ImplImportDeps0, ImplUseDeps0) },
- { add_implicit_imports(ImplImportDeps0, ImplUseDeps0,
- ImplImportDeps, ImplUseDeps) },
- { list__append(ImplImportDeps, ImplUseDeps, ImplementationDeps) },
-
- { get_interface(Items, no, InterfaceItems) },
- { get_dependencies(InterfaceItems, InterfaceImportDeps0,
- InterfaceUseDeps0) },
- { add_implicit_imports(InterfaceImportDeps0, InterfaceUseDeps0,
- InterfaceImportDeps, InterfaceUseDeps) },
- { list__append(InterfaceImportDeps, InterfaceUseDeps,
- InterfaceDeps) },
+ module_name_to_file_name(ModuleName, ".m", no, FileName),
+ { split_into_submodules(ModuleName, Items, SubModuleList) },
+ { list__map(read_dependencies_2(FileName, Error), SubModuleList,
+ ModuleImportsList) }.
+
+:- pred read_dependencies_2(file_name, module_error,
+ pair(module_name, item_list), module_imports).
+:- mode read_dependencies_2(in, in, in, out) is det.
+
+read_dependencies_2(FileName, Error, ModuleName - Items, ModuleImports) :-
+ get_ancestors(ModuleName, ParentDeps),
+
+ get_dependencies(Items, ImplImportDeps0, ImplUseDeps0),
+ add_implicit_imports(ImplImportDeps0, ImplUseDeps0,
+ ImplImportDeps, ImplUseDeps),
+ list__append(ImplImportDeps, ImplUseDeps, ImplementationDeps),
+
+ get_interface(Items, no, InterfaceItems),
+ get_dependencies(InterfaceItems, InterfaceImportDeps0,
+ InterfaceUseDeps0),
+ add_implicit_imports(InterfaceImportDeps0, InterfaceUseDeps0,
+ InterfaceImportDeps, InterfaceUseDeps),
+ list__append(InterfaceImportDeps, InterfaceUseDeps,
+ InterfaceDeps),
% we don't fill in the indirect dependencies yet
- { IndirectDeps = [] },
+ IndirectDeps = [],
- { get_children(InterfaceItems, IncludeDeps) },
+ get_children(InterfaceItems, IncludeDeps),
- { get_fact_table_dependencies(Items, FactTableDeps) },
+ get_fact_table_dependencies(Items, FactTableDeps),
- { ModuleImports = module_imports(ModuleName, ParentDeps, InterfaceDeps,
- ImplementationDeps, IndirectDeps, IncludeDeps, FactTableDeps,
- [], Error) }.
+ ModuleImports = module_imports(FileName, ModuleName, ParentDeps,
+ InterfaceDeps, ImplementationDeps, IndirectDeps, IncludeDeps,
+ FactTableDeps, [], Error).
%-----------------------------------------------------------------------------%
@@ -2456,7 +2595,7 @@
process_module_private_interfaces([Ancestor | Ancestors],
DirectImports0, DirectImports, DirectUses0, DirectUses,
Module0, Module) -->
- { Module0 = module_imports(ModuleName, ModAncestors0,
+ { Module0 = module_imports(FileName, ModuleName, ModAncestors0,
ModInterfaceDeps, ModImplementationDeps,
ModIndirectDeps, ModPublicChildren,
ModFactDeps, ModItems0, ModError0) },
@@ -2492,7 +2631,7 @@
DirectImports1) },
{ list__append(DirectUses0, AncDirectUses, DirectUses1) },
{ list__append(ModItems0, Items, ModItems) },
- { Module1 = module_imports(ModuleName, ModAncestors,
+ { Module1 = module_imports(FileName, ModuleName, ModAncestors,
ModInterfaceDeps, ModImplementationDeps,
ModIndirectDeps, ModPublicChildren,
ModFactDeps, ModItems, ModError) },
@@ -2507,7 +2646,7 @@
Module, Module) --> [].
process_module_long_interfaces([Import | Imports], Ext, IndirectImports0,
IndirectImports, Module0, Module) -->
- { Module0 = module_imports(ModuleName, ModAncestors,
+ { Module0 = module_imports(FileName, ModuleName, ModAncestors,
ModInterfaceImports, ModImplementationImports0,
ModIndirectImports, ModPublicChildren,
ModFactDeps, ModItems0, ModError0) },
@@ -2546,7 +2685,7 @@
{ list__append(IndirectImports2, IndirectUses1,
IndirectImports3) },
{ list__append(ModItems0, Items, ModItems) },
- { Module1 = module_imports(ModuleName, ModAncestors,
+ { Module1 = module_imports(FileName, ModuleName, ModAncestors,
ModInterfaceImports, ModImplementationImports,
ModIndirectImports, ModPublicChildren,
ModFactDeps, ModItems, ModError) },
@@ -2687,7 +2826,7 @@
IndirectImports, IndirectImports, Module, Module) --> [].
process_module_short_interfaces([Import | Imports], Ext,
IndirectImports0, IndirectImports, Module0, Module) -->
- { Module0 = module_imports(ModuleName, ModAncestors,
+ { Module0 = module_imports(FileName, ModuleName, ModAncestors,
ModInterfaceDeps, ModImplementationDeps,
ModIndirectImports0, ModPublicChildren, ModFactDeps,
ModItems0, ModError0) },
@@ -2717,7 +2856,7 @@
{ list__append(IndirectImports0, Imports1, IndirectImports1) },
{ list__append(IndirectImports1, Uses1, IndirectImports2) },
{ list__append(ModItems0, Items, ModItems) },
- { Module1 = module_imports(ModuleName, ModAncestors,
+ { Module1 = module_imports(FileName, ModuleName, ModAncestors,
ModInterfaceDeps, ModImplementationDeps,
ModIndirectImports, ModPublicChildren, ModFactDeps,
ModItems, ModError) },
Index: scripts/Mmake.rules
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/Mmake.rules,v
retrieving revision 1.59
diff -u -r1.59 Mmake.rules
--- Mmake.rules 1998/05/26 09:48:29 1.59
+++ Mmake.rules 1998/05/27 01:19:23
@@ -108,6 +108,8 @@
#-----------------------------------------------------------------------------#
#
# Rules for building interface files
+# WARNING: any changes here will probably need to be
+# duplicated in compiler/modules.m.
#
$(date0s_subdir)%.date0 : %.m
@@ -152,6 +154,8 @@
#-----------------------------------------------------------------------------#
#
# Rules for compiling Mercury source files
+# WARNING: any changes here will probably need to be
+# duplicated in compiler/modules.m.
#
$(cs_subdir)%.c : %.m
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.29
diff -u -r1.29 Mmakefile
--- Mmakefile 1998/05/20 13:10:15 1.29
+++ Mmakefile 1998/05/27 02:09:48
@@ -78,6 +78,7 @@
# Not working:
# cycles - loops when compiled in a non-GC grade with --deforestation.
# cycles2 - loops when compiled in a non-GC grade.
+# nested, nested2 - sometimes fail if using parallel makes
#-----------------------------------------------------------------------------#
Index: tests/hard_coded/nested.exp
===================================================================
RCS file: nested.exp
diff -N nested.exp
--- /dev/null Wed May 27 12:06:04 1998
+++ nested.exp Wed May 27 12:12:34 1998
@@ -0,0 +1,14 @@
+nested:child:hello
+nested:child:hello
+nested:child:hello
+nested:child2:hello
+t1 = nested:child:foo
+t2 = nested:child:foo
+t3 = nested:child:foo
+t4 = nested:child2:foo
+t5 = nested:child2:foo
+has_type_t1 = bar
+has_type_t2 = bar
+has_type_t3 = bar
+has_type_t4 = bar
+has_type_t5 = bar
Index: tests/hard_coded/nested.m
===================================================================
RCS file: nested.m
diff -N nested.m
--- /dev/null Wed May 27 12:06:04 1998
+++ nested.m Wed May 27 12:05:47 1998
@@ -0,0 +1,95 @@
+% "Hello World" in Mercury, using nested modules.
+
+:- module nested.
+:- interface.
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+%-----------------------------------------------------------------------------%
+
+:- module nested:child.
+:- interface.
+:- import_module io.
+
+:- type foo ---> bar ; baz(int).
+
+:- pred hello(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+hello --> io__write_string("nested:child:hello\n").
+
+:- end_module nested:child.
+
+%-----------------------------------------------------------------------------%
+
+:- module nested:child2.
+:- interface.
+:- import_module io.
+
+:- type foo ---> bar ; baz(int).
+
+:- pred hello(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+hello --> io__write_string("nested:child2:hello\n").
+
+:- end_module nested:child2.
+
+%-----------------------------------------------------------------------------%
+
+% now we're back in the parent module.
+
+:- import_module nested:child.
+:- use_module nested:child2.
+:- import_module std_util, require.
+
+:- type t1 == nested:child:foo.
+:- type t2 == child:foo.
+:- type t3 == foo.
+:- type t4 == nested:child2:foo.
+% :- type t5 == child2:foo. % XXX mixing of use_module and import_module
+ % is not yet supported.
+:- type t5 == nested:child2:foo.
+
+main -->
+ nested:child:hello,
+ child:hello,
+ hello,
+ nested:child2:hello,
+ % child2:hello, % XXX mixing of use_module and import_module
+ % is not yet supported.
+
+ print("t1 = "), print(type_of(has_type_t1)), nl,
+ print("t2 = "), print(type_of(has_type_t2)), nl,
+ print("t3 = "), print(type_of(has_type_t3)), nl,
+ print("t4 = "), print(type_of(has_type_t4)), nl,
+ print("t5 = "), print(type_of(has_type_t5)), nl,
+
+ print("has_type_t1 = "), print(has_type_t1), nl,
+ print("has_type_t2 = "), print(has_type_t2), nl,
+ print("has_type_t3 = "), print(has_type_t3), nl,
+ print("has_type_t4 = "), print(has_type_t4), nl,
+ print("has_type_t5 = "), print(has_type_t5), nl,
+
+ { true }.
+
+:- func has_type_t1 = t1.
+:- func has_type_t2 = t2.
+:- func has_type_t3 = t3.
+:- func has_type_t4 = t4.
+:- func has_type_t5 = t5.
+
+has_type_t1 = nested:child:bar.
+has_type_t2 = child:bar.
+has_type_t3 = bar.
+has_type_t4 = nested:child2:bar.
+% has_type_t5 = child2:bar. % XXX mixing of use_module and import_module
+ % is not yet supported.
+has_type_t5 = nested:child2:bar.
+
+:- end_module nested.
Index: tests/hard_coded/nested2.exp
===================================================================
RCS file: nested2.exp
diff -N nested2.exp
--- /dev/null Wed May 27 12:06:04 1998
+++ nested2.exp Wed May 27 12:11:30 1998
@@ -0,0 +1,10 @@
+nested2:hello
+nested2:hello
+t1 = nested2:foo
+t2 = nested2:foo
+t3 = nested2:foo
+t4 = nested2:foo
+has_type_t1 = bar
+has_type_t2 = bar
+has_type_t3 = baz(42)
+has_type_t4 = baz(42)
Index: tests/hard_coded/nested2.m
===================================================================
RCS file: nested2.m
diff -N nested2.m
--- /dev/null Wed May 27 12:06:04 1998
+++ nested2.m Wed May 27 12:10:34 1998
@@ -0,0 +1,61 @@
+% Another test case to test nested modules.
+
+:- module nested2.
+:- interface.
+:- import_module io.
+
+%-----------------------------------------------------------------------------%
+
+:- module nested2:child.
+:- interface.
+
+% module `io' is imported in nested2
+
+:- type t1 == foo.
+:- type t2 == nested2:foo.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+:- import_module std_util.
+
+:- type t3 == foo.
+:- type t4 == nested2:foo.
+
+:- func has_type_t1 = t1.
+:- func has_type_t2 = t2.
+:- func has_type_t3 = t3.
+:- func has_type_t4 = t4.
+
+has_type_t1 = bar.
+has_type_t2 = nested2:bar.
+has_type_t3 = baz(42).
+has_type_t4 = nested2:baz(42).
+
+main -->
+ nested2:hello,
+ hello,
+
+ print("t1 = "), print(type_of(has_type_t1)), nl,
+ print("t2 = "), print(type_of(has_type_t2)), nl,
+ print("t3 = "), print(type_of(has_type_t3)), nl,
+ print("t4 = "), print(type_of(has_type_t4)), nl,
+
+ print("has_type_t1 = "), print(has_type_t1), nl,
+ print("has_type_t2 = "), print(has_type_t2), nl,
+ print("has_type_t3 = "), print(has_type_t3), nl,
+ print("has_type_t4 = "), print(has_type_t4), nl.
+
+:- end_module nested2:child.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- type foo ---> bar ; baz(int).
+
+:- pred hello(io__state::di, io__state::uo) is det.
+
+hello --> print("nested2:hello\n").
+
+:- end_module nested2.
--
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