[m-dev.] for review: add extras/exceptions

Fergus Henderson fjh at cs.mu.OZ.AU
Thu Jul 23 00:26:23 AEST 1998


On 22-Jul-1998, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> > Would it make sense to have rethrow(in(bound(exception(...)))) and
> > avoid these (or rather, force the caller to avoid these?
> 
> I thought about that.  But often you will want to write
> 
> 	( Exception = 

Oops, incomplete thought.  Yes, it probably would make sense to do it
that way.  I shall.

Here's a relative diff from last time.  I will commit this one.

===================================================================
RCS file: RCS/Mmakefile,v
retrieving revision 1.2
diff -u -r1.2 Mmakefile
--- Mmakefile	1998/07/22 13:50:45	1.2
+++ Mmakefile	1998/07/22 13:40:42
@@ -1,14 +1,5 @@
 #-----------------------------------------------------------------------------#
 #
-# the following two lines are required for exception.m
-# (see the comment at the top of exception.m)
-#
-
-RM_C=:
-C2INITFLAGS=$($(subst _init.c,,$@).cs)
-
-#-----------------------------------------------------------------------------#
-#
 # These rules define the main targets: depend, all, check.
 #
 
@@ -19,6 +10,16 @@
 depend: $(PROGS:.m=.depend)
 all: $(PROGS:.m=)
 check: $(PROGS:.m=.res)
+
+#-----------------------------------------------------------------------------#
+#
+# the following lines are required for exception.m
+# (see the comment at the top of exception.m)
+#
+
+RM_C=:
+C2INITFLAGS=--extra-inits
+$(PROGS:.m=_init.c): $(PROGS:.m=.c) exception.c
 
 #-----------------------------------------------------------------------------#
 #
===================================================================
RCS file: RCS/exception.m,v
retrieving revision 1.17
diff -u -r1.17 exception.m
--- exception.m	1998/07/21 18:35:19	1.17
+++ exception.m	1998/07/22 14:20:17
@@ -10,21 +10,23 @@
 
 % This file contains experimental code for exception handling.
 
-% Note that throwing an exception across the C interface won't work --
-% if you try to do that, you will get undefined behaviour.
+% Note that throwing an exception across the C interface won't work.
+% That is, if a Mercury procedure that is exported to C using `pragma export'
+% throws an exception which is not caught within that procedure, then
+% you will get undefined behaviour.
 
 %-----------------------------------------------------------------------------%
 
-% Since this module is implemented using C code with `BEGIN_MODULE()'
-% and `END_MODULE', and because it is not part of the standard library,
-% to use this module you need the following two lines in your Mmakefile:
+% To compile this module you need the following two lines in your Mmakefile:
 %
 %	RM_C=:
-%	C2INITFLAGS=$($(subst _init.c,,$@).cs)
+%	C2INITFLAGS=--extra-inits
 %
-% This ensures that the module initialization code will be run.
-% (Actually these two lines are needed only in certain grades, e.g.
-% for profiling.)
+% You also need to add dependencies to ensure that Mmake knows that
+% the *_init.c files depend on the *.c files.
+%
+% This ensures that the module initialization code for this module will be run.
+% (Actually these steps are needed only in certain grades, e.g. for profiling.)
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -87,12 +89,12 @@
 %		; Result = exception(_)
 %		).
 %
-:- pred try_io(pred(T, io__state, io__state), exception_result(T),
-						io__state, io__state).
-:- mode try_io(pred(out, di, uo) is det,      out(cannot_fail),
-						di, uo) is cc_multi.
-:- mode try_io(pred(out, di, uo) is cc_multi, out(cannot_fail),
-						di, uo) is cc_multi.
+:- pred try_io(pred(T, io__state, io__state),
+		exception_result(T), io__state, io__state).
+:- mode try_io(pred(out, di, uo) is det,     
+		out(cannot_fail), di, uo) is cc_multi.
+:- mode try_io(pred(out, di, uo) is cc_multi,
+		out(cannot_fail), di, uo) is cc_multi.
 
 %
 % try_all(Goal, ResultList):
@@ -150,10 +152,10 @@
 %	not `succeeded(_)' or `failed'.).
 %
 :- pred rethrow(exception_result(T)).
-:- mode rethrow(in) is erroneous.
+:- mode rethrow(in(bound(exception(ground)))) is erroneous.
 
 :- func rethrow(exception_result(T)) = _.
-:- mode rethrow(in) = out is erroneous.
+:- mode rethrow(in(bound(exception(ground)))) = out is erroneous.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -215,7 +217,8 @@
 	is cc_multi.
 
 % Unfortunately the only way to implement get_determinism/2 is to use
-% the C interface.
+% the C interface, since Mercury doesn't allow different code for different
+% modes.
 
 % The enumeration constants in this enum must be in the same order as the
 % functors in the Mercury type `determinism' defined above.
@@ -292,10 +295,6 @@
 
 rethrow(exception(Univ)) :-
 	builtin_throw(Univ).
-rethrow(succeeded(_)) :-
-	error("rethrow/1: invalid argument").
-rethrow(failed) :-
-	error("rethrow/1: invalid argument").
 
 rethrow(ExceptionResult) = _ :-
 	rethrow(ExceptionResult).
@@ -345,8 +344,11 @@
 		wrap_exception, Result0),
 	cc_multi_equal(Result0, Result).
 try(cc_multi, Goal, Result) :-
-	builtin_catch((pred(R::out) is cc_multi :-
-				wrap_success_or_failure(Goal, R)),
+
+	builtin_catch(
+		(pred(R::out) is cc_multi :-
+				wrap_success_or_failure(Goal, R)
+				),
 		wrap_exception, Result).
 try(cc_nondet, Goal, Result) :-
 	builtin_catch((pred(R::out) is cc_multi :-
@@ -539,6 +541,31 @@
   Declare_label(mercury__exception__builtin_throw_1_0_i1);
   Declare_label(mercury__exception__builtin_throw_1_0_i2);
   Declare_label(mercury__exception__builtin_throw_1_0_i3);
+#endif
+
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_0)
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_1)
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_2)
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_3)
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_4)
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_5)
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_throw_1_0)
+MR_MAKE_STACK_LAYOUT_ENTRY(exception_handler_do_fail)
+MR_MAKE_STACK_LAYOUT_ENTRY(mercury__exception__builtin_catch_3_0)
+
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_2, 1)
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_2, 2)
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_3, 1)
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_3, 2)
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_5, 1)
+MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_5, 2)
+#ifdef MR_USE_TRAIL
+  MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_catch_3_5, 3)
+#endif
+#ifndef COMPACT_ARGS
+  MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_throw_1_0, 1)
+  MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_throw_1_0, 2)
+  MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__builtin_throw_1_0, 3)
 #endif
 
 BEGIN_MODULE(exceptions_module)
===================================================================
RCS file: RCS/test_exceptions.m,v
retrieving revision 1.5
diff -u -r1.5 test_exceptions.m
--- test_exceptions.m	1998/07/18 17:15:32	1.5
+++ test_exceptions.m	1998/07/22 14:09:59
@@ -10,6 +10,7 @@
 % Test cases for exception handling.
 
 % XXX we should test nested exception handlers.
+% XXX we should also test exceptions with nested calls to solutions/2.
 
 %-----------------------------------------------------------------------------%
 
@@ -29,42 +30,28 @@
 	{ try(det_succeed, DetSucceedResult) },
 	print("det_succeed: "), print(DetSucceedResult), nl,
 
-	(if { try(semidet_throw, SemidetThrowResult) } then
-		print("semidet_throw: "), print(SemidetThrowResult), nl
-	else
-		print("semidet_throw failed"), nl
-	),
-	(if { try(semidet_succeed, SemidetSucceedResult) } then
-		print("semidet_succeed: "), print(SemidetSucceedResult), nl
-	else
-		print("semidet_succeed failed"), nl
-	),
-	(if { try(semidet_fail, SemidetFailResult) } then
-		print("semidet_fail: "), print(SemidetFailResult), nl
-	else
-		print("semidet_fail failed"), nl
-	),
+	{ try(semidet_throw, SemidetThrowResult) },
+	print("semidet_throw: "), print(SemidetThrowResult), nl,
+
+	{ try(semidet_succeed, SemidetSucceedResult) },
+	print("semidet_succeed: "), print(SemidetSucceedResult), nl,
+
+	{ try(semidet_fail, SemidetFailResult) },
+	print("semidet_fail: "), print(SemidetFailResult), nl,
 
 	{ try(cc_multi_throw, CCMultiThrowResult) },
 	print("cc_multi_throw: "), print(CCMultiThrowResult), nl,
 	{ try(cc_multi_succeed, CCMultiSucceedResult) },
 	print("cc_multi_succeed: "), print(CCMultiSucceedResult), nl,
 
-	(if { try(cc_nondet_throw, CCNondetThrowResult) } then
-		print("cc_nondet_throw: "), print(CCNondetThrowResult), nl
-	else
-		print("cc_nondet_throw failed"), nl
-	),
-	(if { try(cc_nondet_succeed, CCNondetSucceedResult) } then
-		print("cc_nondet_succeed: "), print(CCNondetSucceedResult), nl
-	else
-		print("cc_nondet_succeed failed"), nl
-	),
-	(if { try(cc_nondet_fail, CCNondetFailResult) } then
-		print("cc_nondet_fail: "), print(CCNondetFailResult), nl
-	else
-		print("cc_nondet_fail failed"), nl
-	),
+	{ try(cc_nondet_throw, CCNondetThrowResult) },
+	print("cc_nondet_throw: "), print(CCNondetThrowResult), nl,
+
+	{ try(cc_nondet_succeed, CCNondetSucceedResult) },
+	print("cc_nondet_succeed: "), print(CCNondetSucceedResult), nl,
+
+	{ try(cc_nondet_fail, CCNondetFailResult) },
+	print("cc_nondet_fail: "), print(CCNondetFailResult), nl,
 
 	{ try((pred(R::out) is det :- solutions(multi_throw, R)),
 		MultiThrowResult) },
@@ -143,8 +130,8 @@
 nondet_fail("nondet_fail 2") :- fail.
 
 :- pred cc_nondet_fail(string::out) is cc_nondet.
-cc_nondet_fail("cc_nondet_fail") :- fail.
-cc_nondet_fail("cc_nondet_succeed 2") :- fail.
+cc_nondet_fail("cc_nondet_fail 1") :- fail.
+cc_nondet_fail("cc_nondet_fail 2") :- fail.
 
 
 :- pred nondet_succeed_then_throw(string::out) is nondet.
===================================================================
RCS file: RCS/test_exceptions_func.m,v
retrieving revision 1.4
diff -u -r1.4 test_exceptions_func.m
===================================================================
RCS file: RCS/test_uncaught_exception.m,v
retrieving revision 1.1
diff -u -r1.1 test_uncaught_exception.m
===================================================================
RCS file: RCS/test_exceptions.exp,v
retrieving revision 1.2
diff -u -r1.2 test_exceptions.exp
===================================================================
RCS file: RCS/test_exceptions_func.exp,v
retrieving revision 1.2
diff -u -r1.2 test_exceptions_func.exp
===================================================================
RCS file: RCS/test_uncaught_exception.exp,v
retrieving revision 1.1
diff -u -r1.1 test_uncaught_exception.exp

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.



More information about the developers mailing list