mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-16 06:14:59 +00:00
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.
199 lines
7.9 KiB
Mathematica
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).
|
|
|
|
%-----------------------------------------------------------------------------%
|