(:use #:common-lisp)
(:export #:compile-time-defun
#:show
- #:stringify #:listify #:fix-pair #:pairify #:parse-body
+ #:stringify #:mappend #:listify #:fix-pair #:pairify #:parse-body
#:whitespace-char-p
#:slot-uninitialized
#:nlet #:while #:case2 #:ecase2
#:with-gensyms #:let*/gensyms #:with-places
#:locp #:locf #:ref #:with-locatives
#:update-place #:update-place-after
- #:incf-after #:decf-after))
+ #:incf-after #:decf-after
+ #:fixnump)
+ #+cmu (:import-from #:extensions #:fixnump))
+
(in-package #:mdw.base)
;;;--------------------------------------------------------------------------
(t (with-output-to-string (s)
(princ str s)))))
+(defun mappend (function list &rest more-lists)
+ "Apply FUNCTION to corresponding elements of LIST and MORE-LISTS, yielding
+ a list. Return the concatenation of all the resulting lists. Like
+ mapcan, but nondestructive."
+ (apply #'append (apply #'mapcar function list more-lists)))
+
(compile-time-defun listify (x)
"If X is a (possibly empty) list, return X; otherwise return (list X)."
(if (listp x) x (list x)))
structure definitions without doom ensuing."
(error "No initializer for slot."))
-(compile-time-defun parse-body (body)
+(compile-time-defun parse-body (body &key (allow-docstring-p t))
"Given a BODY (a list of forms), parses it into three sections: a
docstring, a list of declarations (forms beginning with the symbol
`declare') and the body forms. The result is returned as three lists
(even the docstring), suitable for interpolation into a backquoted list
- using `@,'."
- (multiple-value-bind
- (doc body)
- (if (and (consp body)
- (stringp (car body)))
- (values (list (car body)) (cdr body))
- (values nil body))
- (loop for forms on body
- for form = (car forms)
- while (and (consp form)
- (eq (car form) 'declare))
- collect form into decls
- finally (return (values doc decls forms)))))
+ using `@,'. If ALLOW-DOCSTRING-P is nil, docstrings aren't allowed at
+ all."
+ (let ((doc nil) (decls nil))
+ (do ((forms body (cdr forms))) (nil)
+ (let ((form (and forms (car forms))))
+ (cond ((and allow-docstring-p (not doc) (stringp form) (cdr forms))
+ (setf doc form))
+ ((and (consp form)
+ (eq (car form) 'declare))
+ (setf decls (append decls (cdr form))))
+ (t (return (values (and doc (list doc))
+ (and decls (list (cons 'declare decls)))
+ forms))))))))
+
+#-cmu
+(progn
+ (declaim (inline fixnump))
+ (defun fixnump (object)
+ "Answer non-nil if OBJECT is a fixnum, or nil if it isn't."
+ (typep object 'fixnum)))
;;;--------------------------------------------------------------------------
;;; Generating symbols.