mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-13 21:02:47 -08:00
Implemented hooks for users to trap compiler conditions, based on WITH-COMPILATION-UNIT
This commit is contained in:
parent
d25466375a
commit
866cba66d7
3 changed files with 59 additions and 8 deletions
|
|
@ -6,6 +6,23 @@ ECL 0.9l-p1:
|
|||
- The compiler now signals compiler-error, compiler-warning and compiler-note
|
||||
for errors, warnings and notes, respectively.
|
||||
|
||||
- WITH-COMPILATION-UNIT allows the user to set up handlers for different
|
||||
compiler conditions, including errors, warnings and simple notes. The
|
||||
recommended procedure is to use HANDLER-BIND and _NOT_ to transfer control
|
||||
out of the handler, but to defer to the default ones.
|
||||
(use-package :c)
|
||||
(let ((messages nil))
|
||||
(with-compilation-unit ()
|
||||
(handler-bind ((compiler-error #'(lambda (c)
|
||||
(push c messages)
|
||||
(abort)))
|
||||
(compiler-message #'(lambda (c) (push c messages))))
|
||||
(compile-file "foo.lsp")))
|
||||
(format t "~&;;; Printing messages")
|
||||
(loop for m in (nreverse messages)
|
||||
for i from 0
|
||||
do (format t "~&~@<;;; ~@;Message #~D~%~A~:>" i m)))
|
||||
|
||||
* Bugs fixed:
|
||||
|
||||
- The optimizer for COERCE might enter an infinite loop for certain
|
||||
|
|
|
|||
|
|
@ -28,6 +28,16 @@
|
|||
"BUILD-FASL"
|
||||
"BUILD-STATIC-LIBRARY"
|
||||
"BUILD-SHARED-LIBRARY"
|
||||
"COMPILER-WARNING"
|
||||
"COMPILER-NOTE"
|
||||
"COMPILER-MESSAGE"
|
||||
"COMPILER-ERROR"
|
||||
"COMPILER-FATAL-ERROR"
|
||||
"COMPILER-INTERNAL-ERROR"
|
||||
"COMPILER-UNDEFINED-VARIABLE"
|
||||
"COMPILER-MESSAGE-FILE"
|
||||
"COMPILER-MESSAGE-FILE-POSITION"
|
||||
"COMPILER-MESSAGE-FORM"
|
||||
"*SUPPRESS-COMPILER-WARNINGS*"
|
||||
"*SUPPRESS-COMPILER-NOTES*")
|
||||
(:import-from "SI" "GET-SYSPROP" "PUT-SYSPROP" "REM-SYSPROP" "MACRO"
|
||||
|
|
@ -252,6 +262,10 @@
|
|||
(defvar *error-p* nil)
|
||||
(defconstant *cmperr-tag* (cons nil nil))
|
||||
|
||||
(defvar *active-handlers* nil)
|
||||
(defvar *active-protection* nil)
|
||||
(defvar *pending-actions* nil)
|
||||
|
||||
(defvar *compiler-conditions* '()
|
||||
"This variable determines whether conditions are printed or just accumulated.")
|
||||
|
||||
|
|
|
|||
|
|
@ -66,18 +66,38 @@
|
|||
(print-compiler-message c t)
|
||||
(invoke-restart (find-restart-never-fail 'abort-form c)))
|
||||
|
||||
(defun do-compilation-unit (closure &key override)
|
||||
(cond (override
|
||||
(let* ((*active-handlers* nil)
|
||||
(*active-protection* nil))
|
||||
(do-compilation-unit closure)))
|
||||
((null *active-protection*)
|
||||
(let* ((*active-protection* t)
|
||||
(*pending-actions* nil))
|
||||
(unwind-protect (do-compilation-unit closure)
|
||||
(loop for action in *pending-actions*
|
||||
do (funcall action)))))
|
||||
((null *active-handlers*)
|
||||
(let ((*active-handlers* t))
|
||||
(handler-bind ((compiler-note #'handle-note)
|
||||
(compiler-warning #'handle-warning)
|
||||
(compiler-error #'handle-error)
|
||||
(compiler-fatal-error #'handle-fatal-error))
|
||||
(funcall closure))))
|
||||
(t
|
||||
(funcall closure))))
|
||||
|
||||
(defmacro with-compilation-unit ((&rest options) &body body)
|
||||
`(do-compilation-unit #'(lambda () ,@body) ,@options))
|
||||
|
||||
(defmacro with-compiler-env ((error-flag) &body body)
|
||||
`(with-lock (+load-compile-lock+)
|
||||
(restart-case
|
||||
(handler-bind ((compiler-note #'handle-note)
|
||||
(compiler-warning #'handle-warning)
|
||||
(compiler-error #'handle-error)
|
||||
(compiler-fatal-error #'handle-fatal-error))
|
||||
(let ,+init-env-form+
|
||||
(setf ,error-flag nil)
|
||||
(let ,+init-env-form+
|
||||
(setf ,error-flag nil)
|
||||
(with-compilation-unit ()
|
||||
,@body))
|
||||
(abort (c) (setf ,error-flag t))
|
||||
(abort-form (c) (setf ,error-flag t)))))
|
||||
(abort (c) (setf ,error-flag t)))))
|
||||
|
||||
(defvar *c1form-level* 0)
|
||||
(defun print-c1forms (form)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue