X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/sod/blobdiff_plain/8b06ce6e1f3af2c684aac89dc86dc66d135ea876..4ee476bc29b80fca2faabb4bd286ca70c98f7a44:/src/class-finalize-proto.lisp diff --git a/src/class-finalize-proto.lisp b/src/class-finalize-proto.lisp index 7d7a992..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. @@ -106,6 +146,16 @@ (defgeneric finalize-sod-class (class) * The class is checked for compiance with the well-formedness rules. - * The layout chains are computed.")) + * 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. + See also `finalization-error' and `finalization-failed' above.")) ;;;----- That's all, folks --------------------------------------------------