diff: relax file_name <-> module_name mapping
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu May 28 21:24:12 AEST 1998
Estimated hours taken: 8
Allow modules to be put in source files whose names that do not directly match
their the module names. When looking for the source for a module such
as `foo:bar:baz', search for it first in `foo.bar.baz.m', then in `bar.baz.m',
and finally in `baz.m'.
compiler/prog_io.m:
Change prog_io__read_module so that it returns the name of
the module read, as determined by the `:- module' declaration.
Add predicate `check_module_has_expected_name', for checking
that this name matches what was expected.
compiler/modules.m:
Add read_mod_from_file, for reading a module given the file name,
and generated_file_dependencies, for generating the dependencies
of a module given the file name. (As opposed to the module name.)
Change read_mod and read_mod_ignore_errors so that they
search for `.m' files as described above, and return the name
of the source file read.
Also improve the efficiency of read_dependencies slightly:
when reading in `.int' files, there's no need to call
split_into_submodules, because we generate a seperate
`.int' file for each submodule anyway.
compiler/mercury_compile.m:
Change the handling of command-line arguments.
Arguments ending with `.m' are assumed to be file names,
and other arguments are assumed to be module names.
For file names, call read_mod_from_file instead of read_mod.
compiler/handle_options.m:
Change help message to reflect the above change to the semantics
of command-line arguments.
compiler/intermod.m:
compiler/trans_opt.m:
Fix a bug: call prog_io__read_opt_file instead of prog_io__read_module.
doc/user_guide.texi:
Document the above change to the semantics of command-line arguments.
Update the "libraries" chapter to reflect our support for nested
modules.
cvs diff compiler/handle_options.m compiler/intermod.m compiler/mercury_compile.m compiler/modules.m compiler/prog_io.m compiler/trans_opt.m doc/user_guide.texi
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.51
diff -u -r1.51 handle_options.m
--- handle_options.m 1998/05/20 11:11:32 1.51
+++ handle_options.m 1998/05/27 19:24:07
@@ -720,27 +720,22 @@
usage.
usage -->
- io__progname_base("mercury_compile", ProgName),
io__stderr_stream(StdErr),
{ library__version(Version) },
- io__write_strings(StdErr,
- ["Mercury Compiler, version ", Version, "\n"]),
- io__write_string(StdErr,
- "Copyright (C) 1993-1998 The University of Melbourne\n"),
- io__write_string(StdErr, "Usage: "),
- io__write_string(StdErr, ProgName),
- io__write_string(StdErr, " [<options>] <module(s)>\n"),
- io__write_string(StdErr, "Use `"),
- io__write_string(StdErr, ProgName),
- io__write_string(StdErr, " --help' for more information.\n").
+ io__write_strings(StdErr, [
+ "Mercury Compiler, version ", Version, "\n",
+ "Copyright (C) 1993-1998 The University of Melbourne\n",
+ "Usage: mmc [<options>] <arguments>\n",
+ "Use `mmc --help' for more information.\n"
+ ]).
long_usage -->
- io__progname_base("mercury_compile", ProgName),
{ library__version(Version) },
io__write_strings(["Mercury Compiler, version ", Version, "\n"]),
io__write_string("Copyright (C) 1993-1998 The University of Melbourne\n"),
- io__write_string("Usage: "),
- io__write_string(ProgName),
- io__write_string(" [<options>] <module(s)>\n"),
+ io__write_string("Usage: mmc [<options>] <arguments>\n"),
+ io__write_string("Arguments:\n"),
+ io__write_string("\t\tArguments ending in `.m' are assumed to be source file names.\n"),
+ io__write_string("\t\tArguments that do not end in `.m' are assumed to be module names.\n"),
io__write_string("Options:\n"),
options_help.
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.52
diff -u -r1.52 intermod.m
--- intermod.m 1998/05/27 04:00:36 1.52
+++ intermod.m 1998/05/27 17:40:20
@@ -1370,7 +1370,7 @@
maybe_write_string(VeryVerbose, "% done.\n"),
module_name_to_file_name(Import, ".opt", no, FileName),
- prog_io__read_module(FileName, Import, yes,
+ prog_io__read_opt_file(FileName, Import, yes,
ModuleError, Messages, Items1),
update_error_status(FileName, ModuleError, Messages, Error0, Error1),
{ list__append(Items0, Items1, Items2) },
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.92
diff -u -r1.92 mercury_compile.m
--- mercury_compile.m 1998/05/27 04:00:38 1.92
+++ mercury_compile.m 1998/05/28 07:57:39
@@ -68,8 +68,7 @@
; { Args = [] } ->
usage
;
- { strip_module_suffixes(Args, ModuleNames) },
- process_module_list(ModuleNames, ModulesToLink),
+ process_arg_list(Args, ModulesToLink),
io__get_exit_status(ExitStatus),
( { ExitStatus = 0 } ->
( { Link = yes } ->
@@ -99,91 +98,99 @@
)
).
- % Process a list of module names.
- % Remove any `.m' extension before processing
- % the module name.
-
-:- pred strip_module_suffixes(list(string), list(string)).
-:- mode strip_module_suffixes(in, out) is det.
-
-strip_module_suffixes([], []).
-strip_module_suffixes([Module0 | Modules0], [Module | Modules]) :-
- (
- string__remove_suffix(Module0, ".m", Module1)
- ->
- Module = Module1
- ;
- Module = Module0
- ),
- strip_module_suffixes(Modules0, Modules).
-
-:- pred process_module_list(list(string), list(string), io__state, io__state).
-:- mode process_module_list(in, out, di, uo) is det.
-
-process_module_list(Modules, SubModules) -->
- process_module_list_2(Modules, SubModulesList),
- { list__condense(SubModulesList, SubModules) }.
+:- pred process_arg_list(list(string), list(string), io__state, io__state).
+:- mode process_arg_list(in, out, di, uo) is det.
+
+process_arg_list(Args, Modules) -->
+ process_arg_list_2(Args, ModulesList),
+ { list__condense(ModulesList, Modules) }.
-:- pred process_module_list_2(list(string), list(list(string)),
+:- pred process_arg_list_2(list(string), list(list(string)),
io__state, io__state).
-:- mode process_module_list_2(in, out, di, uo) is det.
+:- mode process_arg_list_2(in, out, di, uo) is det.
-process_module_list_2([], []) --> [].
-process_module_list_2([Module0 | Modules0], [Module | Modules]) -->
- process_module(Module0, Module), !,
- process_module_list_2(Modules0, Modules).
+process_arg_list_2([], []) --> [].
+process_arg_list_2([Arg | Args], [Modules | ModulesList]) -->
+ process_arg(Arg, Modules), !,
+ process_arg_list_2(Args, ModulesList).
- % Open the file and process it.
+ % Figure out whether the argument is a module name or a file name.
+ % Open the specified file or module, and process it.
% Return the list of modules (including sub-modules,
% if they were compiled to seperate object files)
% that should be linked into the final executable.
-:- pred process_module(string, list(string), io__state, io__state).
-:- mode process_module(in, out, di, uo) is det.
+:- pred process_arg(string, list(string), io__state, io__state).
+:- mode process_arg(in, out, di, uo) is det.
-process_module(PathName, ModulesToLink) -->
+process_arg(Arg, ModulesToLink) -->
% All messages go to stderr
io__stderr_stream(StdErr),
io__set_output_stream(StdErr, _),
- { dir__split_name(PathName, DirName, BaseFileName) },
- ( { dir__this_directory(DirName) } ->
- { file_name_to_module_name(BaseFileName, ModuleName) },
-
+ % If the argument name ends in `.m', then we assume it is
+ % a file name.
+ ( { string__remove_suffix(Arg, ".m", FileName) } ->
globals__io_lookup_bool_option(generate_dependencies,
GenerateDeps),
( { GenerateDeps = yes } ->
- generate_dependencies(ModuleName),
+ generate_file_dependencies(FileName),
{ ModulesToLink = [] }
;
- process_module_2(ModuleName, ModulesToLink)
+ process_file_name(FileName, ModulesToLink)
)
;
- % Currently we don't allow directory names in the
- % command-line arguments, because it would confuse
- % the mapping between module names and file names.
- io__progname("mercury_compile", ProgName),
- io__write_strings([
- ProgName, ": Error in command-line argument `",
- PathName, "':\n",
- "arguments may not contain directory names.\n"]),
- io__set_exit_status(1),
- { ModulesToLink = [] }
+ % If it doesn't end in `.m', then we assume it is
+ % a module name. (Is it worth checking that the
+ % name doesn't contain directory seperators, and issuing
+ % a warning or error in that case?)
+ { file_name_to_module_name(Arg, ModuleName) },
+
+ globals__io_lookup_bool_option(generate_dependencies,
+ GenerateDeps),
+ ( { GenerateDeps = yes } ->
+ generate_module_dependencies(ModuleName),
+ { ModulesToLink = [] }
+ ;
+ process_module_name(ModuleName, ModulesToLink)
+ )
).
-:- pred process_module_2(module_name, list(string), io__state, io__state).
-:- mode process_module_2(in, out, di, uo) is det.
+:- pred process_module_name(module_name, list(string), io__state, io__state).
+:- mode process_module_name(in, out, di, uo) is det.
-process_module_2(ModuleName, ModulesToLink) -->
+process_module_name(ModuleName, ModulesToLink) -->
globals__io_lookup_bool_option(verbose, Verbose),
- maybe_write_string(Verbose, "% Parsing `"),
- module_name_to_file_name(ModuleName, ".m", no, FileName),
+ maybe_write_string(Verbose, "% Parsing module `"),
+ { prog_out__sym_name_to_string(ModuleName, ModuleNameString) },
+ maybe_write_string(Verbose, ModuleNameString),
+ maybe_write_string(Verbose, "' and imported interfaces...\n"),
+ read_mod(ModuleName, ".m", "Reading module", yes, Items, Error,
+ FileName), !,
+ globals__io_lookup_bool_option(statistics, Stats),
+ maybe_report_stats(Stats),
+ process_module(ModuleName, FileName, Items, Error, ModulesToLink).
+
+:- pred process_file_name(file_name, list(string), io__state, io__state).
+:- mode process_file_name(in, out, di, uo) is det.
+
+process_file_name(FileName, ModulesToLink) -->
+ globals__io_lookup_bool_option(verbose, Verbose),
+ maybe_write_string(Verbose, "% Parsing file `"),
maybe_write_string(Verbose, FileName),
maybe_write_string(Verbose, "' and imported interfaces...\n"),
- read_mod(ModuleName, ".m", "Reading module", yes, Items0, Error), !,
+ read_mod_from_file(FileName, ".m", "Reading file", yes, Items, Error,
+ ModuleName), !,
globals__io_lookup_bool_option(statistics, Stats),
maybe_report_stats(Stats),
+ { string__append(FileName, ".m", SourceFileName) },
+ process_module(ModuleName, SourceFileName, Items, Error, ModulesToLink).
+
+:- pred process_module(module_name, file_name, item_list, module_error,
+ list(string), io__state, io__state).
+:- mode process_module(in, in, in, in, out, di, uo) is det.
+process_module(ModuleName, FileName, Items, Error, ModulesToLink) -->
globals__io_lookup_bool_option(halt_at_syntax_errors, HaltSyntax),
globals__io_lookup_bool_option(make_interface, MakeInterface),
globals__io_lookup_bool_option(make_short_interface,
@@ -197,27 +204,27 @@
; { Error = yes, HaltSyntax = yes } ->
{ ModulesToLink = [] }
; { MakeInterface = yes } ->
- { split_into_submodules(ModuleName, Items0, SubModuleList) },
+ { split_into_submodules(ModuleName, Items, SubModuleList) },
list__foldl(make_interface(FileName), SubModuleList),
{ ModulesToLink = [] }
; { MakeShortInterface = yes } ->
- { split_into_submodules(ModuleName, Items0, SubModuleList) },
+ { split_into_submodules(ModuleName, Items, SubModuleList) },
list__foldl(make_short_interface, SubModuleList),
{ ModulesToLink = [] }
; { MakePrivateInterface = yes } ->
- { split_into_submodules(ModuleName, Items0, SubModuleList) },
+ { split_into_submodules(ModuleName, Items, SubModuleList) },
list__foldl(make_private_interface(FileName), SubModuleList),
{ ModulesToLink = [] }
; { ConvertToMercury = yes } ->
module_name_to_file_name(ModuleName, ".ugly", yes,
OutputFileName),
- convert_to_mercury(ModuleName, OutputFileName, Items0),
+ convert_to_mercury(ModuleName, OutputFileName, Items),
{ ModulesToLink = [] }
; { ConvertToGoedel = yes } ->
- convert_to_goedel(ModuleName, Items0),
+ convert_to_goedel(ModuleName, Items),
{ ModulesToLink = [] }
;
- { split_into_submodules(ModuleName, Items0, SubModuleList) },
+ { split_into_submodules(ModuleName, Items, SubModuleList) },
list__foldl(compile(FileName), SubModuleList),
list__map_foldl(module_to_link, SubModuleList, ModulesToLink)
@@ -278,8 +285,8 @@
io__state, io__state).
:- mode compile(in, in, di, uo) is det.
-compile(SourceFileName, ModuleName - Items0) -->
- grab_imported_modules(SourceFileName, ModuleName, Items0,
+compile(SourceFileName, ModuleName - Items) -->
+ grab_imported_modules(SourceFileName, ModuleName, Items,
Module, Error2),
( { Error2 \= fatal } ->
mercury_compile(Module)
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.74
diff -u -r1.74 modules.m
--- modules.m 1998/05/27 04:00:40 1.74
+++ modules.m 1998/05/28 08:59:47
@@ -108,20 +108,51 @@
%-----------------------------------------------------------------------------%
- % read_mod(ModuleName, Extension, Descr, Search, Items, Error):
+ % read_mod(ModuleName, Extension, Descr, Search, Items, Error,
+ % SourceFileName):
% Given a module name and a file extension (e.g. `.m',
% `.int', or `int2'), read in the list of items in that file.
+ % If Extension is ".m", and ModuleName is a nested module,
+ % then try searching for different filenames:
+ % for modules such as `foo.bar.baz.m' search first for
+ % `foo.bar.baz.m', then `bar.baz.m', then `baz.m'.
% If Search is yes, search all directories given by the option
% search_directories for the module.
+ % If the actual module name (as determined by the
+ % `:- module' declaration) does not match the specified
+ % module name, then report an error message.
+ % Return the actual source file name found
+ % (excluding the directory part).
+ %
+ % N.B. This reads a module given the module name.
+ % If you want to read a module given the file name,
+ % use `read_mod_from_file'.
+ %
+:- pred read_mod(module_name, string, string, bool,
+ item_list, module_error, file_name, io__state, io__state).
+:- mode read_mod(in, in, in, in, out, out, out, di, uo) is det.
+
+ % Similar to read_mod, but doesn't return error messages.
+:- pred read_mod_ignore_errors(module_name, string, string, bool,
+ item_list, module_error, file_name, io__state, io__state).
+:- mode read_mod_ignore_errors(in, in, in, in, out, out, out, di, uo) is det.
+
+ % read_mod_from_file(SourceFileName, Extension, Descr, Search, Items,
+ % Error, ModuleName):
+ % Given a file name and a file extension (e.g. `.m',
+ % `.int', or `int2'), read in the list of items in that file.
+ % If Search is yes, search all directories given by the option
+ % search_directories for the module.
+ % Return the module name (as determined by the
+ % `:- module' declaration, if any).
%
-:- pred read_mod(module_name, string, string, bool, item_list, module_error,
- io__state, io__state).
-:- mode read_mod(in, in, in, in, out, out, di, uo) is det.
-
- % Same as above, but doesn't return error messages.
-:- pred read_mod_ignore_errors(module_name, string, string, bool, item_list,
- module_error, io__state, io__state).
-:- mode read_mod_ignore_errors(in, in, in, in, out, out, di, uo) is det.
+ % N.B. This reads a module given the file name.
+ % If you want to read a module given the module name,
+ % use `read_mod'.
+ %
+:- pred read_mod_from_file(file_name, string, string, bool,
+ item_list, module_error, module_name, io__state, io__state).
+:- mode read_mod_from_file(in, in, in, in, out, out, out, di, uo) is det.
%-----------------------------------------------------------------------------%
@@ -330,7 +361,7 @@
%-----------------------------------------------------------------------------%
- % generate_dependencies(ModuleName):
+ % generate_module_dependencies(ModuleName):
% Generate the per-program makefile dependencies (`.dep') file
% for a program whose top-level module is `ModuleName'.
% This involves first transitively reading in all imported
@@ -338,8 +369,15 @@
% per-module makefile dependency (`.d') files for all those
% modules.
%
-:- pred generate_dependencies(module_name, io__state, io__state).
-:- mode generate_dependencies(in, di, uo) is det.
+:- pred generate_module_dependencies(module_name, io__state, io__state).
+:- mode generate_module_dependencies(in, di, uo) is det.
+
+ % generate_file_dependencies(FileName):
+ % Same as generate_module_dependencies, but takes
+ % a file name instead of a module name.
+ %
+:- pred generate_file_dependencies(file_name, io__state, io__state).
+:- mode generate_file_dependencies(in, di, uo) is det.
% get_dependencies(Items, ImportDeps, UseDeps).
% Get the list of modules that a list of items depends on.
@@ -1627,9 +1665,25 @@
%-----------------------------------------------------------------------------%
-generate_dependencies(ModuleName) -->
- % first, build up a map of the dependencies.
+generate_module_dependencies(ModuleName) -->
+ { map__init(DepsMap0) },
+ generate_dependencies(ModuleName, DepsMap0).
+
+generate_file_dependencies(FileName) -->
+ % read in the top-level file (to figure out its module name)
+ read_mod_from_file(FileName, ".m", "Reading file", no,
+ Items, Error, ModuleName),
+ { string__append(FileName, ".m", SourceFileName) },
+ { init_dependencies(SourceFileName, Error, ModuleName - Items,
+ ModuleImports) },
{ map__init(DepsMap0) },
+ { insert_into_deps_map(ModuleImports, DepsMap0, DepsMap1) },
+ generate_dependencies(ModuleName, DepsMap1).
+
+:- pred generate_dependencies(module_name, deps_map, io__state, io__state).
+:- mode generate_dependencies(in, in, di, uo) is det.
+generate_dependencies(ModuleName, DepsMap0) -->
+ % first, build up a map of the dependencies.
generate_deps_map([ModuleName], DepsMap0, DepsMap),
%
% check whether we could read the main `.m' file
@@ -1897,6 +1951,18 @@
:- mode generate_dep_file(in, in, in, in, di, uo) is det.
generate_dep_file(SourceFileName, ModuleName, DepsMap, DepStream) -->
+ %
+ % Some of the targets are based on the source file name
+ % rather than on the module name.
+ %
+ {
+ string__remove_suffix(SourceFileName, ".m", SourceFileBase)
+ ->
+ file_name_to_module_name(SourceFileBase, SourceModuleName)
+ ;
+ error("modules.m: source file name doesn't end in `.m'")
+ },
+
io__write_string(DepStream,
"# Automatically generated dependencies for module `"),
{ prog_out__sym_name_to_string(ModuleName, ModuleNameString) },
@@ -2085,7 +2151,7 @@
module_name_to_file_name(ModuleName, "_init.pic_o", yes,
InitPicObjFileName),
- module_name_to_file_name(ModuleName, "", no, ExeFileName),
+ module_name_to_file_name(SourceModuleName, "", no, ExeFileName),
io__write_strings(DepStream, [
"MLOBJS_DEPS += ", ExeFileName, "\n",
ExeFileName, " : $(", MakeVarName, ".os) ",
@@ -2095,7 +2161,8 @@
"\t $(", MakeVarName, ".os) $(MLOBJS) $(MLLIBS)\n\n"
]),
- module_name_to_file_name(ModuleName, ".split", yes, SplitExeFileName),
+ module_name_to_file_name(SourceModuleName, ".split", yes,
+ SplitExeFileName),
module_name_to_file_name(ModuleName, ".split.a", yes, SplitLibFileName),
io__write_strings(DepStream, [
SplitExeFileName, " : ", SplitLibFileName, " ",
@@ -2164,8 +2231,8 @@
InitCFileName, "\n\n"
]),
- module_name_to_file_name(ModuleName, ".nu", yes, NU_ExeFileName),
- module_name_to_file_name(ModuleName, ".nu.debug", yes,
+ module_name_to_file_name(SourceModuleName, ".nu", yes, NU_ExeFileName),
+ module_name_to_file_name(SourceModuleName, ".nu.debug", yes,
NU_DebugExeFileName),
io__write_strings(DepStream, [
NU_ExeFileName, " : $(", MakeVarName, ".nos)\n",
@@ -2177,9 +2244,9 @@
"$(", MakeVarName, ".nos)\n\n"
]),
- module_name_to_file_name(ModuleName, ".sicstus", yes,
+ module_name_to_file_name(SourceModuleName, ".sicstus", yes,
SicstusExeFileName),
- module_name_to_file_name(ModuleName, ".sicstus.debug", yes,
+ module_name_to_file_name(SourceModuleName, ".sicstus.debug", yes,
SicstusDebugExeFileName),
io__write_strings(DepStream, [
SicstusExeFileName, " : $(", MakeVarName, ".qls)\n",
@@ -2191,7 +2258,8 @@
" $(", MakeVarName, ".qls)\n\n"
]),
- module_name_to_file_name(ModuleName, ".check", no, CheckTargetName),
+ module_name_to_file_name(SourceModuleName, ".check", no,
+ CheckTargetName),
module_name_to_file_name(ModuleName, ".ints", no, IntsTargetName),
module_name_to_file_name(ModuleName, ".int3s", no, Int3sTargetName),
module_name_to_file_name(ModuleName, ".opts", no, OptsTargetName),
@@ -2211,7 +2279,8 @@
".trans_opt_dates)\n\n"
]),
- module_name_to_file_name(ModuleName, ".clean", no, CleanTargetName),
+ module_name_to_file_name(SourceModuleName, ".clean", no,
+ CleanTargetName),
io__write_strings(DepStream, [
"clean : ", CleanTargetName, "\n"
]),
@@ -2234,7 +2303,7 @@
io__write_string(DepStream, "\n"),
- module_name_to_file_name(ModuleName, ".change_clean", no,
+ module_name_to_file_name(SourceModuleName, ".change_clean", no,
ChangeCleanTargetName),
io__write_strings(DepStream, [
".PHONY : ", ChangeCleanTargetName, "\n",
@@ -2256,7 +2325,7 @@
DepFileName, "\n\n"
]),
- module_name_to_file_name(ModuleName, ".realclean", no,
+ module_name_to_file_name(SourceModuleName, ".realclean", no,
RealCleanTargetName),
io__write_strings(DepStream, [
"realclean : ", RealCleanTargetName, "\n"
@@ -2275,9 +2344,9 @@
"\t-rm -f $(", MakeVarName, ".ds)\n",
"\t-rm -f $(", MakeVarName, ".hs)\n"
]),
- module_name_to_file_name(ModuleName, ".nu.save", no,
+ module_name_to_file_name(SourceModuleName, ".nu.save", no,
NU_SaveExeFileName),
- module_name_to_file_name(ModuleName, ".nu.debug.save", no,
+ module_name_to_file_name(SourceModuleName, ".nu.debug.save", no,
NU_DebugSaveExeFileName),
io__write_strings(DepStream, [
"\t-rm -f ",
@@ -2296,9 +2365,9 @@
DepFileName, "\n\n"
]),
- module_name_to_file_name(ModuleName, ".clean_nu", no,
+ module_name_to_file_name(SourceModuleName, ".clean_nu", no,
CleanNU_TargetName),
- module_name_to_file_name(ModuleName, ".clean_sicstus", no,
+ module_name_to_file_name(SourceModuleName, ".clean_sicstus", no,
CleanSicstusTargetName),
io__write_strings(DepStream, [
"clean_nu : ", CleanNU_TargetName, "\n",
@@ -2482,24 +2551,26 @@
read_dependencies(ModuleName, Search, ModuleImportsList) -->
read_mod_ignore_errors(ModuleName, ".m",
- "Getting dependencies for module", Search, Items0, Error),
+ "Getting dependencies for module", Search, Items0, Error,
+ FileName0),
( { Items0 = [], Error = fatal } ->
read_mod_ignore_errors(ModuleName, ".int",
"Getting dependencies for module interface", Search,
- Items, _Error)
+ Items, _Error, FileName),
+ { SubModuleList = [ModuleName - Items] }
;
- { Items = Items0 }
+ { FileName = FileName0 },
+ { Items = Items0 },
+ { split_into_submodules(ModuleName, Items, SubModuleList) }
),
- module_name_to_file_name(ModuleName, ".m", no, FileName),
- { split_into_submodules(ModuleName, Items, SubModuleList) },
- { list__map(read_dependencies_2(FileName, Error), SubModuleList,
+ { list__map(init_dependencies(FileName, Error), SubModuleList,
ModuleImportsList) }.
-:- pred read_dependencies_2(file_name, module_error,
+:- pred init_dependencies(file_name, module_error,
pair(module_name, item_list), module_imports).
-:- mode read_dependencies_2(in, in, in, out) is det.
+:- mode init_dependencies(in, in, in, out) is det.
-read_dependencies_2(FileName, Error, ModuleName - Items, ModuleImports) :-
+init_dependencies(FileName, Error, ModuleName - Items, ModuleImports) :-
get_ancestors(ModuleName, ParentDeps),
get_dependencies(Items, ImplImportDeps0, ImplUseDeps0),
@@ -2528,8 +2599,78 @@
%-----------------------------------------------------------------------------%
-read_mod(ModuleName, Extension, Descr, Search, Items, Error) -->
- module_name_to_file_name(ModuleName, Extension, no, FileName),
+read_mod(ModuleName, Extension, Descr, Search, Items, Error, FileName) -->
+ read_mod_2(no, ModuleName, ModuleName, Extension, Descr, Search,
+ Items, Error, FileName).
+
+read_mod_ignore_errors(ModuleName, Extension, Descr, Search,
+ Items, Error, FileName) -->
+ read_mod_2(yes, ModuleName, ModuleName, Extension, Descr, Search,
+ Items, Error, FileName).
+
+:- pred read_mod_2(bool, module_name, module_name, string, string,
+ bool, item_list, module_error, file_name,
+ io__state, io__state).
+:- mode read_mod_2(in, in, in, in, in, in, out, out, out, di, uo)
+ is det.
+
+read_mod_2(IgnoreErrors, ModuleName, PartialModuleName,
+ Extension, Descr, Search, Items, Error, FileName) -->
+ module_name_to_file_name(PartialModuleName, Extension, no, FileName0),
+ globals__io_lookup_bool_option(very_verbose, VeryVerbose),
+ maybe_write_string(VeryVerbose, "% "),
+ maybe_write_string(VeryVerbose, Descr),
+ maybe_write_string(VeryVerbose, " `"),
+ maybe_write_string(VeryVerbose, FileName0),
+ maybe_write_string(VeryVerbose, "'... "),
+ maybe_flush_output(VeryVerbose),
+ prog_io__read_module(FileName0, ModuleName, Search,
+ Error0, ActualModuleName, Messages, Items0),
+ check_module_has_expected_name(FileName0,
+ ModuleName, ActualModuleName),
+ ( { IgnoreErrors = yes } ->
+ (
+ { Error0 = fatal },
+ { Items0 = [] }
+ ->
+ maybe_write_string(VeryVerbose, "not found.\n")
+ ;
+ maybe_write_string(VeryVerbose, "done.\n")
+ )
+ ;
+ ( { Error0 = fatal } ->
+ maybe_write_string(VeryVerbose, "fatal error(s).\n"),
+ io__set_exit_status(1)
+ ; { Error0 = yes } ->
+ maybe_write_string(VeryVerbose, "parse error(s).\n"),
+ io__set_exit_status(1)
+ ;
+ maybe_write_string(VeryVerbose, "successful parse.\n")
+ ),
+ prog_out__write_messages(Messages)
+ ),
+ %
+ % if that didn't work, and we're reading in the source (.m)
+ % file for a nested module, try again after dropping one
+ % level of module qualifiers.
+ %
+ (
+ { Error0 = fatal },
+ { Items0 = [] },
+ { Extension = ".m" },
+ { PartialModuleName = qualified(Parent, Child) }
+ ->
+ { drop_one_qualifier(Parent, Child, PartialModuleName2) },
+ read_mod_2(IgnoreErrors, ModuleName, PartialModuleName2,
+ Extension, Descr, Search, Items, Error, FileName)
+ ;
+ { Error = Error0 },
+ { Items = Items0 },
+ { FileName = FileName0 }
+ ).
+
+read_mod_from_file(FileName, Extension, Descr, Search,
+ Items, Error, ModuleName) -->
globals__io_lookup_bool_option(very_verbose, VeryVerbose),
maybe_write_string(VeryVerbose, "% "),
maybe_write_string(VeryVerbose, Descr),
@@ -2537,8 +2678,11 @@
maybe_write_string(VeryVerbose, FileName),
maybe_write_string(VeryVerbose, "'... "),
maybe_flush_output(VeryVerbose),
- prog_io__read_module(FileName, ModuleName, Search,
- Error, Messages, Items),
+ { string__append(FileName, Extension, FullFileName) },
+ { dir__basename(FileName, BaseFileName) },
+ { file_name_to_module_name(BaseFileName, DefaultModuleName) },
+ prog_io__read_module(FullFileName, DefaultModuleName, Search,
+ Error, ModuleName, Messages, Items),
( { Error = fatal } ->
maybe_write_string(VeryVerbose, "fatal error(s).\n"),
io__set_exit_status(1)
@@ -2561,19 +2705,6 @@
combine_module_errors(no, Error, Error).
*/
-read_mod_ignore_errors(ModuleName, Extension, Descr, Search, Items, Error) -->
- module_name_to_file_name(ModuleName, Extension, no, FileName),
- globals__io_lookup_bool_option(very_verbose, VeryVerbose),
- maybe_write_string(VeryVerbose, "% "),
- maybe_write_string(VeryVerbose, Descr),
- maybe_write_string(VeryVerbose, " `"),
- maybe_write_string(VeryVerbose, FileName),
- maybe_write_string(VeryVerbose, "'... "),
- maybe_flush_output(VeryVerbose),
- prog_io__read_module(FileName, ModuleName, Search,
- Error, _Messages, Items),
- maybe_write_string(VeryVerbose, "done.\n").
-
%-----------------------------------------------------------------------------%
% process_module_private_interfaces(Ancestors, DirectImports0,
@@ -2614,7 +2745,7 @@
;
read_mod(Ancestor, ".int0",
"Reading private interface for module", yes,
- PrivateIntItems, PrivateIntError),
+ PrivateIntItems, PrivateIntError, _AncestorFileName),
{ strip_off_interface_decl(PrivateIntItems, Items) },
{ maybe_add_int_error(PrivateIntError, ModError0, ModError) },
@@ -2664,7 +2795,7 @@
;
read_mod(Import, Ext,
"Reading interface for module", yes,
- LongIntItems, LongIntError),
+ LongIntItems, LongIntError, _LongIntFileName),
{ strip_off_interface_decl(LongIntItems, Items) },
{ maybe_add_int_error(LongIntError, ModError0, ModError) },
@@ -2844,7 +2975,7 @@
;
read_mod(Import, Ext,
"Reading short interface for module", yes,
- ShortIntItems, ShortIntError),
+ ShortIntItems, ShortIntError, _ImportFileName),
{ strip_off_interface_decl(ShortIntItems, Items) },
{ maybe_add_int_error(ShortIntError, ModError0, ModError) },
Index: compiler/prog_io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io.m,v
retrieving revision 1.171
diff -u -r1.171 prog_io.m
--- prog_io.m 1998/05/26 19:19:22 1.171
+++ prog_io.m 1998/05/27 19:43:01
@@ -62,13 +62,17 @@
% This module (prog_io) exports the following predicates:
- % prog_io__read_module(FileName, ModuleName, Search, Error,
- % Messages, Program)
- % Reads and parses the module 'ModuleName'.
+ % prog_io__read_module(FileName, DefaultModuleName, Search, Error,
+ % ActualModuleName, Messages, Program)
+ % Reads and parses the module in file `FileName',
+ % using the default module name `DefaultModuleName'.
% If Search is yes, search directories given by the option
% search_directories.
% Error is `fatal' if the file coudn't be opened, `yes'
% if a syntax error was detected, and `no' otherwise.
+ % ActualModuleName is the module name specified in the
+ % `:- module' declaration, if any, or the DefaultModuleName
+ % if there is no `:- module' declaration.
% Messages is a list of warning/error messages.
% Program is the parse tree.
@@ -80,16 +84,26 @@
:- type file_name == string.
:- type dir_name == string.
-:- pred prog_io__read_module(file_name, module_name, bool, module_error,
- message_list, item_list, io__state, io__state).
-:- mode prog_io__read_module(in, in, in, out, out, out, di, uo) is det.
+:- pred prog_io__read_module(file_name, module_name, bool,
+ module_error, module_name, message_list, item_list,
+ io__state, io__state).
+:- mode prog_io__read_module(in, in, in, out, out, out, out, di, uo) is det.
% Same as prog_io__read_module, but use intermod_directories
% instead of search_directories when searching for the file.
-:- pred prog_io__read_opt_file(file_name, module_name, bool, module_error,
- message_list, item_list, io__state, io__state).
+ % Also report an error if the actual module name doesn't match
+ % the expected module name.
+:- pred prog_io__read_opt_file(file_name, module_name, bool,
+ module_error, message_list, item_list, io__state, io__state).
:- mode prog_io__read_opt_file(in, in, in, out, out, out, di, uo) is det.
+ % check_module_has_expected_name(FileName, ExpectedName, ActualName):
+ % Check that two module names are equal,
+ % and report an error if they aren't.
+:- pred check_module_has_expected_name(file_name, module_name, module_name,
+ io__state, io__state).
+:- mode check_module_has_expected_name(in, in, in, di, uo) is det.
+
% search_for_file(Dirs, FileName, Found, IO0, IO)
%
% Search Dirs for FileName, opening the file if it is found.
@@ -170,21 +184,42 @@
:- import_module prog_io_goal, prog_io_dcg, prog_io_pragma, prog_io_util.
:- import_module prog_io_typeclass.
-:- import_module hlds_data, hlds_pred, prog_util, globals, options, (inst).
+:- import_module hlds_data, hlds_pred, prog_util, prog_out.
+:- import_module globals, options, (inst).
:- import_module purity.
:- import_module int, string, std_util, parser, term_io, dir, require.
%-----------------------------------------------------------------------------%
-prog_io__read_module(FileName, ModuleName, Search, Error, Messages, Items) -->
- prog_io__read_module_2(FileName, ModuleName, Search,
- search_directories, Error, Messages, Items).
+prog_io__read_module(FileName, DefaultModuleName, Search,
+ Error, ModuleName, Messages, Items) -->
+ prog_io__read_module_2(FileName, DefaultModuleName, Search,
+ search_directories, Error, ModuleName, Messages, Items).
-prog_io__read_opt_file(FileName, ModuleName, Search,
+prog_io__read_opt_file(FileName, DefaultModuleName, Search,
Error, Messages, Items) -->
- prog_io__read_module_2(FileName, ModuleName, Search,
- intermod_directories, Error, Messages, Items).
+ prog_io__read_module_2(FileName, DefaultModuleName, Search,
+ intermod_directories, Error, ModuleName, Messages, Items),
+ check_module_has_expected_name(FileName,
+ DefaultModuleName, ModuleName).
+
+check_module_has_expected_name(FileName, ExpectedName, ActualName) -->
+ ( { ActualName \= ExpectedName } ->
+ { prog_out__sym_name_to_string(ActualName, ActualString) },
+ { prog_out__sym_name_to_string(ExpectedName, ExpectedString) },
+ io__stderr_stream(ErrStream),
+ io__write_strings(ErrStream, [
+ "Error: file `", FileName,
+ "' contains the wrong module.\n",
+ "Expected module `", ExpectedString,
+ "', found module `", ActualString, "'.\n"
+ ]),
+ io__set_exit_status(1)
+ ;
+ []
+ ).
+
% This implementation uses io__read_term to read in the program
% term at a time, and then converts those terms into clauses and
@@ -195,11 +230,13 @@
% late-input modes.)
:- pred prog_io__read_module_2(file_name, module_name, bool, option,
- module_error, message_list, item_list, io__state, io__state).
-:- mode prog_io__read_module_2(in, in, in, in, out, out, out, di, uo) is det.
+ module_error, module_name, message_list, item_list,
+ io__state, io__state).
+:- mode prog_io__read_module_2(in, in, in, in, out, out, out, out,
+ di, uo) is det.
prog_io__read_module_2(FileName, DefaultModuleName, Search,
- SearchOpt, Error, Messages, Items) -->
+ SearchOpt, Error, ModuleName, Messages, Items) -->
(
{ Search = yes }
->
@@ -211,7 +248,8 @@
),
search_for_file(Dirs, FileName, R),
( { R = yes } ->
- read_all_items(DefaultModuleName, Messages, Items, Error),
+ read_all_items(DefaultModuleName, ModuleName,
+ Messages, Items, Error),
io__seen
;
io__progname_base("prog_io.m", Progname),
@@ -222,7 +260,8 @@
dummy_term(Term),
Messages = [Message - Term],
Error = fatal,
- Items = []
+ Items = [],
+ ModuleName = DefaultModuleName
}
).
@@ -344,17 +383,18 @@
%
% We use a continuation-passing style here.
-:- pred read_all_items(module_name, message_list, item_list, module_error,
+:- pred read_all_items(module_name, module_name,
+ message_list, item_list, module_error,
io__state, io__state).
-:- mode read_all_items(in, out, out, out, di, uo) is det.
+:- mode read_all_items(in, out, out, out, out, di, uo) is det.
-read_all_items(ModuleName, Messages, Items, Error) -->
+read_all_items(DefaultModuleName, ModuleName, Messages, Items, Error) -->
%
% read all the items (the first one is handled specially)
%
io__input_stream(Stream),
io__input_stream_name(Stream, SourceFileName),
- read_first_item(ModuleName, SourceFileName,
+ read_first_item(DefaultModuleName, SourceFileName, ModuleName,
RevMessages, RevItems0, Error0),
%
@@ -382,11 +422,12 @@
% and then if it turns out to not be a `:- module' declaration
% we reparse it in the default module scope. Blecchh.
%
-:- pred read_first_item(module_name, file_name,
+:- pred read_first_item(module_name, file_name, module_name,
message_list, item_list, module_error, io__state, io__state).
-:- mode read_first_item(in, in, out, out, out, di, uo) is det.
+:- mode read_first_item(in, in, out, out, out, out, di, uo) is det.
-read_first_item(DefaultModuleName, SourceFileName, Messages, Items, Error) -->
+read_first_item(DefaultModuleName, SourceFileName, ModuleName,
+ Messages, Items, Error) -->
globals__io_lookup_bool_option(warn_missing_module_name, WarnMissing),
globals__io_lookup_bool_option(warn_wrong_module_name, WarnWrong),
@@ -410,7 +451,7 @@
{ FirstItem = pragma(source_file(NewSourceFileName)) }
->
read_first_item(DefaultModuleName, NewSourceFileName,
- Messages, Items, Error)
+ ModuleName, Messages, Items, Error)
;
%
% check if the first term was a `:- module' decl
@@ -430,18 +471,19 @@
ModuleName = DefaultModuleName,
Messages0 = []
;
+ prog_out__sym_name_to_string(StartModuleName,
+ StartModuleNameString),
+ string__append_list(["source file `", SourceFileName,
+ "' contains module named `", StartModuleNameString,
+ "'"], WrongModuleWarning),
maybe_add_warning(WarnWrong, MaybeFirstTerm, FirstContext,
- "incorrect module name in `:- module' declaration",
- [], Messages0),
+ WrongModuleWarning, [], Messages0),
- % XXX Which one should we use here?
- % Tradition says that the default module
- % name (computed from the filename) takes
- % precedence, but I don't know why;
- % using the declared one might be better.
- % For the moment I'll leave it as is,
- % in case changing it would break something.
- ModuleName = DefaultModuleName
+ % Which one should we use here?
+ % We used to use the default module name
+ % (computed from the filename)
+ % but now we use the declared one.
+ ModuleName = StartModuleName
},
{ make_module_decl(ModuleName, FirstContext, FixedFirstItem) },
{ Items0 = [FixedFirstItem] },
Index: compiler/trans_opt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/trans_opt.m,v
retrieving revision 1.9
diff -u -r1.9 trans_opt.m
--- trans_opt.m 1998/03/18 08:07:48 1.9
+++ trans_opt.m 1998/05/27 17:39:33
@@ -207,7 +207,7 @@
maybe_write_string(VeryVerbose, "% done.\n"),
module_name_to_file_name(Import, ".trans_opt", no, FileName),
- prog_io__read_module(FileName, Import, yes,
+ prog_io__read_opt_file(FileName, Import, yes,
ModuleError, Messages, Items1),
update_error_status(ModuleError, Messages, Error0, Error1),
{ list__append(Items0, Items1, Items2) },
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.123
diff -u -r1.123 user_guide.texi
--- user_guide.texi 1998/05/20 11:11:49 1.123
+++ user_guide.texi 1998/05/28 08:56:18
@@ -123,9 +123,9 @@
@node Filenames
@chapter File naming conventions
-Mercury source files should be named @file{*.m}.
-Each Mercury source file must contain a single Mercury module
-whose name should be the same as the filename without
+Mercury source files must be named @file{*.m}.
+Each Mercury source file should contain a single Mercury module
+whose module name should be the same as the filename without
the @samp{.m} extension.
The Mercury implementation uses a variety of intermediate files, which
@@ -137,6 +137,10 @@
subdirectory, where you can happily ignore them.
Thus you may wish to skip the rest of this chapter.
+In cases where the source file name and module name don't match,
+the names for intermediate files are based on the name of the
+module from which they are derived, not on the source file name.
+
Files ending in @file{.int}, @file{.int0}, @file{.int2} and @file{.int3}
are interface files; these are generated automatically by the compiler,
using the @samp{--make-interface} (or @samp{--make-int}),
@@ -183,22 +187,24 @@
Some of its options (e.g. @samp{-c}, @samp{-o}, and @samp{-I})
have a similar meaning to that in other Unix compilers.
-Arguments to @samp{mmc} that name Mercury source files
-may omit the @samp{.m} suffix.
+Arguments to @samp{mmc} may be either file names (ending in @samp{.m}),
+or module names. For a module name such as @samp{foo.bar.baz},
+the compiler will look for the source in files @file{foo.bar.baz.m},
+ at file{bar.baz.m}, and @file{baz.m}, in that order.
-To compile a program which consists of just a single module,
+To compile a program which consists of just a single source file,
use the command
@example
-mmc @var{module}.m
+mmc @var{filename}.m
@end example
Unlike traditional Unix compilers, however,
- at samp{mmc} will put the executable into a file called @file{@var{module}},
+ at samp{mmc} will put the executable into a file called @file{@var{filename}},
not @file{a.out}.
-For programs that consist of more than one module, we @emph{strongly} recommend
-that you use Mmake (@pxref{Using Mmake}). Mmake will perform
+For programs that consist of more than one source file, we @emph{strongly}
+recommend that you use Mmake (@pxref{Using Mmake}). Mmake will perform
all the steps listed below, using automatic dependency analysis
to ensure that things are done in the right order, and that
steps are not repeated unnecessarily.
@@ -206,39 +212,45 @@
of how the Mercury implementation goes about building programs.
Thus you may wish to skip the rest of this chapter.
-To compile a module to object code without creating an executable,
+To compile a source file to object code without creating an executable,
use the command
@example
-mmc -c @var{module}.m
+mmc -c @var{filename}.m
@end example
- at samp{mmc} will put the object code into a file called @file{@var{module}.o}.
+ at samp{mmc} will put the object code into a file called @file{@var{module}.o},
+where @var{module} is the name of the Mercury module defined in
+ at file{@var{filename}.m}.
It also will leave the intermediate C code in a file called
@file{@var{module}.c}.
+If the source file contains nested modules, then each sub-module will get
+compiled to separate C and object files.
Before you can compile a module,
you must make the interface files
for the modules that it imports (directly or indirectly).
-You can create the interface files for one or more modules using the commands
+You can create the interface files for one or more source files
+using the following commands:
@example
-mmc --make-short-int @var{module1}.m @var{module2}.m ...
-mmc --make-int @var{module1}.m @var{module2}.m ...
+mmc --make-short-int @var{filename1}.m @var{filename2}.m ...
+mmc --make-priv-int @var{filename1}.m @var{filename2}.m ...
+mmc --make-int @var{filename1}.m @var{filename2}.m ...
@end example
If you are going to compile with @samp{--intermodule-optimization} enabled,
then you also need to create the optimization interface files.
@example
-mmc --make-opt-int @var{module1}.m @var{module2}.m ...
+mmc --make-opt-int @var{filename1}.m @var{filename2}.m ...
@end example
If you are going to compile with @samp{--transitive-intermodule-optimization}
enabled, then you also need to create the transitive optimization files.
@example
-mmc --make-trans-opt @var{module1}.m @var{module2}.m ...
+mmc --make-trans-opt @var{filename1}.m @var{filename2}.m ...
@end example
Given that you have made all the interface files,
@@ -247,10 +259,10 @@
using the command
@example
-mmc @var{module1}.m @var{module2}.m ...
+mmc @var{filename1}.m @var{filename2}.m ...
@end example
-This will by default put the resulting executable in @file{@var{module1}},
+This will by default put the resulting executable in @file{@var{filename1}},
but you can use the @samp{-o @var{filename}} option to specify a different
name for the output file, if you so desire.
@@ -342,7 +354,7 @@
The command
@example
-mmc -e @var{module1}.m ...
+mmc -e @var{filename1}.m ...
@end example
causes the Mercury compiler
@@ -363,10 +375,10 @@
@node Using NU-Prolog
@section Using NU-Prolog
-You can compile a Mercury source module using NU-Prolog via the command
+You can compile a Mercury source file using NU-Prolog via the command
@example
-mnc @var{module1}.m ...
+mnc @var{filename1}.m ...
@end example
@samp{mnc} is the Mercury variant of @samp{nc}, the NU-Prolog compiler.
@@ -388,7 +400,7 @@
You can link these together using the command
@example
-mnl -o @var{main_module} @var{module1}.no ...
+mnl -o @var{main_module} @var{filename1}.no ...
@end example
Ignore any warnings such as
@@ -421,7 +433,7 @@
with a normal consulting command such as
@example
-['@var{module}.m'].
+['@var{filename}.m'].
@end example
You can also use the @file{--debug} option to @samp{mnl} when linking.
@@ -470,7 +482,7 @@
The command to use is just
@example
-sicstus_conv @var{module}.m
+sicstus_conv @var{filename}.m
@end example
By default, @samp{msc} compiles files to machine code using
@@ -669,10 +681,14 @@
@section Hazards of using Prolog
There are some Mercury programs which are not valid Prolog programs.
+Programs which make use of the more advanced features of Mercury will
+not work with NU-Prolog or SICStus Prolog.
In particular, Mercury programs that use functions will generally not
be valid Prolog programs (with the exception that the basic arithmetic
functions such as @samp{+}, @samp{-}, etc., will work fine if you use
Prolog's @samp{is} predicate).
+Also the use of features such as type classes, lambda expressions,
+non-trivial use of the module system, etc. will cause problems.
Also, Mercury will always reorder goals
to ensure that they are mode-correct
@@ -711,7 +727,7 @@
Mmake, short for ``Mercury Make'',
is a tool for building Mercury programs
that is built on top of ordinary or GNU Make @footnote{
-We aim to eventually add support for ordinary ``Make'' programs,
+We might eventually add support for ordinary ``Make'' programs,
but currently only GNU Make is supported.}.
With Mmake, building even a complicated Mercury program
consisting of a number of modules is as simple as
@@ -812,7 +828,8 @@
belonging to the named @var{main-module} or its imported modules.
@item @var{main-module}.change_clean
-Removes files that need updating when changing garbage collection method or
+Removes files that need updating when changing compilation model
+(@pxref{Compilation model options}) or
when enabling inter-module optimization.
Specifically, this will remove all the @samp{.c}, @samp{.s}, @samp{.o},
@samp{.dep} and executable files belonging to the named @var{main-module}
@@ -924,15 +941,41 @@
@node Writing libraries
@section Writing libraries
-A Mercury library is identified by a top-level module, which must
-directly or indirectly use (import) all of the modules in that
-library. It may be as simple as this @file{mypackage.m} file:
+A Mercury library is identified by a top-level module,
+which should contain all of the modules in that library.
+It may be as simple as this @file{mypackage.m} file:
@example
:- module mypackage.
-:- import_module foo, bar, baz.
+:- interface
+:- include_module foo, bar, baz.
@end example
+ at noindent
+This defines a module @samp{mypackage} containing
+sub-modules @samp{mypackage:foo}, @samp{mypackage:bar},
+and @samp{mypackage:baz}.
+
+It is also possible to build libraries of unrelated
+modules, so long as the top-level module imports all
+the necessary modules. For example:
+
+ @example
+ :- module blah.
+ :- import_module fee, fie, foe, fum.
+ @end example
+
+ at noindent
+This example defines a module @samp{blah}, which has
+no functionality of its own, and which is just used
+for grouping the unrelated modules @samp{fee},
+ at samp{fie}, @samp{foe}, and @samp{fum}.
+
+Generally it is better style for each library to consist
+of a single module which encapsulates its sub-modules,
+as in the first example, rather than just a group of
+unrelated modules, as in the second example.
+
@node Building libraries
@section Building libraries
@@ -1422,10 +1465,15 @@
@code{mmc} is invoked as
@example
-mmc [@var{options}] @var{modules}
+mmc [@var{options}] @var{arguments}
@end example
-For module names, the trailing @file{.m} is optional.
+Arguments can be either module names or file names.
+Arguments ending in @samp{.m} are assumed to be file names,
+while other arguments are assumed to be module names.
+If you specify a module name such as @samp{foo.bar.baz},
+the compiler will look for the source in files @file{foo.bar.baz.m},
+ at file{bar.baz.m}, and @file{baz.m}, in that order.
Options are either short (single-letter) options preceded by a single @samp{-},
or long options preceded by @samp{--}.
--
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