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