Files
mercury/compiler/prog_util.m
Andrew Bromage 9b7f11c6dd Reorganisation of modules to do with the inst data type.
Estimated hours taken: 20

Reorganisation of modules to do with the inst data type.

This is actually the first installment of the alias tracking mode
checker in disguise.  A very good disguise.  The rationale for
this reorganisation is to reduce coupling in the part of the mode
checker which is _not_ in this change (ie most of it).

Alias tracking requires a new kind of inst, alias(inst_key), where
an inst_key is a handle on some other sub-inst.  With it goes a
data structure in which to store dereferenced insts and all the
operations which go with it.  This code will go in the new module
inst.m so that it doesn't have to go in prog_data.m.  (I briefly
considered putting it in instmap.m however this introduces some
bad coupling since instmap.m imports hlds_module.m.  Putting it
in prog_data.m would cause hlds_*.m to depend on prog_data.m,
but we have designed things so that the dependencies go in the
other direction.)

The remainder of the reorganisation is a general cleanup: the
inst testing predicates (inst_is_*) have been moved out of
mode_util because they are not actually operations on modes at
all, and have been moved into inst_match.  inst_match has then
been split because otherwise it would be 2000 lines long and
will get significantly bigger when aliasing is added.  Roughly
speaking, any operations which create new insts from old ones
have been moved into a new module, inst_util while any operations
which test the values of insts remain in inst_match.

Also included are the removal of some NU-Prologisms since the
NU-Prolog version of the compiler is no longer supported.  Two
changes here:

	- Removal of some when declarations.
	- A gross hack in inst_is_*_2, where two copies of
	  the same inst were passed into the predicate so that
	  one could be switched on.  Thank NU-Prolog's lack of
	  common subexpression elimination.

compiler/inst.m:
	New module which contains the data types inst, uniqueness,
	pred_inst_info, bound_inst.

compiler/inst_util.m:
	New module which contains predicates which perform mode
	checking-like operations on insts.

	Moved in:
		abstractly_unify_inst, abstractly_unify_inst_functor,
		inst_merge, make_mostly_uniq_inst (from inst_match.m)

compiler/inst_match.m:
	Moved out:
		inst_merge, make_mostly_uniq_inst,
		abstractly_unify_inst, abstractly_unify_inst_functor
			(to inst_util.m)

	Moved in:
		inst_is_*, inst_list_is_*, bound_inst_list_is_*
			(from mode_util.m)

	Now exported:
		unique_matches_initial/2, unique_matches_final/2
		inst_contains_instname/3, pred_inst_matches/3
		(They are required by inst_util.m, and they are
		useful in their own right.)

