mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-15 22:03:26 +00:00
Estimated hours taken: 8 Move exception handling into the standard library, and change error/1 so that it throws an exception. This has two advantages: one is that user code can now catch exceptions caused by calls to error/1, the other is that the debugger handles calls to error/1 more gracefully (by virtue of its existing support for exception handling). extras/exceptions/exception.m: library/exception.m: Move exception.m from `extras' into the standard library. Change the code for handling uncaught exceptions so that it prints out the same diagnostics that error/1 used to print out (i.e. a stack trace and the last debugger event number). extras/exceptions/Mmakefile: extras/exceptions/test_exceptions.exp: extras/exceptions/test_exceptions.m: extras/exceptions/test_exceptions_func.exp: extras/exceptions/test_exceptions_func.m: extras/exceptions/test_uncaught_exception.exp: extras/exceptions/test_uncaught_exception.m tests/hard_coded/exceptions/Mmakefile: tests/hard_coded/exceptions/test_exceptions.exp: tests/hard_coded/exceptions/test_exceptions.m: tests/hard_coded/exceptions/test_exceptions_func.exp: tests/hard_coded/exceptions/test_exceptions_func.m: tests/hard_coded/exceptions/test_uncaught_exception.exp: tests/hard_coded/exceptions/test_uncaught_exception.exp2: tests/hard_coded/exceptions/test_uncaught_exception.m Move the exception test cases from extras/exceptions to a new directory tests/hard_coded/exceptions. Also, change the expected output for the `test_uncaught_exception' test case, since it now prints out more information. tests/hard_coded/Mmakefile: Add `exceptions' to the list of subdirectories. extras/exceptions/README: Delete this file, since the files that it refers to have now all been moved elsewhere. library/require.m: Change error/1 so that it throws an exception. library/library.m: Add exceptions.m to the list of modules in the standard library.
95 lines
2.6 KiB
Mathematica
95 lines
2.6 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1993-1999 The University of Melbourne.
|
|
% This file may only be copied under the terms of the GNU Library General
|
|
% Public License - see the file COPYING.LIB in the Mercury distribution.
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module require.
|
|
|
|
% Main author: fjh.
|
|
% Stability: medium to high.
|
|
|
|
% This module provides features similar to <assert.h> in C.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
:- interface.
|
|
|
|
:- type software_error ---> software_error(string).
|
|
|
|
:- pred error(string).
|
|
:- mode error(in) is erroneous.
|
|
|
|
% error(Message).
|
|
% Throw a `software_error(Message)' exception.
|
|
% This will normally cause execution to abort with an error
|
|
% message.
|
|
|
|
:- pred require(pred, string).
|
|
:- mode require((pred) is semidet, in) is det.
|
|
|
|
% require(Goal, Message).
|
|
% Call goal, and call error(Message) if Goal fails.
|
|
% This is not as useful as you might imagine, since it requires
|
|
% that the goal not produce any output variables. In
|
|
% most circumstances you should use an explicit if-then-else
|
|
% with a call to error/1 in the "else".
|
|
|
|
:- pred report_lookup_error(string, K, V).
|
|
:- mode report_lookup_error(in, in, unused) is erroneous.
|
|
|
|
% report_lookup_error(Message, Key, Value)
|
|
% Call error/1 with an error message that is appropriate for
|
|
% the failure of a lookup operation involving the specified
|
|
% Key and Value. The error message will include Message
|
|
% and information about Key and Value.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module string, list, std_util, exception.
|
|
|
|
require(Goal, Message) :-
|
|
( call(Goal) ->
|
|
true
|
|
;
|
|
error(Message),
|
|
fail
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
report_lookup_error(Msg, K, V) :-
|
|
KeyType = type_name(type_of(K)),
|
|
ValueType = type_name(type_of(V)),
|
|
functor(K, Functor, Arity),
|
|
( Arity = 0 ->
|
|
FunctorStr = Functor
|
|
;
|
|
string__int_to_string(Arity, ArityStr),
|
|
string__append_list([Functor, "/", ArityStr], FunctorStr)
|
|
),
|
|
string__append_list(
|
|
[Msg,
|
|
"\n\tKey Type: ",
|
|
KeyType,
|
|
"\n\tKey Functor: ",
|
|
FunctorStr,
|
|
"\n\tValue Type: ",
|
|
ValueType
|
|
],
|
|
ErrorString),
|
|
error(ErrorString).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Hopefully error/1 won't be called often (!), so no point inlining it.
|
|
:- pragma no_inline(error/1).
|
|
|
|
error(Message) :-
|
|
throw(software_error(Message)).
|
|
|
|
:- end_module require.
|
|
|
|
%-----------------------------------------------------------------------------%
|