Implemented hooks for users to trap compiler conditions, based on WITH-COMPILATION-UNIT

This commit is contained in:
jjgarcia 2008-08-20 20:47:33 +00:00
parent d25466375a
commit 866cba66d7
3 changed files with 59 additions and 8 deletions

View file

@ -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

View file

@ -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.")

View file

@ -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)