\f
;;;; GENSYM tricks
+;;; GENSYM variant for easier debugging and better backtraces: append
+;;; the closest enclosing non-nil block name to the provided stem.
+(defun block-gensym (&optional (name "G") (env (when (boundp 'sb!c::*lexenv*)
+ (symbol-value 'sb!c::*lexenv*))))
+ (let ((block-name (when env
+ (car (find-if #'car (sb!c::lexenv-blocks env))))))
+ (if block-name
+ (sb!xc:gensym (format nil "~A[~A]" name block-name))
+ (sb!xc:gensym name))))
+
+;;; Compile a version of BODY for all TYPES, and dispatch to the
+;;; correct one based on the value of VAR. This was originally used
+;;; only for strings, hence the name. Renaming it to something more
+;;; generic might not be a bad idea.
+(defmacro string-dispatch ((&rest types) var &body body)
+ (let ((fun (sb!xc:gensym "STRING-DISPATCH-FUN")))
+ `(flet ((,fun (,var)
+ ,@body))
+ (declare (inline ,fun))
+ (etypecase ,var
+ ,@(loop for type in types
+ ;; TRULY-THE allows transforms to take advantage of the type
+ ;; information without need for constraint propagation.
+ collect `(,type (,fun (truly-the ,type ,var))))))))
+
;;; Automate an idiom often found in macros:
;;; (LET ((FOO (GENSYM "FOO"))
;;; (MAX-INDEX (GENSYM "MAX-INDEX-")))
(stem (if (every #'alpha-char-p symbol-name)
symbol-name
(concatenate 'string symbol-name "-"))))
- `(,symbol (gensym ,stem))))
+ `(,symbol (block-gensym ,stem))))
symbols)
,@body))
;;; macros and other code-manipulating code.)
(declaim (ftype (function (index) list) make-gensym-list))
(defun make-gensym-list (n)
- (loop repeat n collect (gensym)))
+ (loop repeat n collect (block-gensym)))
\f
;;;; miscellany
dfd))
;;; Give names to elements of a numeric sequence.
-(defmacro defenum ((&key (prefix "") (suffix "") (start 0) (step 1))
+(defmacro defenum ((&key (start 0) (step 1))
&rest identifiers)
(let ((results nil)
(index 0)
(step (eval step)))
(dolist (id identifiers)
(when id
- (multiple-value-bind (root docs)
+ (multiple-value-bind (sym docs)
(if (consp id)
(values (car id) (cdr id))
(values id nil))
- (push `(def!constant ,(symbolicate prefix root suffix)
+ (push `(def!constant ,sym
,(+ start (* step index))
,@docs)
results)))