compiler/instmap.m:
	instmap_delta_lookup_var/3 reincarnated as
	instmap_delta_search_var/3.  The reason for this change is
	that previously, instmap_delta_lookup_var simply returned
	`free' if the searched-for var did not occur in the
	instmap_delta.  This is somewhat non-obvious behaviour.
	instmap_delta_search_var/3 fails in such a situation.

compiler/mode_util.m:
	Moved out:
		inst_is_*, inst_list_is_*, bound_inst_list_is_*
			(to inst_match.m)
		(These are not really operations on modes.)

compiler/modecheck_call.m:
	Moved in modecheck_higher_order_func_call/5, from modecheck_unify.m

compiler/modecheck_unify.m:
	Moved out modecheck_higher_order_func_call/5, to modecheck_call.m
	where it should have been all along.

compiler/prog_data.m:
	Moved out the types inst, uniqueness, pred_inst_info,
	bound_inst (to inst.m).

compiler/common.m:
compiler/cse_detection.m:
compiler/fact_table.m:
compiler/higher_order.m:
compiler/hlds_data.m:
compiler/hlds_goal.m:
compiler/hlds_out.m:
compiler/intermod.m:
compiler/liveness.m:
compiler/llds.m:
compiler/make_hlds.m:
compiler/mercury_to_mercury.m:
compiler/mode_debug.m:
compiler/mode_errors.m:
compiler/mode_info.m:
compiler/modes.m:
compiler/module_qual.m:
compiler/polymorphism.m:
compiler/prog_io.m:
compiler/prog_io_util.m:
compiler/prog_util.m:
compiler/simplify.m:
compiler/switch_detection.m:
compiler/unify_proc.m:
compiler/unique_modes.m:
	Miscellaneous minor changes to cope with the above changes.

compiler/notes/compiler_design.html:
	Document the new modules.
1997-07-24 01:27:21 +00:00

199 lines
7.9 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.
%-----------------------------------------------------------------------------%
% main author: fjh
% various utility predicates acting on the parse tree data
% structure defined in prog_data.m.
:- module prog_util.
:- interface.
:- import_module list, term.
:- import_module prog_data.
%-----------------------------------------------------------------------------%
% Convert a sym_name into a string.
:- pred unqualify_name(sym_name, string).
:- mode unqualify_name(in, out) is det.
:- pred sym_name_get_module_name(sym_name, module_name, module_name).
:- mode sym_name_get_module_name(in, in, out) is det.
% Given a possible module qualified sym_name and a list of
% argument types and a context, construct a term. This is
% used to construct types.
:- pred construct_qualified_term(sym_name, list(term), term).
:- mode construct_qualified_term(in, in, out) is det.
:- pred construct_qualified_term(sym_name, list(term), term__context, term).
:- mode construct_qualified_term(in, in, in, out) is det.
%-----------------------------------------------------------------------------%
% A pred declaration may contains just types, as in
% :- pred list__append(list(T), list(T), list(T)).
% or it may contain both types and modes, as in
% :- pred list__append(list(T)::in, list(T)::in,
% list(T)::output).
%
% This predicate takes the argument list of a pred declaration,
% splits it into two separate lists for the types and (if present)
% the modes.
:- type maybe_modes == maybe(list(mode)).
:- pred split_types_and_modes(list(type_and_mode), list(type), maybe_modes).
:- mode split_types_and_modes(in, out, out) is det.
:- pred split_type_and_mode(type_and_mode, type, maybe(mode)).
:- mode split_type_and_mode(in, out, out) is det.
%-----------------------------------------------------------------------------%
% Perform a substitution on a goal.
:- pred prog_util__rename_in_goal(goal, var, var, goal).
:- mode prog_util__rename_in_goal(in, in, in, out) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module (inst).
:- import_module bool, std_util, map.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
unqualify_name(unqualified(PredName), PredName).
unqualify_name(qualified(_ModuleName, PredName), PredName).
sym_name_get_module_name(unqualified(_), ModuleName, ModuleName).
sym_name_get_module_name(qualified(ModuleName, _PredName), _, ModuleName).
construct_qualified_term(qualified(Module, Name), Args, Context, Term) :-
ModuleTerm = term__functor(term__atom(Module), [], Context),
UnqualifiedTerm = term__functor(term__atom(Name), Args, Context),
Term = term__functor(term__atom(":"), [ModuleTerm, UnqualifiedTerm],
Context).
construct_qualified_term(unqualified(Name), Args, Context, Term) :-
Term = term__functor(term__atom(Name), Args, Context).
construct_qualified_term(SymName, Args, Term) :-
term__context_init(Context),
construct_qualified_term(SymName, Args, Context, Term).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
split_types_and_modes(TypesAndModes, Types, MaybeModes) :-
split_types_and_modes_2(TypesAndModes, yes, Types, Modes, Result),
(
Result = yes
->
MaybeModes = yes(Modes)
;
MaybeModes = no
).
:- pred split_types_and_modes_2(list(type_and_mode), bool,
list(type), list(mode), bool).
:- mode split_types_and_modes_2(in, in, out, out, out) is det.
% T = type, M = mode, TM = combined type and mode
split_types_and_modes_2([], Result, [], [], Result).
split_types_and_modes_2([TM|TMs], Result0, [T|Ts], [M|Ms], Result) :-
split_type_and_mode(TM, Result0, T, M, Result1),
split_types_and_modes_2(TMs, Result1, Ts, Ms, Result).
% if a pred declaration specifies modes for some but
% not all of the arguments, then the modes are ignored
% - should this be an error instead?
:- pred split_type_and_mode(type_and_mode, bool, type, mode, bool).
:- mode split_type_and_mode(in, in, out, out, out) is det.
split_type_and_mode(type_only(T), _, T, (free -> free), no).
split_type_and_mode(type_and_mode(T,M), R, T, M, R).
split_type_and_mode(type_only(T), T, no).
split_type_and_mode(type_and_mode(T,M), T, yes(M)).
%-----------------------------------------------------------------------------%
prog_util__rename_in_goal(Goal0 - Context, OldVar, NewVar, Goal - Context) :-
prog_util__rename_in_goal_expr(Goal0, OldVar, NewVar, Goal).
:- pred prog_util__rename_in_goal_expr(goal_expr, var, var, goal_expr).
:- mode prog_util__rename_in_goal_expr(in, in, in, out) is det.
prog_util__rename_in_goal_expr((GoalA0, GoalB0), OldVar, NewVar,
(GoalA, GoalB)) :-
prog_util__rename_in_goal(GoalA0, OldVar, NewVar, GoalA),
prog_util__rename_in_goal(GoalB0, OldVar, NewVar, GoalB).
prog_util__rename_in_goal_expr(true, _Var, _NewVar, true).
prog_util__rename_in_goal_expr((GoalA0; GoalB0), OldVar, NewVar,
(GoalA; GoalB)) :-
prog_util__rename_in_goal(GoalA0, OldVar, NewVar, GoalA),
prog_util__rename_in_goal(GoalB0, OldVar, NewVar, GoalB).
prog_util__rename_in_goal_expr(fail, _Var, _NewVar, fail).
prog_util__rename_in_goal_expr(not(Goal0), OldVar, NewVar, not(Goal)) :-
prog_util__rename_in_goal(Goal0, OldVar, NewVar, Goal).
prog_util__rename_in_goal_expr(some(Vars0, Goal0), OldVar, NewVar,
some(Vars, Goal)) :-
prog_util__rename_in_vars(Vars0, OldVar, NewVar, Vars),
prog_util__rename_in_goal(Goal0, OldVar, NewVar, Goal).
prog_util__rename_in_goal_expr(all(Vars0, Goal0), OldVar, NewVar,
all(Vars, Goal)) :-
prog_util__rename_in_vars(Vars0, OldVar, NewVar, Vars),
prog_util__rename_in_goal(Goal0, OldVar, NewVar, Goal).
prog_util__rename_in_goal_expr(implies(GoalA0, GoalB0), OldVar, NewVar,
implies(GoalA, GoalB)) :-
prog_util__rename_in_goal(GoalA0, OldVar, NewVar, GoalA),
prog_util__rename_in_goal(GoalB0, OldVar, NewVar, GoalB).
prog_util__rename_in_goal_expr(equivalent(GoalA0, GoalB0), OldVar, NewVar,
equivalent(GoalA, GoalB)) :-
prog_util__rename_in_goal(GoalA0, OldVar, NewVar, GoalA),
prog_util__rename_in_goal(GoalB0, OldVar, NewVar, GoalB).
prog_util__rename_in_goal_expr(if_then(Vars0, Cond0, Then0), OldVar, NewVar,
if_then(Vars, Cond, Then)) :-
prog_util__rename_in_vars(Vars0, OldVar, NewVar, Vars),
prog_util__rename_in_goal(Cond0, OldVar, NewVar, Cond),
prog_util__rename_in_goal(Then0, OldVar, NewVar, Then).
prog_util__rename_in_goal_expr(if_then_else(Vars0, Cond0, Then0, Else0),
OldVar, NewVar, if_then_else(Vars, Cond, Then, Else)) :-
prog_util__rename_in_vars(Vars0, OldVar, NewVar, Vars),
prog_util__rename_in_goal(Cond0, OldVar, NewVar, Cond),
prog_util__rename_in_goal(Then0, OldVar, NewVar, Then),
prog_util__rename_in_goal(Else0, OldVar, NewVar, Else).
prog_util__rename_in_goal_expr(call(SymName, Terms0), OldVar, NewVar,
call(SymName, Terms)) :-
term__substitute_list(Terms0, OldVar, term__variable(NewVar), Terms).
prog_util__rename_in_goal_expr(unify(TermA0, TermB0), OldVar, NewVar,
unify(TermA, TermB)) :-
term__substitute(TermA0, OldVar, term__variable(NewVar), TermA),
term__substitute(TermB0, OldVar, term__variable(NewVar), TermB).
:- pred prog_util__rename_in_vars(list(var), var, var, list(var)).
:- mode prog_util__rename_in_vars(in, in, in, out) is det.
prog_util__rename_in_vars([], _, _, []).
prog_util__rename_in_vars([Var0 | Vars0], OldVar, NewVar, [Var | Vars]) :-
( Var0 = OldVar ->
Var = NewVar
;
Var = Var0
),
prog_util__rename_in_vars(Vars0, OldVar, NewVar, Vars).
%-----------------------------------------------------------------------------%