X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fprimordial-extensions.lisp;h=0ca98ac2675daf5171b832543a47cd9927b2629e;hb=5762f26aae78beaead9919074963f67d92794599;hp=f9293bea9ddd7f7b3f82959ea09a57bb34e3f577;hpb=4898ef32c639b1c7f4ee13a5ba566ce6debd03e6;p=sbcl.git diff --git a/src/code/primordial-extensions.lisp b/src/code/primordial-extensions.lisp index f9293be..0ca98ac 100644 --- a/src/code/primordial-extensions.lisp +++ b/src/code/primordial-extensions.lisp @@ -124,6 +124,21 @@ ;;;; GENSYM tricks +;;; 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-"))) @@ -145,9 +160,14 @@ ;;; Return a list of N gensyms. (This is a common suboperation in ;;; macros and other code-manipulating code.) -(declaim (ftype (function (index) list) make-gensym-list)) -(defun make-gensym-list (n) - (loop repeat n collect (gensym))) +(declaim (ftype (function (index &optional t) (values list &optional)) + make-gensym-list)) +(defun make-gensym-list (n &optional name) + (when (eq t name) + (break)) + (if name + (loop repeat n collect (gensym (string name))) + (loop repeat n collect (gensym)))) ;;;; miscellany @@ -177,6 +197,11 @@ (replace name x :start1 index) (incf index len))))))) +(defun gensymify (x) + (if (symbolp x) + (sb!xc:gensym (symbol-name x)) + (sb!xc:gensym))) + ;;; like SYMBOLICATE, but producing keywords (defun keywordicate (&rest things) (let ((*package* *keyword-package*)) @@ -236,7 +261,7 @@ 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) @@ -244,11 +269,11 @@ (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)))