X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/sod/blobdiff_plain/675b48242d0f5c6f2f2563003a1d2fd87e06522c..e45a106df3272c787444bc6f7b8920016b7fc677:/src/class-finalize-proto.lisp diff --git a/src/class-finalize-proto.lisp b/src/class-finalize-proto.lisp index 80d0c12..2f589b8 100644 --- a/src/class-finalize-proto.lisp +++ b/src/class-finalize-proto.lisp @@ -25,6 +25,46 @@ (cl:in-package #:sod) +;;;-------------------------------------------------------------------------- +;;; Finalization error handling. + +;; These variables are internal to the implementation. +(defvar-unbound *finalization-errors* + "A list of tokens for errors reported about the class being finalized. + + During finalization, this is bound to a list of tokens corresponding to + the problems which have been reported so far via `finalization-error'.") +(defvar-unbound *finalization-error-token* + "The token to store in `*finalization-errors*' in the event of an error.") + +(export 'finalization-error) +(defmacro finalization-error ((token &rest args) &body body) + "Check for a kind of finalization error denoted by TOKEN and the ARGS. + + The TOKEN and ARGS are convered into an error token as follows. If no + ARGS are given, then the TOKEN itself is evaluated and used directly; + otherwise, the token is a list whose first element is the result of + evaluating TOKEN, and the remaining elements are the results of evaluating + the ARGS. Error tokens are compared with `equal'. + + If a finalization error denoted by this token has already been reported, + then do nothing: the BODY is not evaluated, and the result is nil. + Special exception: a nil token denotes a `generic' error which can be + repeated indefintely. + + If the BODY signals an error (and doesn't handle it), then the error token + is added to a list of reported errors. That way, future calls to + `finalization-error' with an equal error token won't cause the user to be + inundated with duplicate reports." + `(let ((*finalization-error-token* ,(if (null args) token + `(list ,token ,@args)))) + ,@body)) + +(export 'finalization-failed) +(defun finalization-failed () + "Give up on finalizing the current class." + (throw '%finalization-failed nil)) + ;;;-------------------------------------------------------------------------- ;;; Protocol definition. @@ -108,8 +148,14 @@ (defgeneric finalize-sod-class (class) * The layout chains are computed. + Returns a generalized boolean: non-nil if the class has been successfully + finalized -- either just now, or if it was finalized already and nothing + needed to be done -- or nil if finalization failed -- either just now, or + because the class had previously been marked as broken following a failed + finalization attempt. + User methods can assume that the class in question has not yet been - finalized. Errors during finalization can be reported in the usual - way.")) + finalized. Errors during finalization can be reported in the usual way. + See also `finalization-error' and `finalization-failed' above.")) ;;;----- That's all, folks --------------------------------------------------