Files
mercury/compiler/goal_path.m
Zoltan Somogyi 6df9a05856 This diff cleans up a bunch of modules. It has no algorithmic changes
Estimated hours taken: 10
Branches: main

This diff cleans up a bunch of modules. It has no algorithmic changes
other than in the formatting of error messages.

compiler/error_util.m:
	Delete the obsolete predicate append_punctuation, since the suffix
	format component can now do more, and do it more easily.

compiler/goal_util.m:
compiler/hlds_goal.m:
compiler/hlds_llds.m:
compiler/instmap.m:
compiler/const_prop.m:
	Change the argument order of some the predicates exported by these
	modules to make them easier to use with state variable syntax.

compiler/*.m:
	Convert a bunch of these modules to four space indentation, and fix
	departures from our coding style.

	Conform to the changed argument order above.

	Use suffixes instead of append_punctuation.

library/string.m:
	Add string.foldl2.

tests/invalid/circ_*.err_exp:
tests/warnings/unused_args_*.exp:
	Expect the updated error messages, which format sym_names consistently
	the same way as other messages.
2005-08-30 04:12:17 +00:00

233 lines
8.3 KiB
Mathematica

%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 1997-2005 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.
%-----------------------------------------------------------------------------%
% This module looks after goal paths, which associate each goal
% with its position in a procedure definition,
% Main author: zs.
:- module check_hlds__goal_path.
:- interface.
:- import_module hlds__hlds_goal.
:- import_module hlds__hlds_module.
:- import_module hlds__hlds_pred.
:- import_module bool.
% IMPORTANT: the type constraint_id in hlds_data.m makes use of
% goal_paths to identify constraints between the typechecking pass
% and the polymorphism pass. For this reason, goal paths should not
% be recalculated anywhere between these two passes. See the XXX
% comment near the declaration of constraint_id.
%
:- pred goal_path__fill_slots(module_info::in, proc_info::in, proc_info::out)
is det.
% Fill in the goal_paths for goals in the clauses_info of the predicate.
% Clauses are given goal paths `disj(1)', ..., `disj(N)'. If the bool
% argument is true then the goal paths are stored in a form where any
% prefix consisting of `disj(_)', `neg', `exist(_)' and `ite_else'
% components is removed. This is used to optimise the constraint-based
% mode analysis where the instantiatedness of a variable at such a goal
% path is always equivalent to its instantiatedness at the parent goal
% path.
%
:- pred goal_path__fill_slots_in_clauses(module_info::in, bool::in,
pred_info::in, pred_info::out) is det.
:- pred goal_path__fill_slots_in_goal(hlds_goal::in, vartypes::in,
module_info::in, hlds_goal::out) is det.
:- implementation.
:- import_module check_hlds__type_util.
:- import_module hlds__hlds_data.
:- import_module hlds__hlds_goal.
:- import_module parse_tree__error_util.
:- import_module parse_tree__prog_data.
:- import_module char.
:- import_module int.
:- import_module list.
:- import_module map.
:- import_module require.
:- import_module std_util.
:- type slot_info
---> slot_info(
vartypes :: vartypes,
module_info :: module_info,
omit_mode_equiv_prefix :: bool
).
goal_path__fill_slots(ModuleInfo, !Proc) :-
proc_info_goal(!.Proc, Goal0),
proc_info_vartypes(!.Proc, VarTypes),
goal_path__fill_slots_in_goal(Goal0, VarTypes, ModuleInfo, Goal),
proc_info_set_goal(Goal, !Proc).
goal_path__fill_slots_in_clauses(ModuleInfo, OmitModeEquivPrefix, !PredInfo) :-
pred_info_clauses_info(!.PredInfo, ClausesInfo0),
clauses_info_clauses_only(ClausesInfo0, Clauses0),
clauses_info_vartypes(ClausesInfo0, VarTypes),
SlotInfo = slot_info(VarTypes, ModuleInfo, OmitModeEquivPrefix),
list__map_foldl(fill_slots_in_clause(SlotInfo), Clauses0, Clauses, 1, _),
clauses_info_set_clauses(Clauses, ClausesInfo0, ClausesInfo),
pred_info_set_clauses_info(ClausesInfo, !PredInfo).
:- pred fill_slots_in_clause(slot_info::in, clause::in, clause::out,
int::in, int::out) is det.
fill_slots_in_clause(SlotInfo, Clause0, Clause, ClauseNum, ClauseNum + 1) :-
Clause0 = clause(ProcIds, Goal0, Lang, Context),
fill_goal_slots([disj(ClauseNum)], SlotInfo, Goal0, Goal),
Clause = clause(ProcIds, Goal, Lang, Context).
goal_path__fill_slots_in_goal(Goal0, VarTypes, ModuleInfo, Goal) :-
SlotInfo = slot_info(VarTypes, ModuleInfo, no),
fill_goal_slots([], SlotInfo, Goal0, Goal).
:- pred fill_goal_slots(goal_path::in, slot_info::in,
hlds_goal::in, hlds_goal::out) is det.
fill_goal_slots(Path0, SlotInfo, Expr0 - Info0, Expr - Info) :-
OmitModeEquivPrefix = SlotInfo ^ omit_mode_equiv_prefix,
(
OmitModeEquivPrefix = yes,
list__takewhile(mode_equiv_step, Path0, _, Path)
;
OmitModeEquivPrefix = no,
Path = Path0
),
goal_info_set_goal_path(Path, Info0, Info),
fill_expr_slots(Info, Path0, SlotInfo, Expr0, Expr).
:- pred mode_equiv_step(goal_path_step::in) is semidet.
mode_equiv_step(Step) :-
( Step = disj(_)
; Step = neg
; Step = scope(_)
; Step = ite_else
).
:- pred fill_expr_slots(hlds_goal_info::in, goal_path::in, slot_info::in,
hlds_goal_expr::in, hlds_goal_expr::out) is det.
fill_expr_slots(GoalInfo, Path0, SlotInfo, Goal0, Goal) :-
(
Goal0 = conj(Goals0),
fill_conj_slots(Path0, 0, SlotInfo, Goals0, Goals),
Goal = conj(Goals)
;
Goal0 = par_conj(Goals0),
fill_conj_slots(Path0, 0, SlotInfo, Goals0, Goals),
Goal = par_conj(Goals)
;
Goal0 = disj(Goals0),
fill_disj_slots(Path0, 0, SlotInfo, Goals0, Goals),
Goal = disj(Goals)
;
Goal0 = switch(Var, CanFail, Cases0),
VarTypes = SlotInfo ^ vartypes,
ModuleInfo = SlotInfo ^ module_info,
map__lookup(VarTypes, Var, Type),
( switch_type_num_functors(ModuleInfo, Type, NumFunctors) ->
NumCases = NumFunctors
;
NumCases = -1
),
fill_switch_slots(Path0, 0, NumCases, SlotInfo, Cases0, Cases),
Goal = switch(Var, CanFail, Cases)
;
Goal0 = not(SubGoal0),
fill_goal_slots([neg | Path0], SlotInfo, SubGoal0, SubGoal),
Goal = not(SubGoal)
;
Goal0 = scope(Reason, SubGoal0),
SubGoal0 = _ - InnerInfo,
goal_info_get_determinism(GoalInfo, OuterDetism),
goal_info_get_determinism(InnerInfo, InnerDetism),
( InnerDetism = OuterDetism ->
MaybeCut = no_cut
;
MaybeCut = cut
),
fill_goal_slots([scope(MaybeCut) | Path0], SlotInfo,
SubGoal0, SubGoal),
Goal = scope(Reason, SubGoal)
;
Goal0 = if_then_else(A, Cond0, Then0, Else0),
fill_goal_slots([ite_cond | Path0], SlotInfo, Cond0, Cond),
fill_goal_slots([ite_then | Path0], SlotInfo, Then0, Then),
fill_goal_slots([ite_else | Path0], SlotInfo, Else0, Else),
Goal = if_then_else(A, Cond, Then, Else)
;
Goal0 = unify(LHS, RHS0, Mode, Kind, Context),
(
RHS0 = lambda_goal(A, B, C, D, E, F, G, H, LambdaGoal0)
->
fill_goal_slots(Path0, SlotInfo, LambdaGoal0, LambdaGoal),
RHS = lambda_goal(A, B, C, D, E, F, G, H, LambdaGoal)
;
RHS = RHS0
),
Goal = unify(LHS, RHS, Mode, Kind, Context)
;
Goal0 = call(_, _, _, _, _, _),
Goal = Goal0
;
Goal0 = generic_call(_, _, _, _),
Goal = Goal0
;
Goal0 = foreign_proc(_, _, _, _, _, _),
Goal = Goal0
;
Goal0 = shorthand(_),
% These should have been expanded out by now.
unexpected(this_file, "fill_expr_slots: unexpected shorthand")
).
:- pred fill_conj_slots(goal_path::in, int::in, slot_info::in,
list(hlds_goal)::in, list(hlds_goal)::out) is det.
fill_conj_slots(_, _, _, [], []).
fill_conj_slots(Path0, N0, SlotInfo, [Goal0 | Goals0], [Goal | Goals]) :-
N1 = N0 + 1,
fill_goal_slots([conj(N1) | Path0], SlotInfo, Goal0, Goal),
fill_conj_slots(Path0, N1, SlotInfo, Goals0, Goals).
:- pred fill_disj_slots(goal_path::in, int::in, slot_info::in,
list(hlds_goal)::in, list(hlds_goal)::out) is det.
fill_disj_slots(_, _, _, [], []).
fill_disj_slots(Path0, N0, SlotInfo, [Goal0 | Goals0], [Goal | Goals]) :-
N1 = N0 + 1,
fill_goal_slots([disj(N1) | Path0], SlotInfo, Goal0, Goal),
fill_disj_slots(Path0, N1, SlotInfo, Goals0, Goals).
:- pred fill_switch_slots(goal_path::in, int::in, int::in, slot_info::in,
list(case)::in, list(case)::out) is det.
fill_switch_slots(_, _, _, _, [], []).
fill_switch_slots(Path0, N0, NumCases, SlotInfo,
[case(A, Goal0) | Cases0], [case(A, Goal) | Cases]) :-
N1 = N0 + 1,
fill_goal_slots([switch(N1, NumCases) | Path0], SlotInfo, Goal0, Goal),
fill_switch_slots(Path0, N1, NumCases, SlotInfo, Cases0, Cases).
%-----------------------------------------------------------------------------%
:- func this_file = string.
this_file = "goal_path.m".
%-----------------------------------------------------------------------------%