Files
mercury/compiler/prog_out.m
Simon Taylor 27d156bbb5 Implemented a :- use_module directive. This is the same as
Estimated hours taken: 14

Implemented a :- use_module directive. This is the same as
:- import_module, except all uses of the imported items
must be explicitly module qualified.

:- use_module is implemented by ensuring that unqualified versions
of items only get added to the HLDS symbol tables if they were imported
using import_module.

Indirectly imported items (from `.int2' files) and items declared in `.opt'
files are treated as if they were imported with use_module, since all uses
of them should be module qualified.

compiler/module_qual.m
	Keep two sets of type, mode and inst ids, those which can
	be used without qualifiers and those which can't.

	Renamed some predicates which no longer have unique names since
	'__' became a synonym for ':'.

	Made mq_info_set_module_used check whether the current item is in
	the interface, rather than relying on its caller to do the check.

	Removed init_mq_info_module, since make_hlds.m now uses the
	mq_info built during the module qualification pass.

compiler/prog_data.m
	Added a pseudo-declaration `used', same as `imported' except uses of
	the following items must be module qualified.

	Added a type need_qualifier to describe whether uses of an item
	need to be module qualified.

compiler/make_hlds.m
	Keep with the import_status whether current item was imported
	using a :- use_module directive.

	Use the mq_info structure passed in instead of building a new one.

	Ensure unqualified versions of constructors only get added to the
	cons_table if they can be used without qualification.

compiler/hlds_module.m
	Added an extra argument to predicate_table_insert of type
	need_qualifier.

	Only add predicates to the name and name-arity indices if they
	can be used without qualifiers.

	Changed the structure of the module-name-arity index, so that
	lookups can be made without an arity, such as when type-checking
	module qualified higher-order predicate constants. This does not
	change the interface to the module_name_arity index.

	Factored out some common code in predicate_table_insert which
	applies to both predicates and functions.

compiler/hlds_pred.m
	Removed the opt_decl import_status. It isn't needed any more
	since all uses of items declared in .opt files must now be
	module qualified.

	Added some documentation about when the clauses_info is valid.

compiler/intermod.m
	Ensure that predicate and function calls in the `.opt' file are
	module qualified. Use use_module instead of import_module in
	`.opt' files.

compiler/modules.m
	Handle use_module directives.

	Report a warning if both use_module and import_module declarations
	exist for the same module.

compiler/mercury_compile.m
	Collect inter-module optimization information before module
	qualification, since it can't cause conflicts any more. This means
	that the mq_info structure built in module_qual.m can be reused in
	make_hlds.m, instead of building a new one.

compiler/prog_out.m
	Add a predicate prog_out__write_module_list, which was moved
	here from module_qual.m.

compiler/typecheck.m
	Removed code to check that predicates declared in `.opt' files
	were being used appropriately, since this is now handled by
	use_module.

compiler/*.m
	Added missing imports, mostly for prog_data and term.

NEWS
compiler/notes/todo.html
doc/reference_manual.texi
	Document `:- use_module'.

tests/valid/intermod_lambda_test.m
tests/valid/intermod_lambda_test2.m
tests/invalid/errors.m
tests/invalid/errors2.m
	Test cases.
1997-06-29 23:11:42 +00:00

365 lines
10 KiB
Mathematica

%-----------------------------------------------------------------------------%
% Copyright (C) 1995 University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
:- module prog_out.
% Main author: fjh.
% This module defines some predicates which output various parts
% of the parse tree created by prog_io.
% WARNING - this module is mostly junk at the moment!
% Only the first hundred lines or so are meaningful.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- interface.
:- import_module prog_data, io, term.
:- pred prog_out__write_messages(message_list, io__state, io__state).
:- mode prog_out__write_messages(in, di, uo) is det.
:- pred prog_out__write_context(term__context, io__state, io__state).
:- mode prog_out__write_context(in, di, uo) is det.
:- pred prog_out__write_sym_name(sym_name, io__state, io__state).
:- mode prog_out__write_sym_name(in, di, uo) is det.
:- pred prog_out__write_module_spec(module_specifier, io__state, io__state).
:- mode prog_out__write_module_spec(in, di, uo) is det.
:- pred prog_out__write_module_list(list(module_name), io__state, io__state).
:- mode prog_out__write_module_list(in, di, uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module require, string, list, varset, std_util, term_io.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
% write out the list of error/warning messages which is
% returned when a module is parsed.
prog_out__write_messages([]) --> [].
prog_out__write_messages([Message | Messages]) -->
prog_out__write_message(Message),
prog_out__write_messages(Messages).
:- pred prog_out__write_message(pair(string, term), io__state, io__state).
:- mode prog_out__write_message(in, di, uo) is det.
prog_out__write_message(Msg - Term) -->
(
{ Term = term__functor(_Functor, _Args, Context) }
->
prog_out__write_context(Context)
;
[]
),
io__write_string(Msg),
(
{ Term = term__functor(term__atom(""), [], _Context2) }
->
io__write_string(".\n")
;
io__write_string(": "),
{ varset__init(VarSet) }, % XXX variable names in error messages
term_io__write_term_nl(VarSet, Term)
).
%-----------------------------------------------------------------------------%
% Write out the information in term context (at the moment, just
% the line number) in a form suitable for the beginning of an
% error message.
prog_out__write_context(Context) -->
{ term__context_file(Context, FileName) },
{ term__context_line(Context, LineNumber) },
( { FileName = "" } ->
[]
;
{ string__format("%s:%03d: ", [s(FileName), i(LineNumber)],
ContextMessage) },
io__write_string(ContextMessage)
).
%-----------------------------------------------------------------------------%
% write out a (possibly qualified) symbol name
prog_out__write_sym_name(qualified(ModuleSpec,Name)) -->
prog_out__write_module_spec(ModuleSpec),
io__write_string(":"),
io__write_string(Name).
prog_out__write_sym_name(unqualified(Name)) -->
io__write_string(Name).
% write out a module specifier
prog_out__write_module_spec(ModuleSpec) -->
io__write_string(ModuleSpec).
%-----------------------------------------------------------------------------%
prog_out__write_module_list([Import1, Import2, Import3 | Imports]) -->
io__write_strings(["`", Import1, "', "]),
write_module_list([Import2, Import3 | Imports]).
prog_out__write_module_list([Import1, Import2]) -->
io__write_strings(["`", Import1, "' and `", Import2 ,"'"]).
prog_out__write_module_list([Import]) -->
io__write_strings(["`", Import, "'"]).
prog_out__write_module_list([]) -->
{ error("prog_out__write_module_list") }.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
% THE REMAINDER OF THIS FILE IS JUNK THAT IS NOT USED.
% It has been made obsolete by mercury_to_mercury.m.
% However, the code below handles operator precedence better
% than mercury_to_mercury.m.
/**************************
% Please note that this code is the property of
% the University of Melbourne and is Copyright 1985, 1986, 1987, 1988 by it.
%
% All rights are reserved.
%
% Author: Philip Dart, 1988
% Based on a theme by Lawrence Byrd and Lee Naish.
% Fixed again by Lee Naish 9/88
% May bear some vague resemblance to some code written by Lawrence Byrd
% at Edinburgh a long time ago.
prog_out__writeDCGClause(Head, Body, VarSet) -->
% prog_out__get_op_prec("-->", 1, Prec),
{ Prec = 1199 },
prog_out__qwrite(Prec, VarSet, Head),
io__write_string(" -->"),
prog_out__write_goal(Body, 1, ',', VarSet).
:- type context ---> '(' ; (';') ; (then) ; (else) ; ','.
:- pred prog_out__write_goal(goal, int, context, varset, io__state, io__state).
:- mode prog_out__write_goal(in, in, in, in, di, uo) is det.
prog_out__write_goal(fail, I0, T, _VarSet) -->
prog_out__beforelit(T, I0),
io__write_string("fail").
prog_out__write_goal(true, I0, T, _VarSet) -->
prog_out__beforelit(T, I0),
io__write_string("true").
prog_out__write_goal(some(Vars,Goal), I0, T, VarSet) -->
prog_out__beforelit(T, I0),
io__write_string("some ["),
prog_out__write_var_list(Vars, VarSet),
io__write_string("] ("),
{ I1 is I0 + 1 },
prog_out__write_goal(Goal, I1, '(', VarSet),
io__write_string("\n"),
prog_out__indent(I0),
io__write_string(")").
prog_out__write_goal(all(Vars,Goal), I0, T, VarSet) -->
prog_out__beforelit(T, I0),
io__write_string("all ["),
prog_out__write_var_list(Vars, VarSet),
io__write_string("] ("),
{ I1 is I0 + 1 },
prog_out__write_goal(Goal, I1, '(', VarSet),
io__write_string("\n"),
prog_out__indent(I0),
io__write_string(")").
prog_out__write_goal((P, Q), I0, T, VarSet) -->
prog_out__write_goal(P, I0, T, VarSet),
io__write_string(","),
{if T = (',') then I = I0 else I is I0 + 1},
prog_out__write_goal(Q, I, (','), VarSet).
prog_out__write_goal(if_then_else(Vars,C,A,B), I, T, VarSet) -->
{if T = (then) then I1 is I + 1 else I1 = I},
(if {T = (else)} then
[]
else
io__write_string("\n"),
prog_out__indent(I1)
),
io__write_string(" if "),
prog_out__write_some_vars(VarSet, Vars),
prog_out__write_goal(C, I, '(', VarSet),
io__write_string(" then"),
prog_out__write_goal(A, I1, (then), VarSet),
io__write_string("\n"),
prog_out__indent(I1),
io__write_string("else"),
prog_out__write_goal(B, I1, (else), VarSet),
(if {T = (else)} then
[]
else
io__write_string("\n"),
prog_out__indent(I1),
io__write_string(")")
).
prog_out__write_goal(if_then(Vars,C,A), I, T, VarSet) -->
{if T = (then) then I1 is I + 1 else I1 = I},
(if {T = (else)} then
[]
else
io__write_string("\n"),
prog_out__indent(I1)
),
io__write_string(" if "),
prog_out__write_some_vars(VarSet, Vars),
prog_out__write_goal(C, I, '(', VarSet),
io__write_string(" then"),
prog_out__write_goal(A, I1, (then), VarSet),
(if {T = (else)} then
[]
else
io__write_string("\n"),
prog_out__indent(I1),
io__write_string(")")
).
prog_out__write_goal((P ; Q), I, T, VarSet) -->
(if {T = (;)} then
io__write_string("\t\n"),
prog_out__write_goal(P, I, (;), VarSet)
else
io__write_string("\n"),
prog_out__indent(I),
io__write_string("("),
prog_out__write_goal(P, I, '(', VarSet)
),
io__write_string("\n"),
prog_out__indent(I),
io__write_string(";"),
prog_out__write_goal(Q, I, (;), VarSet),
(if {T = (;)} then
[]
else
io__write_string("\n"),
prog_out__indent(I),
io__write_string(")")
).
prog_out__write_goal(not(A), I, _, VarSet) -->
io__write_string("not("),
prog_out__write_goal(A, I, '(', VarSet),
io__write_string(")").
prog_out__write_goal(call(X), I, T, VarSet) -->
prog_out__beforelit(T, I),
% Pos 1 of (,) has lowest prec of constructs
% prog_out__get_op_prec(",", 1, Prec),
{ Prec = 999 },
prog_out__qwrite(Prec, VarSet, X).
prog_out__write_var_list(_VarSet, Vars) -->
io__write_anything(Vars).
prog_out__write_some_vars(_VarSet, Vars) -->
io__write_string("some "),
io__write_anything(Vars). % XXX
:- pred prog_out__beforelit(context, int, io__state, io__state).
:- mode prog_out__beforelit(in, in, di, uo) is det.
prog_out__beforelit('(', _) -->
io__write_string("\t").
prog_out__beforelit((;), I) -->
io__write_string("\n"),
{ I1 is I + 1 },
prog_out__indent(I1),
io__write_string("\t").
prog_out__beforelit((then), I) -->
io__write_string("\n"),
{ I1 is I + 1 },
prog_out__indent(I1).
prog_out__beforelit((else), I) -->
io__write_string("\n"),
{ I1 is I + 1 },
prog_out__indent(I1).
prog_out__beforelit(',', I) -->
io__write_string("\n"),
prog_out__indent(I).
:- pred prog_out__indent(int, io__state, io__state).
:- mode prog_out__indent(int, di, uo) is det.
prog_out__indent(N) -->
(if {N > 0} then
io__write_string("\t"),
{ N1 is N - 1 },
prog_out__indent(N1)
else
[]
).
:- pred prog_out__qwrite(int, varset, term, io__state, io__state).
:- mode prog_out__qwrite(in, in, in, di, uo) is det.
% XXX problems with precedence
prog_out__qwrite(_Prec, VarSet, X) -->
term_io__write_term(VarSet, X).
:- pred prog_out__get_op_prec(string, int, int, io__state, io__state).
:- mode prog_out__get_op_prec(in, in, out, di, uo) is det.
prog_out__get_op_prec(Op, Pos, Prec) -->
term_io__current_ops(Ops),
{ get_prec_and_type(Op, Ops, Prec1, Type),
prog_out__op_adj(Pos, Type, Adj),
Prec is Prec1 - Adj
}.
get_prec_and_type(ThisOp, [Op|Ops], Prec, Type) :-
(if some [Prec1, Type1]
Op = op(Prec1, Type1, ThisOp)
then
Prec = Prec1,
Type = Type1
else
get_prec_and_type(ThisOp, Ops, Prec, Type)
).
:- pred prog_out__op_adj(int, op_type, int).
:- mode prog_out__op_adj(in, in, out) is det.
prog_out__op_adj(1, xfx, 1).
prog_out__op_adj(1, xfy, 1).
prog_out__op_adj(1, fxy, 1).
prog_out__op_adj(1, fxx, 1).
prog_out__op_adj(1, yfx, 0).
% prog_out__op_adj(1, yfy, 0).
prog_out__op_adj(1, fyx, 0).
prog_out__op_adj(1, fyy, 0).
prog_out__op_adj(2, xfx, 1).
prog_out__op_adj(2, xfy, 0).
prog_out__op_adj(2, fxy, 0).
prog_out__op_adj(2, fxx, 1).
prog_out__op_adj(2, yfx, 1).
% prog_out__op_adj(2, yfy, 0).
prog_out__op_adj(2, fyx, 1).
prog_out__op_adj(2, fyy, 0).
prog_out__op_adj(1, xf, 1).
prog_out__op_adj(1, fx, 1).
prog_out__op_adj(1, yf, 0).
prog_out__op_adj(1, fy, 0).
******************************/