mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-17 14:57:03 +00:00
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:
@@ -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),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user