X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fearly-extensions.lisp;h=916d03aeb55bf005d6fd46ea11a125921d8695bd;hb=a10eba73462a7203914114f3a4bdac98c741ec08;hp=de6421e1bce986bbbceb9ac1698c82cfb0d6f378;hpb=667ec9d494530079bef28e8589dd0d3274b935ec;p=sbcl.git diff --git a/src/code/early-extensions.lisp b/src/code/early-extensions.lisp index de6421e..916d03a 100644 --- a/src/code/early-extensions.lisp +++ b/src/code/early-extensions.lisp @@ -110,8 +110,8 @@ (1- max)))) (t nil)))) -;;; Is X a circular list? -(defun circular-list-p (x) +;;; Is X a list containing a cycle? +(defun cyclic-list-p (x) (and (listp x) (labels ((safe-cddr (x) (if (listp (cdr x)) (cddr x)))) (do ((y x (safe-cddr y)) @@ -146,6 +146,13 @@ ((or (= r 0) (> d q)) (/= r 0)) (declare (fixnum inc)) (multiple-value-setq (q r) (truncate x d)))))) + +;;; Could this object contain other objects? (This is important to +;;; the implementation of things like *PRINT-CIRCLE* and the dumper.) +(defun compound-object-p (x) + (or (consp x) + (typep x 'instance) + (typep x '(array t *)))) ;;;; the COLLECT macro ;;;; @@ -289,6 +296,15 @@ (declaim (inline neq)) (defun neq (x y) (not (eq x y))) + +;;; not really an old-fashioned function, but what the calling +;;; convention should've been: like NTH, but with the same argument +;;; order as in all the other dereferencing functions, with the +;;; collection first and the index second +(declaim (inline nth-but-with-sane-arg-order)) +(declaim (ftype (function (list index) t) nth-but-with-sane-arg-order)) +(defun nth-but-with-sane-arg-order (list index) + (nth index list)) ;;;; miscellaneous iteration extensions @@ -555,7 +571,7 @@ ;;;; various operations on names ;;; Is NAME a legal function name? -(defun legal-function-name-p (name) +(defun legal-fun-name-p (name) (or (symbolp name) (and (consp name) (eq (car name) 'setf) @@ -565,16 +581,16 @@ ;;; Given a function name, return the name for the BLOCK which ;;; encloses its body (e.g. in DEFUN, DEFINE-COMPILER-MACRO, or FLET). -(declaim (ftype (function ((or symbol cons)) symbol) function-name-block-name)) -(defun function-name-block-name (function-name) - (cond ((symbolp function-name) - function-name) - ((and (consp function-name) - (= (length function-name) 2) - (eq (first function-name) 'setf)) - (second function-name)) +(declaim (ftype (function ((or symbol cons)) symbol) fun-name-block-name)) +(defun fun-name-block-name (fun-name) + (cond ((symbolp fun-name) + fun-name) + ((and (consp fun-name) + (= (length fun-name) 2) + (eq (first fun-name) 'setf)) + (second fun-name)) (t - (error "not legal as a function name: ~S" function-name)))) + (error "not legal as a function name: ~S" fun-name)))) (defun looks-like-name-of-special-var-p (x) (and (symbolp x) @@ -583,26 +599,37 @@ (char= #\* (aref name 0)) (char= #\* (aref name (1- (length name)))))))) -;;; ANSI guarantees that some symbols are self-evaluating. This -;;; function is to be called just before a change which would affect -;;; that. (We don't absolutely have to call this function before such -;;; changes, since such changes are given as undefined behavior. In -;;; particular, we don't if the runtime cost would be annoying. But -;;; otherwise it's nice to do so.) -(defun about-to-modify (symbol) +;;; Some symbols are defined by ANSI to be self-evaluating. Return +;;; non-NIL for such symbols (and make the non-NIL value a traditional +;;; message, for use in contexts where the user asks us to change such +;;; a symbol). +(defun symbol-self-evaluating-p (symbol) (declare (type symbol symbol)) (cond ((eq symbol t) - (error "Veritas aeterna. (can't change T)")) + "Veritas aeterna. (can't change T)") ((eq symbol nil) - (error "Nihil ex nihil. (can't change NIL)")) + "Nihil ex nihil. (can't change NIL)") ((keywordp symbol) - (error "Keyword values can't be changed.")) - ;; (Just because a value is CONSTANTP is not a good enough - ;; reason to complain here, because we want DEFCONSTANT to - ;; be able to use this function, and it's legal to DEFCONSTANT - ;; a constant as long as the new value is EQL to the old - ;; value.) - )) + "Keyword values can't be changed.") + (t + nil))) + +;;; This function is to be called just before a change which would +;;; affect the symbol value. (We don't absolutely have to call this +;;; function before such changes, since such changes are given as +;;; undefined behavior. In particular, we don't if the runtime cost +;;; would be annoying. But otherwise it's nice to do so.) +(defun about-to-modify-symbol-value (symbol) + (declare (type symbol symbol)) + (let ((reason (symbol-self-evaluating-p symbol))) + (when reason + (error reason))) + ;; (Note: Just because a value is CONSTANTP is not a good enough + ;; reason to complain here, because we want DEFCONSTANT to be able + ;; to use this function, and it's legal to DEFCONSTANT a constant as + ;; long as the new value is EQL to the old value.) + (values)) + ;;; If COLD-FSET occurs not at top level, just treat it as an ordinary ;;; assignment. That way things like @@ -662,10 +689,10 @@ ;;; error indicating that a required &KEY argument was not supplied. ;;; This function is also useful for DEFSTRUCT slot defaults ;;; corresponding to required arguments. -(declaim (ftype (function () nil) required-argument)) -(defun required-argument () +(declaim (ftype (function () nil) required-arg)) +(defun required-arg () #!+sb-doc - (/show0 "entering REQUIRED-ARGUMENT") + (/show0 "entering REQUIRED-ARG") (error "A required &KEY or &OPTIONAL argument was not supplied.")) ;;; like CL:ASSERT and CL:CHECK-TYPE, but lighter-weight