X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fprimordial-extensions.lisp;h=e28cb0e33fdb333bb2e56b590097d21a5fbe8ece;hb=b9147dff981d00779cccc6b9a00be2a388bd28a6;hp=f9293bea9ddd7f7b3f82959ea09a57bb34e3f577;hpb=4898ef32c639b1c7f4ee13a5ba566ce6debd03e6;p=sbcl.git diff --git a/src/code/primordial-extensions.lisp b/src/code/primordial-extensions.lisp index f9293be..e28cb0e 100644 --- a/src/code/primordial-extensions.lisp +++ b/src/code/primordial-extensions.lisp @@ -124,6 +124,30 @@ ;;;; 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 + (gensym (format nil "~A[~A]" name block-name)) + (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 (gensym "STRING-DISPATCH-FUN-"))) + `(flet ((,fun (,var) + ,@body)) + (declare (inline ,fun)) + (etypecase ,var + ,@(loop for type in types + collect `(,type (,fun (the ,type ,var)))))))) + ;;; Automate an idiom often found in macros: ;;; (LET ((FOO (GENSYM "FOO")) ;;; (MAX-INDEX (GENSYM "MAX-INDEX-"))) @@ -139,7 +163,7 @@ (stem (if (every #'alpha-char-p symbol-name) symbol-name (concatenate 'string symbol-name "-")))) - `(,symbol (gensym ,stem)))) + `(,symbol (block-gensym ,stem)))) symbols) ,@body)) @@ -147,7 +171,7 @@ ;;; 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))) ;;;; miscellany