Permalink
Browse files

0.8alpha.0.28:

	Fix bug 47d (DEFGENERIC must signal PROGRAM-ERROR when
	attempting to create a generic function with the same name as a
	special operator).
	... sounds easy, huh?  No.
	... make COMPILER-ERROR not inherit from ERROR any more, so that
		user handlers don't (wrongly) claim to handle it;
	... establish a handler for COMPILER-ERROR around the evaluator
		that delegates to the compiler handlers if present, but
		handles them itself if not...
	... by signalling an error from a new internal restart, to allow
		user handlers for ERROR and friends a chance to run.
  • Loading branch information...
1 parent ac85367 commit 6f095a43607506faaceedb8b22633a5770bd7f7a @csrhodes csrhodes committed May 13, 2003
Showing with 261 additions and 198 deletions.
  1. +0 −18 BUGS
  2. +3 −0 NEWS
  3. +185 −158 src/code/eval.lisp
  4. +58 −9 src/compiler/compiler-error.lisp
  5. +1 −1 src/compiler/ir1report.lisp
  6. +3 −1 tests/clos.impure.lisp
  7. +10 −10 tests/compiler.pure.lisp
  8. +1 −1 version.lisp-expr
View
18 BUGS
@@ -258,24 +258,6 @@ WORKAROUND:
not a binary input stream, but instead cheerfully reads from
character streams, e.g. (MAKE-STRING-INPUT-STREAM "abc").
-47:
- DEFCLASS bugs reported by Peter Van Eynde July 25, 2000:
- d: (DEFGENERIC IF (X)) should signal a PROGRAM-ERROR, but instead
- causes a COMPILER-ERROR.
-
-51:
- miscellaneous errors reported by Peter Van Eynde July 25, 2000:
- a: (PROGN
- (DEFGENERIC FOO02 (X))
- (DEFMETHOD FOO02 ((X NUMBER)) T)
- (LET ((M (FIND-METHOD (FUNCTION FOO02)
- NIL
- (LIST (FIND-CLASS (QUOTE NUMBER))))))
- (REMOVE-METHOD (FUNCTION FOO02) M)
- (DEFGENERIC FOO03 (X))
- (ADD-METHOD (FUNCTION FOO03) M)))
- should give an error, but SBCL allows it.
-
60:
The debugger LIST-LOCATIONS command doesn't work properly.
View
3 NEWS
@@ -1722,6 +1722,9 @@ changes in sbcl-0.8.0 relative to sbcl-0.8alpha.0
SB-MOP:EFFECTIVE-SLOT-DEFINITION-CLASS now have the
specified-by-AMOP lambda list of (CLASS &REST INITARGS).
* compiler checks for duplicated variables in macro lambda lists.
+ * fixed bug 47.d: (DEFGENERIC IF (X)) now signals a PROGRAM-ERROR,
+ not a COMPILER-ERROR (followed by some other strange error on
+ choosing the CONTINUE restart).
* fixed some bugs revealed by Paul Dietz' test suite:
** the GENERIC-FUNCTION type is no longer disjoint from FUNCTION
types.
View
@@ -14,11 +14,17 @@
;;; general case of EVAL (except in that it can't handle toplevel
;;; EVAL-WHEN magic properly): Delegate to #'COMPILE.
(defun %eval (expr lexenv)
- (funcall (sb!c:compile-in-lexenv
- (gensym "EVAL-TMPFUN-")
- `(lambda ()
- ,expr)
- lexenv)))
+ ;; FIXME: It might be nice to quieten the toplevel by muffling
+ ;; warnings generated by this compilation (since we're about to
+ ;; execute the results irrespective of the warnings). We might want
+ ;; to be careful about not muffling warnings arising from inner
+ ;; evaluations/compilations, though [e.g. the ignored variable in
+ ;; (DEFUN FOO (X) 1)]. -- CSR, 2003-05-13
+ (let ((fun (sb!c:compile-in-lexenv (gensym "EVAL-TMPFUN-")
+ `(lambda ()
+ ,expr)
+ lexenv)))
+ (funcall fun)))
;;; Handle PROGN and implicit PROGN.
(defun eval-progn-body (progn-body lexenv)
@@ -52,159 +58,180 @@
(defun eval-in-lexenv (original-exp lexenv)
(declare (optimize (safety 1)))
;; (aver (lexenv-simple-p lexenv))
- (let ((exp (macroexpand original-exp lexenv)))
- (typecase exp
- (symbol
- (ecase (info :variable :kind exp)
- (:constant
- (values (info :variable :constant-value exp)))
- ((:special :global)
- (symbol-value exp))
- ;; FIXME: This special case here is a symptom of non-ANSI
- ;; weirdness in SBCL's ALIEN implementation, which could
- ;; cause problems for e.g. code walkers. It'd probably be
- ;; good to ANSIfy it by making alien variable accessors into
- ;; ordinary forms, e.g. (SB-UNIX:ENV) and (SETF SB-UNIX:ENV),
- ;; instead of magical symbols, e.g. plain SB-UNIX:ENV. Then
- ;; if the old magical-symbol syntax is to be retained for
- ;; compatibility, it can be implemented with
- ;; DEFINE-SYMBOL-MACRO, keeping the code walkers happy.
- (:alien
- (%eval original-exp lexenv))))
- (list
- (let ((name (first exp))
- (n-args (1- (length exp))))
- (case name
- ((function)
- (unless (= n-args 1)
- (error "wrong number of args to FUNCTION:~% ~S" exp))
- (let ((name (second exp)))
- (if (and (legal-fun-name-p name)
- (not (consp (let ((sb!c:*lexenv* lexenv))
- (sb!c:lexenv-find name funs)))))
- (fdefinition name)
- (%eval original-exp lexenv))))
- ((quote)
- (unless (= n-args 1)
- (error "wrong number of args to QUOTE:~% ~S" exp))
- (second exp))
- (setq
- (unless (evenp n-args)
- (error "odd number of args to SETQ:~% ~S" exp))
- (unless (zerop n-args)
- (do ((name (cdr exp) (cddr name)))
- ((null name)
- (do ((args (cdr exp) (cddr args)))
- ((null (cddr args))
- ;; We duplicate the call to SET so that the
- ;; correct value gets returned.
- (set (first args) (eval (second args))))
- (set (first args) (eval (second args)))))
- (let ((symbol (first name)))
- (case (info :variable :kind symbol)
- ;; FIXME: I took out the *TOPLEVEL-AUTO-DECLARE*
- ;; test here, and removed the *TOPLEVEL-AUTO-DECLARE*
- ;; variable; the code should now act as though that
- ;; variable is NIL. This should be tested..
- (:special)
- (t (return (%eval original-exp lexenv))))))))
- ((progn)
- (eval-progn-body (rest exp) lexenv))
- ((eval-when)
- ;; FIXME: DESTRUCTURING-BIND returns ARG-COUNT-ERROR
- ;; instead of PROGRAM-ERROR when there's something wrong
- ;; with the syntax here (e.g. missing SITUATIONS). This
- ;; could be fixed by hand-crafting clauses to catch and
- ;; report each possibility, but it would probably be
- ;; cleaner to write a new macro
- ;; DESTRUCTURING-BIND-PROGRAM-SYNTAX which does
- ;; DESTRUCTURING-BIND and promotes any mismatch to
- ;; PROGRAM-ERROR, then to use it here and in (probably
- ;; dozens of) other places where the same problem arises.
- (destructuring-bind (eval-when situations &rest body) exp
- (declare (ignore eval-when))
- (multiple-value-bind (ct lt e)
- (sb!c:parse-eval-when-situations situations)
- ;; CLHS 3.8 - Special Operator EVAL-WHEN: The use of
- ;; the situation :EXECUTE (or EVAL) controls whether
- ;; evaluation occurs for other EVAL-WHEN forms; that
- ;; is, those that are not top level forms, or those in
- ;; code processed by EVAL or COMPILE. If the :EXECUTE
- ;; situation is specified in such a form, then the
- ;; body forms are processed as an implicit PROGN;
- ;; otherwise, the EVAL-WHEN form returns NIL.
- (declare (ignore ct lt))
- (when e
- (eval-progn-body body lexenv)))))
- ((locally)
- (multiple-value-bind (body decls) (parse-body (rest exp) nil)
- (let ((lexenv
- ;; KLUDGE: Uh, yeah. I'm not anticipating
- ;; winning any prizes for this code, which was
- ;; written on a "let's get it to work" basis.
- ;; These seem to be the variables that need
- ;; bindings for PROCESS-DECLS to work
- ;; (*FREE-FUNS* and *FREE-VARS* so that
- ;; references to free functions and variables in
- ;; the declarations can be noted;
- ;; *UNDEFINED-WARNINGS* so that warnings about
- ;; undefined things can be accumulated [and then
- ;; thrown away, as it happens]). -- CSR, 2002-10-24
- (let ((sb!c:*lexenv* lexenv)
- (sb!c::*free-funs* (make-hash-table :test 'equal))
- (sb!c::*free-vars* (make-hash-table :test 'eq))
- (sb!c::*undefined-warnings* nil))
- (sb!c::process-decls decls
- nil nil
- (sb!c::make-continuation)
- lexenv))))
- (eval-progn-body body lexenv))))
- ((macrolet)
- (destructuring-bind (definitions &rest body)
- (rest exp)
- ;; FIXME: shared code with FUNCALL-IN-FOOMACROLET-LEXENV
- (declare (type list definitions))
- (unless (= (length definitions)
- (length (remove-duplicates definitions :key #'first)))
- (style-warn "duplicate definitions in ~S" definitions))
- (let ((lexenv
- (sb!c::make-lexenv
- :default lexenv
- :funs (mapcar
- (sb!c::macrolet-definitionize-fun
- :eval
- ;; I'm not sure that this is the correct
- ;; LEXENV to be compiling local macros
- ;; in...
- lexenv)
- definitions))))
- (eval-in-lexenv `(locally ,@body) lexenv))))
- ((symbol-macrolet)
- (destructuring-bind (definitions &rest body)
- (rest exp)
- ;; FIXME: shared code with FUNCALL-IN-FOOMACROLET-LEXENV
- (declare (type list definitions))
- (unless (= (length definitions)
- (length (remove-duplicates definitions :key #'first)))
- (style-warn "duplicate definitions in ~S" definitions))
- (let ((lexenv
- (sb!c::make-lexenv
- :default lexenv
- :vars (mapcar
- (sb!c::symbol-macrolet-definitionize-fun
- :eval)
- definitions))))
- (eval-in-lexenv `(locally ,@body) lexenv))))
- (t
- (if (and (symbolp name)
- (eq (info :function :kind name) :function))
- (collect ((args))
- (dolist (arg (rest exp))
- (args (eval-in-lexenv arg lexenv)))
- (apply (symbol-function name) (args)))
- (%eval exp lexenv))))))
- (t
- exp))))
+ (handler-bind
+ ((sb!c:compiler-error
+ (lambda (c)
+ (if (boundp 'sb!c::*compiler-error-bailout*)
+ ;; if we're in the compiler, delegate either to a higher
+ ;; authority or, if that's us, back down to the
+ ;; outermost compiler handler...
+ (progn
+ (signal c)
+ nil)
+ ;; ... if we're not in the compiler, better signal a
+ ;; program error straight away.
+ (invoke-restart 'sb!c::signal-program-error)))))
+ (let ((exp (macroexpand original-exp lexenv)))
+ (typecase exp
+ (symbol
+ (ecase (info :variable :kind exp)
+ (:constant
+ (values (info :variable :constant-value exp)))
+ ((:special :global)
+ (symbol-value exp))
+ ;; FIXME: This special case here is a symptom of non-ANSI
+ ;; weirdness in SBCL's ALIEN implementation, which could
+ ;; cause problems for e.g. code walkers. It'd probably be
+ ;; good to ANSIfy it by making alien variable accessors
+ ;; into ordinary forms, e.g. (SB-UNIX:ENV) and (SETF
+ ;; SB-UNIX:ENV), instead of magical symbols, e.g. plain
+ ;; SB-UNIX:ENV. Then if the old magical-symbol syntax is to
+ ;; be retained for compatibility, it can be implemented
+ ;; with DEFINE-SYMBOL-MACRO, keeping the code walkers
+ ;; happy.
+ (:alien
+ (%eval original-exp lexenv))))
+ (list
+ (let ((name (first exp))
+ (n-args (1- (length exp))))
+ (case name
+ ((function)
+ (unless (= n-args 1)
+ (error "wrong number of args to FUNCTION:~% ~S" exp))
+ (let ((name (second exp)))
+ (if (and (legal-fun-name-p name)
+ (not (consp (let ((sb!c:*lexenv* lexenv))
+ (sb!c:lexenv-find name funs)))))
+ (fdefinition name)
+ (%eval original-exp lexenv))))
+ ((quote)
+ (unless (= n-args 1)
+ (error "wrong number of args to QUOTE:~% ~S" exp))
+ (second exp))
+ (setq
+ (unless (evenp n-args)
+ (error "odd number of args to SETQ:~% ~S" exp))
+ (unless (zerop n-args)
+ (do ((name (cdr exp) (cddr name)))
+ ((null name)
+ (do ((args (cdr exp) (cddr args)))
+ ((null (cddr args))
+ ;; We duplicate the call to SET so that the
+ ;; correct value gets returned.
+ (set (first args) (eval (second args))))
+ (set (first args) (eval (second args)))))
+ (let ((symbol (first name)))
+ (case (info :variable :kind symbol)
+ ;; FIXME: I took out the *TOPLEVEL-AUTO-DECLARE*
+ ;; test here, and removed the
+ ;; *TOPLEVEL-AUTO-DECLARE* variable; the code
+ ;; should now act as though that variable is
+ ;; NIL. This should be tested..
+ (:special)
+ (t (return (%eval original-exp lexenv))))))))
+ ((progn)
+ (eval-progn-body (rest exp) lexenv))
+ ((eval-when)
+ ;; FIXME: DESTRUCTURING-BIND returns ARG-COUNT-ERROR
+ ;; instead of PROGRAM-ERROR when there's something wrong
+ ;; with the syntax here (e.g. missing SITUATIONS). This
+ ;; could be fixed by hand-crafting clauses to catch and
+ ;; report each possibility, but it would probably be
+ ;; cleaner to write a new macro
+ ;; DESTRUCTURING-BIND-PROGRAM-SYNTAX which does
+ ;; DESTRUCTURING-BIND and promotes any mismatch to
+ ;; PROGRAM-ERROR, then to use it here and in (probably
+ ;; dozens of) other places where the same problem
+ ;; arises.
+ (destructuring-bind (eval-when situations &rest body) exp
+ (declare (ignore eval-when))
+ (multiple-value-bind (ct lt e)
+ (sb!c:parse-eval-when-situations situations)
+ ;; CLHS 3.8 - Special Operator EVAL-WHEN: The use of
+ ;; the situation :EXECUTE (or EVAL) controls whether
+ ;; evaluation occurs for other EVAL-WHEN forms; that
+ ;; is, those that are not top level forms, or those
+ ;; in code processed by EVAL or COMPILE. If the
+ ;; :EXECUTE situation is specified in such a form,
+ ;; then the body forms are processed as an implicit
+ ;; PROGN; otherwise, the EVAL-WHEN form returns NIL.
+ (declare (ignore ct lt))
+ (when e
+ (eval-progn-body body lexenv)))))
+ ((locally)
+ (multiple-value-bind (body decls) (parse-body (rest exp) nil)
+ (let ((lexenv
+ ;; KLUDGE: Uh, yeah. I'm not anticipating
+ ;; winning any prizes for this code, which was
+ ;; written on a "let's get it to work" basis.
+ ;; These seem to be the variables that need
+ ;; bindings for PROCESS-DECLS to work
+ ;; (*FREE-FUNS* and *FREE-VARS* so that
+ ;; references to free functions and variables
+ ;; in the declarations can be noted;
+ ;; *UNDEFINED-WARNINGS* so that warnings about
+ ;; undefined things can be accumulated [and
+ ;; then thrown away, as it happens]). -- CSR,
+ ;; 2002-10-24
+ (let ((sb!c:*lexenv* lexenv)
+ (sb!c::*free-funs* (make-hash-table :test 'equal))
+ (sb!c::*free-vars* (make-hash-table :test 'eq))
+ (sb!c::*undefined-warnings* nil))
+ (sb!c::process-decls decls
+ nil nil
+ (sb!c::make-continuation)
+ lexenv))))
+ (eval-progn-body body lexenv))))
+ ((macrolet)
+ (destructuring-bind (definitions &rest body)
+ (rest exp)
+ ;; FIXME: shared code with
+ ;; FUNCALL-IN-FOOMACROLET-LEXENV
+ (declare (type list definitions))
+ (unless (= (length definitions)
+ (length (remove-duplicates definitions
+ :key #'first)))
+ (style-warn "duplicate definitions in ~S" definitions))
+ (let ((lexenv
+ (sb!c::make-lexenv
+ :default lexenv
+ :funs (mapcar
+ (sb!c::macrolet-definitionize-fun
+ :eval
+ ;; I'm not sure that this is the
+ ;; correct LEXENV to be compiling
+ ;; local macros in...
+ lexenv)
+ definitions))))
+ (eval-in-lexenv `(locally ,@body) lexenv))))
+ ((symbol-macrolet)
+ (destructuring-bind (definitions &rest body)
+ (rest exp)
+ ;; FIXME: shared code with
+ ;; FUNCALL-IN-FOOMACROLET-LEXENV
+ (declare (type list definitions))
+ (unless (= (length definitions)
+ (length (remove-duplicates definitions
+ :key #'first)))
+ (style-warn "duplicate definitions in ~S" definitions))
+ (let ((lexenv
+ (sb!c::make-lexenv
+ :default lexenv
+ :vars (mapcar
+ (sb!c::symbol-macrolet-definitionize-fun
+ :eval)
+ definitions))))
+ (eval-in-lexenv `(locally ,@body) lexenv))))
+ (t
+ (if (and (symbolp name)
+ (eq (info :function :kind name) :function))
+ (collect ((args))
+ (dolist (arg (rest exp))
+ (args (eval-in-lexenv arg lexenv)))
+ (apply (symbol-function name) (args)))
+ (%eval exp lexenv))))))
+ (t
+ exp)))))
;;; miscellaneous full function definitions of things which are
;;; ordinarily handled magically by the compiler
Oops, something went wrong.

0 comments on commit 6f095a4

Please sign in to comment.