Included Books
other
(in-package "ACL2")
include-book
(include-book "xdoc/top" :dir :system)
include-book
(include-book "kestrel/event-macros/fail-event" :dir :system)
include-book
(include-book "kestrel/utilities/er-soft-plus" :dir :system)
other
(defxdoc orelse :parents (system-utilities-non-built-in) :short "Evaluate an event and, if it fails, then evaluate a second event" :long "<p>NOTE: Also see @(see orelse*) for a similar utility that allows any number of @(see events).</p> @({ General Form: (orelse form1 form2 :quiet q ; default nil :no-error n ; default nil :expansion?p e ; default t }) <p>where @('form1') and @('form2') are @(see events) (see @(see embedded-event-form)) and the keywords have the indicated defaults. The behavior is as follows: @('form1') is submitted and if that succeeds — that is, if the result is an @(see error-triple) @('(mv nil val state)') — then the @('orelse') call returns that error-triple. Otherwise, it return the result of evaluating @('form2'), except that if that evaluation also fails and if @(':no-error') is non-@('nil'), then evaluation concludes by submitting the event @('(value-triple :failed)').</p> <p>If @(':quiet') has a non-@('nil') value, then output is suppressed using @(tsee with-output) with argument @(':stack :push'), so that @('form1') and @('form2') may recover the original output environment using @('with-output') with argument @(':stack :pop').</p> <p>The sizes of @(see certificate) files may be reduced with @(':expansion?p t') (the default). That argument avoids storing a @(tsee make-event) expansion for @('(orelse form1 form2 ...)') when evaluation of the first event form succeeds.</p> <p>See community book @('kestrel/utilities/orelse.lisp') for a utility, @(tsee encapsulate-report-errors), that employs @('orelse').</p>")
other
(defxdoc orelse* :parents (system-utilities-non-built-in) :short "Evaluate a sequence of @(see events), until one succeeds" :long "<p>@('Orelse*') behaves as described in the documentation for @(see orelse), except that @('orelse*') takes a list of forms.</p> @({ General Form: (orelse* (form1 form2 ...) :quiet q ; default nil :no-error n ; default nil :expansion?p e ; default t })")
other
(defxdoc on-failure :parents (system-utilities-non-built-in) :short "Run an event, printing a custom error message if it fails." :long " @({ General Form: (on-failure event :ctx ctx ; default "event processing" :erp erp ; default t :val val ; default nil :msg msg ; default nil ) }) <p>where @('event') is an @(see embedded-event-form), and the other arguments are passed to @(tsee fail-event) as explained below. Thus, none of the arguments is evaluated. The General Form above expands to the following.</p> @({ (ORELSE EVENT (FAIL-EVENT CTX ERP VAL MSG)) }) <p>Thus, first @('event') is evaluated — see @(see orelse) — and either it succeeds or else the indicated error occurs — see @(see fail-event).</p> <p>Consider the following example.</p> @({ (on-failure (defund f (x) x) :ctx (defund . f) ; see :doc ctx :erp t ; see :doc er-soft+ :val nil ; see :doc er-soft+ :msg ("Failed:~|~%~x0" (#\0 . (defun f (x) x)))) }) <p>If @('f') is not already defined, then this is essentially equivalent to @('(defund f (x) x)'). But if @('f') currently has a conflicting definition, then the event will fail and the final error message, unless error output is inhibited (see @(see set-inhibit-output-lst)), will be the following.</p> @({ ACL2 Error in (DEFUND F ...): Failed: (DEFUN F (X) X) }) <p>For another example of the use of @('on-failure'), which uses the macro @(tsee msg) to construct a @(see msgp), see the definition of function @('report-event-when-error-fn') in @(see community-book) @('books/kestrel/utilities/orelse.lisp').</p>")
other
(defxdoc encapsulate-report-errors :parents (system-utilities-non-built-in) :short "Run @(tsee encapsulate), but with a helpful error at the first failure of one of its top-level events (if any)." :long "<p>This macro is equivalent to @(see encapsulate) except that it takes an extra argument, which is a @(see context), that goes in the first position. Unlike @('encapsulate'), it provides a helpful error if any of its given @(see events) fails. It uses that extra `context' argument in reporting that error. (But the error itself is reported by the event, with the usual context constructed for that event.)</p> @({ General Form: (encapsulate-report-errors ctx signature-list event1 event2 ... eventk) }) <p>where @('ctx') is a context, @('signature-list') is a list of @(see signature)s, and each @('eventi') is an @(see embedded-event-form). Note that none of these arguments is evaluated. Thus, a typical call might be laid down as follows.</p> @({ `(encapsulate-report-errors ,ctx () ,@events) }) <p>Normally, if if any of the given events (shown above as ``@('event1 event2 ... eventk')'') fails, then the output will conclude as follows, where here we write @('<CTX>') to denote the formatted context and @('<EV>') to denote the failed event printed in abbreviated form.</p> @({ ACL2 Error in <CTX>: The following event has caused an unexpected error: <EV> Please contact the implementor of the tool that you are using. }) <p>However, if the event is of the form @('(on-failure ...)'), then the specified failure message is printed instead of this generic one. See @(see on-failure).</p>")
orelse-fnfunction
(defun orelse-fn (form-list quiet no-error expansion?p) (declare (xargs :guard (true-listp form-list))) (let ((ev `(make-event '(:or ,@FORM-LIST ,@(AND NO-ERROR '((VALUE-TRIPLE :FAILED)))) ,@(AND EXPANSION?P `(:EXPANSION? ,(CAR FORM-LIST))) :on-behalf-of :quiet!))) (cond (quiet `(with-output :stack :push :gag-mode nil :off :all ,EV)) (t ev))))
orelse*macro
(defmacro orelse* (form-list &key quiet no-error (expansion?p 't)) (orelse-fn form-list quiet no-error expansion?p))
orelsemacro
(defmacro orelse (form1 form2 &key quiet no-error (expansion?p 't)) `(orelse* (,FORM1 ,FORM2) :quiet ,QUIET :no-error ,NO-ERROR :expansion?p ,EXPANSION?P))
formal-mapfunction
(defun formal-map (fn ctx lst) (declare (xargs :guard (true-listp lst))) (cond ((endp lst) nil) (t (cons `(,FN ,CTX ,(CAR LST)) (formal-map fn ctx (cdr lst))))))
on-failuremacro
(defmacro on-failure (event &key (ctx '"event processing") (erp 't) val msg) (let ((msg (or msg (msg "The following event failed:~%~X01" event (evisc-tuple 12 12 nil nil))))) `(orelse (with-output :stack :pop ,EVENT) (with-output :stack :pop (fail-event ,CTX ,ERP ,VAL ,MSG)) :quiet t)))
other
(defxdoc identity-macro :parents (system-utilities-non-built-in) :short "The most trivial macro imaginable" :long "<p>@('(Identity-macro x)') macroexpands to @('x').</p>")
identity-macromacro
(defmacro identity-macro (x) x)
report-event-when-error-fnmutual-recursion
(mutual-recursion (defun report-event-when-error-fn (ctx event) (declare (xargs :guard t)) (cond ((or (atom event) (atom (cdr event))) event) ((eq (car event) 'local) (list 'local (report-event-when-error-fn ctx (cadr event)))) ((eq (car event) 'progn) (cons 'progn (report-event-when-error-fn-lst ctx (cdr event)))) ((eq (car event) 'on-failure) event) ((eq (car event) 'identity-macro) (cadr event)) ((eq (car event) 'encapsulate) (list* 'encapsulate (cadr event) (report-event-when-error-fn-lst ctx (cddr event)))) (t `(on-failure ,EVENT :ctx ,CTX :msg ,(MSG "The following event has caused an ~ unexpected error:~|~%~x0.~|~%Please ~ contact the implementor of the tool that ~ you are using." EVENT))))) (defun report-event-when-error-fn-lst (ctx lst) (cond ((atom lst) nil) (t (cons (report-event-when-error-fn ctx (car lst)) (report-event-when-error-fn-lst ctx (cdr lst)))))))
report-event-when-errormacro
(defmacro report-event-when-error (ctx event) (report-event-when-error-fn ctx event))
encapsulate-orelse-fnfunction
(defun encapsulate-orelse-fn (fn ctx signature events) (declare (xargs :guard (true-listp events))) `(make-event (let ((events (formal-map ',FN ',CTX ',EVENTS))) (list* 'encapsulate ,SIGNATURE events)) :on-behalf-of :quiet!))
encapsulate-orelsemacro
(defmacro encapsulate-orelse (fn ctx signature &rest events) (encapsulate-orelse-fn fn ctx signature events))
encapsulate-report-errorsmacro
(defmacro encapsulate-report-errors (ctx signature &rest events) `(encapsulate-orelse report-event-when-error ,CTX ,SIGNATURE ,@EVENTS))