[m-rev.] diff: event goal error checking
Mark Brown
mark at csse.unimelb.edu.au
Tue Nov 28 17:16:28 AEDT 2006
Estimated hours taken: 1
Branches: main
Improved error checking for event goals.
compiler/typecheck.m:
When checking that an event name matches an existing event, also
check that the number of arguments matches the expected number.
Otherwise typecheck_var_has_type_list will just throw an exception.
compiler/typecheck_errors.m:
Report the argument length mismatch as an error.
Fix the severity of unknown event call errors. If allowed to get
through then modes.m would throw an exception.
tests/invalid/Mercury.options:
tests/invalid/Mmakefile:
tests/invalid/invalid_event.err_exp:
tests/invalid/invalid_event.m:
tests/invalid/invalid_event_spec:
Test the error checking.
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.411
diff -u -r1.411 typecheck.m
--- compiler/typecheck.m 24 Nov 2006 03:48:10 -0000 1.411
+++ compiler/typecheck.m 28 Nov 2006 05:30:00 -0000
@@ -1517,7 +1517,13 @@
typecheck_info_get_module_info(!.Info, ModuleInfo),
module_info_get_event_spec_map(ModuleInfo, EventSpecMap),
( event_arg_types(EventSpecMap, EventName, EventArgTypes) ->
- typecheck_var_has_type_list(Args, EventArgTypes, 1, !Info)
+ ( list.same_length(Args, EventArgTypes) ->
+ typecheck_var_has_type_list(Args, EventArgTypes, 1, !Info)
+ ;
+ Spec = report_event_args_mismatch(!.Info, EventName, EventArgTypes,
+ Args),
+ typecheck_info_add_error(Spec, !Info)
+ )
;
Spec = report_unknown_event_call_error(!.Info, EventName),
typecheck_info_add_error(Spec, !Info)
Index: compiler/typecheck_errors.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/typecheck_errors.m,v
retrieving revision 1.33
diff -u -r1.33 typecheck_errors.m
--- compiler/typecheck_errors.m 6 Nov 2006 07:55:14 -0000 1.33
+++ compiler/typecheck_errors.m 28 Nov 2006 06:00:18 -0000
@@ -44,6 +44,9 @@
:- func report_unknown_event_call_error(typecheck_info, string) = error_spec.
+:- func report_event_args_mismatch(typecheck_info, string, list(mer_type),
+ list(prog_var)) = error_spec.
+
:- func report_no_clauses(module_info, pred_id, pred_info) = error_spec.
:- func report_no_clauses_stub(module_info, pred_id, pred_info) = error_spec.
@@ -291,9 +294,19 @@
report_unknown_event_call_error(Info, EventName) = Spec :-
typecheck_info_get_context(Info, Context),
- Pieces = [words("There is no event named"), quote(EventName), suffix(".")],
+ Pieces = [words("Error: there is no event named"),
+ quote(EventName), suffix(".")],
+ Msg = simple_msg(Context, [always(Pieces)]),
+ Spec = error_spec(severity_error, phase_type_check, [Msg]).
+
+report_event_args_mismatch(Info, EventName, EventArgTypes, Args) = Spec :-
+ typecheck_info_get_context(Info, Context),
+ Pieces =
+ [words("Error:")] ++
+ error_num_args_to_pieces(no, length(Args), [length(EventArgTypes)]) ++
+ [words("in event"), quote(EventName), suffix(".")],
Msg = simple_msg(Context, [always(Pieces)]),
- Spec = error_spec(severity_warning, phase_type_check, [Msg]).
+ Spec = error_spec(severity_error, phase_type_check, [Msg]).
%-----------------------------------------------------------------------------%
Index: tests/invalid/Mercury.options
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/Mercury.options,v
retrieving revision 1.16
diff -u -r1.16 Mercury.options
--- tests/invalid/Mercury.options 15 Jun 2006 04:32:05 -0000 1.16
+++ tests/invalid/Mercury.options 28 Nov 2006 04:28:23 -0000
@@ -41,6 +41,7 @@
MCFLAGS-impure_method_impl = --no-intermodule-optimization \
--no-automatic-intermodule-optimization \
--verbose-error-messages
+MCFLAGS-invalid_event = --event-spec-file-name invalid_event_spec
MCFLAGS-loopcheck = --warn-inferred-erroneous \
--verbose-error-messages
MCFLAGS-method_impl = --no-intermodule-optimization \
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.201
diff -u -r1.201 Mmakefile
--- tests/invalid/Mmakefile 21 Nov 2006 11:47:48 -0000 1.201
+++ tests/invalid/Mmakefile 28 Nov 2006 04:28:52 -0000
@@ -102,6 +102,7 @@
inst_list_dup \
instance_bug \
instance_dup_var \
+ invalid_event \
invalid_export_detism \
invalid_import_detism \
invalid_main \
Index: tests/invalid/invalid_event.err_exp
===================================================================
RCS file: tests/invalid/invalid_event.err_exp
diff -N tests/invalid/invalid_event.err_exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/invalid_event.err_exp 28 Nov 2006 06:01:34 -0000
@@ -0,0 +1,3 @@
+invalid_event.m:032: Error: wrong number of arguments (2; should be 1) in event
+invalid_event.m:032: `safe_test'.
+invalid_event.m:055: Error: there is no event named `nodiag_succeed'.
Index: tests/invalid/invalid_event.m
===================================================================
RCS file: tests/invalid/invalid_event.m
diff -N tests/invalid/invalid_event.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/invalid_event.m 28 Nov 2006 05:58:06 -0000
@@ -0,0 +1,100 @@
+:- module invalid_event.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is cc_multi.
+
+:- implementation.
+
+:- import_module list.
+:- import_module int.
+
+:- type listint == list(int).
+
+main(!IO) :-
+ data(Data),
+ ( queen(Data, Out) ->
+ print_list(Out, !IO)
+ ;
+ io.write_string("No solution\n", !IO)
+ ).
+
+:- pred data(list(int)::out) is det.
+
+data([1,2,3,4,5]).
+
+:- pred queen(list(int)::in, list(int)::out) is nondet.
+
+queen(Data, Out) :-
+ qperm(Data, Out),
+ event safe_test(Data, Out),
+ safe(Out).
+
+:- pred qperm(list(T)::in, list(T)::out) is nondet.
+
+qperm([], []).
+qperm(L, K) :-
+ L = [_ | _],
+ qdelete(U, L, Z),
+ K = [U | V],
+ qperm(Z, V).
+
+:- pred qdelete(T::out, list(T)::in, list(T)::out) is nondet.
+
+qdelete(A, [A | L], L).
+qdelete(X, [A | Z], [A | R]) :-
+ qdelete(X, Z, R).
+
+:- pred safe(list(int)::in) is semidet.
+
+safe([]).
+safe([N | L]) :-
+ nodiag(N, 1, L),
+ event nodiag_succeed(N, L),
+ safe(L).
+
+:- pred nodiag(int::in, int::in, list(int)::in) is semidet.
+
+nodiag(_, _, []).
+nodiag(B, D, [N | L]) :-
+ NmB = N - B,
+ BmN = B - N,
+ ( D = NmB ->
+ event nodiag_fail("N - B", B, N, [N | L]),
+ fail
+ ; D = BmN ->
+ event nodiag_fail("B - N", B, N, [N | L]),
+ fail
+ ;
+ true
+ ),
+ D1 = D + 1,
+ nodiag(B, D1, L).
+
+:- pred print_list(list(int)::in, io::di, io::uo) is det.
+
+print_list(Xs, !IO) :-
+ (
+ Xs = [],
+ io.write_string("[]\n", !IO)
+ ;
+ Xs = [_ | _],
+ io.write_string("[", !IO),
+ print_list_2(Xs, !IO),
+ io.write_string("]\n", !IO)
+ ).
+
+:- pred print_list_2(list(int)::in, io::di, io::uo) is det.
+
+print_list_2([], !IO).
+print_list_2([X | Xs], !IO) :-
+ io.write_int(X, !IO),
+ (
+ Xs = []
+ ;
+ Xs = [_ | _],
+ io__write_string(", ", !IO),
+ print_list_2(Xs, !IO)
+ ).
Index: tests/invalid/invalid_event_spec
===================================================================
RCS file: tests/invalid/invalid_event_spec
diff -N tests/invalid/invalid_event_spec
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/invalid_event_spec 28 Nov 2006 04:29:23 -0000
@@ -0,0 +1,10 @@
+event nodiag_fail(
+ test_failed: string,
+ arg_b: int,
+ arg_d: int,
+ arg_list: list(int)
+)
+
+event safe_test(
+ test_list: listint
+)
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list