Support impurity declarations for higher-order code.

Estimated hours taken: 24
Branches: main

Support impurity declarations for higher-order code.

In particular, allow `impure' and `semipure' annotations on
higher-order types, higher-order calls, and lambda expresions.

NEWS:
doc/reference_manual.texi:
	Document the new language feature.

compiler/hlds_goal.m:
compiler/hlds_pred.m:
	Add `purity' field to
	- the `higher_order' alternative of the hlds_goal.generic_call type
	- the `higher_order' alternative of the hlds_pred.generic_call_id type
	- the `lambda_goal' alternative of the hlds_goal.unify_rhs type

compiler/type_util.m:
	Add a new `purity' argument to the procedures dealing with
	higher-order types.  Add code for parsing impure/semipure
	higher-order types.

compiler/lambda.m:
compiler/make_hlds.m:
compiler/typecheck.m:
compiler/post_typecheck.m:
compiler/purity.m:
compiler/polymorphism.m:
	Various minor changes to support impure/semipure higher-order lambda
	expressions.

compiler/polymorphism.m:
compiler/pseudo_type_info.m:
	XXX ought to change these to include purity in the RTTI for
	higher-order function types.

compiler/simplify.m:
	Don't try to optimize semipure/impure higher-order calls.

compiler/assertion.m:
compiler/bytecode_gen.m:
compiler/call_gen.m:
compiler/continuation_info.m:
compiler/cse_detection.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/det_analysis.m:
compiler/det_util.m:
compiler/equiv_type.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_out.m:
compiler/intermod.m:
compiler/magic.m:
compiler/magic_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/mode_util.m:
compiler/modecheck_call.m:
compiler/modecheck_unify.m:
compiler/modes.m:
compiler/module_qual.m:
compiler/pd_util.m:
compiler/prog_rep.m:
compiler/pseudo_type_info.m:
compiler/quantification.m:
compiler/recompilation.usage.m:
compiler/rl_gen.m:
compiler/stratify.m:
compiler/switch_detection.m:
compiler/term_traversal.m:
compiler/term_util.m:
compiler/unify_gen.m:
compiler/unique_modes.m:
	Trivial changes to handle the new purity fields and/or arguments.

tests/hard_coded/purity/Mmakefile:
tests/hard_coded/purity/impure_func_t5_fixed2.m:
tests/hard_coded/purity/impure_func_t5_fixed2.exp:
tests/hard_coded/purity/impure_func_t5_fixed2.exp2:
tests/hard_coded/purity/impure_pred_t1_fixed3.m:
tests/hard_coded/purity/impure_pred_t1_fixed3.exp:
tests/invalid/purity/Mmakefile:
tests/invalid/purity/impure_func_t5_fixed.m:
tests/invalid/purity/impure_func_t5_fixed.err_exp:
tests/invalid/purity/impure_pred_t1_fixed.m:
tests/invalid/purity/impure_pred_t1_fixed.err_exp:
	Add new test cases to test the new feature.

tests/invalid/purity/impure_func_t5.err_exp:
tests/invalid/purity/impure_pred_t1.err_exp:
tests/invalid/purity/impure_pred_t2.err_exp:
tests/invalid/purity/purity.err_exp:
tests/invalid/purity/purity_nonsense.err_exp:
	Update the expected error messages for existing test cases.

tests/invalid/purity/.cvsignore:
	New file, copied from tests/invalid/.cvsignore.
This commit is contained in:
Fergus Henderson
2003-01-27 09:21:03 +00:00
parent 17d6bc9eba
commit ef7ed9c2f5
64 changed files with 813 additions and 421 deletions

View File

@@ -1,5 +1,5 @@
%-----------------------------------------------------------------------------%
% Copyright (C) 1995-2002 The University of Melbourne.
% Copyright (C) 1995-2003 The 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.
%-----------------------------------------------------------------------------%
@@ -232,14 +232,14 @@ lambda__process_goal(Goal0 - GoalInfo0, Goal) -->
lambda__process_goal_2(unify(XVar, Y, Mode, Unification, Context), GoalInfo,
Unify - GoalInfo) -->
( { Y = lambda_goal(PredOrFunc, EvalMethod, _, NonLocalVars, Vars,
Modes, Det, LambdaGoal0) } ->
( { Y = lambda_goal(Purity, PredOrFunc, EvalMethod, _, NonLocalVars,
Vars, Modes, Det, LambdaGoal0) } ->
% first, process the lambda goal recursively, in case it
% contains some nested lambda expressions.
lambda__process_goal(LambdaGoal0, LambdaGoal1),
% then, convert the lambda expression into a new predicate
lambda__process_lambda(PredOrFunc, EvalMethod, Vars,
lambda__process_lambda(Purity, PredOrFunc, EvalMethod, Vars,
Modes, Det, NonLocalVars, LambdaGoal1,
Unification, Y1, Unification1),
{ Unify = unify(XVar, Y1, Mode, Unification1, Context) }
@@ -303,14 +303,14 @@ lambda__process_cases([case(ConsId, Goal0) | Cases0],
lambda__process_goal(Goal0, Goal),
lambda__process_cases(Cases0, Cases).
:- pred lambda__process_lambda(pred_or_func, lambda_eval_method,
:- pred lambda__process_lambda(purity, pred_or_func, lambda_eval_method,
list(prog_var), list(mode), determinism, list(prog_var),
hlds_goal, unification, unify_rhs, unification,
lambda_info, lambda_info).
:- mode lambda__process_lambda(in, in, in, in, in, in, in, in, out, out,
:- mode lambda__process_lambda(in, in, in, in, in, in, in, in, in, out, out,
in, out) is det.
lambda__process_lambda(PredOrFunc, EvalMethod, Vars, Modes, Detism,
lambda__process_lambda(Purity, PredOrFunc, EvalMethod, Vars, Modes, Detism,
OrigNonLocals0, LambdaGoal, Unification0, Functor,
Unification, LambdaInfo0, LambdaInfo) :-
LambdaInfo0 = lambda_info(VarSet, VarTypes, _PredConstraints, TVarSet,
@@ -501,6 +501,7 @@ lambda__process_lambda(PredOrFunc, EvalMethod, Vars, Modes, Detism,
list__append(ArgModes1, Modes, AllArgModes),
map__apply_to_list(AllArgVars, VarTypes, ArgTypes),
purity_to_markers(Purity, LambdaMarkers0),
(
% Pass through the aditi markers for
% aggregate query closures.
@@ -530,18 +531,20 @@ lambda__process_lambda(PredOrFunc, EvalMethod, Vars, Modes, Detism,
; Marker = aditi_no_memo
)),
MarkerList0, MarkerList),
marker_list_to_markers(MarkerList, LambdaMarkers)
LambdaMarkers = list__foldl((func(LMs0, Mrk) = LMs :-
add_marker(Mrk, LMs0, LMs)),
MarkerList, LambdaMarkers0)
;
EvalMethod = (aditi_bottom_up)
->
marker_list_to_markers([aditi], LambdaMarkers)
add_marker(LambdaMarkers0, aditi, LambdaMarkers)
;
EvalMethod = (aditi_top_down)
->
marker_list_to_markers([(aditi_top_down)],
add_marker(LambdaMarkers0, aditi_top_down,
LambdaMarkers)
;
init_markers(LambdaMarkers)
LambdaMarkers = LambdaMarkers0
),
% Now construct the proc_info and pred_info for the new
@@ -562,7 +565,7 @@ lambda__process_lambda(PredOrFunc, EvalMethod, Vars, Modes, Detism,
set__init(Assertions),
pred_info_create(ModuleName, PredName, TVarSet, ExistQVars,
ArgTypes, true, LambdaContext, local, LambdaMarkers,
ArgTypes, true, LambdaContext, local, LambdaMarkers,
PredOrFunc, Constraints, Owner, Assertions, ProcInfo,
ProcId, PredInfo),