[m-dev.] Diff: Make Mercury cope with impure code (part 1/2)

Fergus Henderson fjh at cs.mu.oz.au
Fri Nov 28 22:19:37 AEDT 1997


modes.m:
>  modecheck_goal_expr(call(PredId0, _, Args0, _, Context, PredName0),
> -                GoalInfo0, Goal) -->
> -        % do the last step of type-checking
> +		GoalInfo0, Goal) -->
> +	% Resolve overloading.  This is only necessary when invoked to
> +	% modecheck a lambda goal; other overloading is handled in purity.m

Hmm, shouldn't that be unnecessary now?
Shouldn't purity.m resolve overloading even for lambda goals?

> +% check whether there are any delayed goals (other than headvar unifications)
> +% at the point where we are about to schedule an impure goal.  If so, that is
> +% an error.
> +:- pred check_for_impurity_error[...]

I think you should explain why headvar unifications are treated specially.

> -:- pred resolve_pred_overloading(pred_id, list(var), sym_name, sym_name,
> -                                mode_info, pred_id).
> -:- mode resolve_pred_overloading(in, in, in, out, mode_info_ui, out) is det.
> -        %
> -        % In the case of a call to an overloaded predicate, typecheck.m
> -        % does not figure out the correct pred_id.  We must do that here.
> -        %
> -resolve_pred_overloading(PredId0, Args0, PredName0, PredName,
> -                        ModeInfo0, PredId) :-
> -        ( invalid_pred_id(PredId0) ->
> -                %
> -                % Find the set of candidate pred_ids for predicates which
> -                % have the specified name and arity
> -                %
> -                mode_info_get_module_info(ModeInfo0, ModuleInfo0),
> -                mode_info_get_predid(ModeInfo0, ThisPredId),
> -                module_info_pred_info(ModuleInfo0, ThisPredId, PredInfo),
> -                pred_info_typevarset(PredInfo, TVarSet),
> -                mode_info_get_var_types(ModeInfo0, VarTypes0),
> -                typecheck__resolve_pred_overloading(ModuleInfo0, Args0,
> -                        VarTypes0, TVarSet, PredName0, PredName, PredId)
> -        ;
> -                PredId = PredId0,
> -                PredName = PredName0
> -        ).
> -
> -%-----------------------------------------------------------------------------%
>  %-----------------------------------------------------------------------------%
>  
>  	% Given a list of variables, and a list of livenesses,
> @@ -1612,5 +1677,33 @@
>  check_circular_modes(Module0, Module) -->
>  	{ Module = Module0 }.
>  
> +
> +%-----------------------------------------------------------------------------%
> +
> +:- pred resolve_pred_overloading(pred_id, list(var), sym_name, sym_name,
> +				mode_info, pred_id).
> +:- mode resolve_pred_overloading(in, in, in, out, mode_info_ui, out) is det.
> +	%
> +	% In the case of a call to an overloaded predicate, typecheck.m
> +	% does not figure out the correct pred_id.  We must do that here.
> +	%
> +resolve_pred_overloading(PredId0, Args0, PredName0, PredName,
> +			ModeInfo0, PredId) :-
> +	( invalid_pred_id(PredId0) ->
> +		%
> +		% Find the set of candidate pred_ids for predicates which
> +		% have the specified name and arity
> +		%
> +		mode_info_get_module_info(ModeInfo0, ModuleInfo0),
> +		mode_info_get_predid(ModeInfo0, ThisPredId),
> +		module_info_pred_info(ModuleInfo0, ThisPredId, PredInfo),
> +		pred_info_typevarset(PredInfo, TVarSet),
> +		mode_info_get_var_types(ModeInfo0, VarTypes0),
> +		typecheck__resolve_pred_overloading(ModuleInfo0, Args0,
> +			VarTypes0, TVarSet, PredName0, PredName, PredId)
> +	;
> +		PredId = PredId0,
> +		PredName = PredName0
> +	).

Any particular reason for moving that predicate definition?
If not, please keep it in the original place
(keeps diffs shorter, makes CVS merging easier).

> +:- pred parse_goal_with_purity(term, varset, purity, goal_expr, varset).
> +:- mode parse_goal_with_purity(in, in, in, out, out) is det.
> +
> +parse_goal_with_purity(A0, V0, Purity, A, V) :-
> +	parse_goal(A0, V0, A1, V),
> +	(   A1 = call(Pred, Args, pure) - _ ->
> +		A = call(Pred, Args, Purity)
> +	;
> +		% XXX Should print a warning:  user put an `impure' or
> +		%     `semipure' marker on a non-atomic goal, or else they put
> +		%     multiple markers on a goal.
> +		A - _ = A1
> +	).

It would be better to do

		purity_to_string(Purity, PurityString),
		A = call(unqualified(PurityString), [A1], pure)

Then the error will be caught (by typecheck.m).  You may want to
add some code to report_error_undef_pred in typecheck.m to print
out a vaguely reasonable error message.  (Yeah, I know this is
not an ideal way of handling parse errors.)

Ditto for parse_dcg_goal_with_purity.

Also you should add clauses for `impure' and `semipure' to the predicate
language_builtin/2 in typecheck.m.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   WWW: <http://www.cs.mu.oz.au/~fjh>  
Note: due to some buggy software and a (probably accidental)
denial-of-service attack, any mail sent to me between
	Tue Nov 25 20:00:00 UTC (6am Wed, local time)
and	Wed Nov 26 06:00:00 UTC (4pm, local time)
may have gone into the bit-bucket.  Please re-send it.



More information about the developers mailing list