| 1 |
(in-package :alexandria) |
|---|
| 2 |
|
|---|
| 3 |
(declaim (inline ensure-symbol)) |
|---|
| 4 |
(defun ensure-symbol (name &optional (package *package*)) |
|---|
| 5 |
"Returns a symbol with name designated by NAME, accessible in package |
|---|
| 6 |
designated by PACKAGE. If symbol is not already accessible in PACKAGE, it is |
|---|
| 7 |
interned there. Returns a secondary value reflecting the status of the symbol |
|---|
| 8 |
in the package, which matches the secondary return value of INTERN. |
|---|
| 9 |
|
|---|
| 10 |
Example: (ENSURE-SYMBOL :CONS :CL) => CL:CONS, :EXTERNAL" |
|---|
| 11 |
(intern (string name) package)) |
|---|
| 12 |
|
|---|
| 13 |
(defun maybe-intern (name package) |
|---|
| 14 |
(values |
|---|
| 15 |
(if package |
|---|
| 16 |
(intern name (if (eq t package) *package* package)) |
|---|
| 17 |
(make-symbol name)))) |
|---|
| 18 |
|
|---|
| 19 |
(declaim (inline format-symbol)) |
|---|
| 20 |
(defun format-symbol (package control &rest arguments) |
|---|
| 21 |
"Constructs a string by applying ARGUMENTS to CONTROL as if by FORMAT, and |
|---|
| 22 |
then creates a symbol named by that string. If PACKAGE is NIL, returns an |
|---|
| 23 |
uninterned symbol, if package is T, returns a symbol interned in the current |
|---|
| 24 |
package, and otherwise returns a symbol interned in the package designated by |
|---|
| 25 |
PACKAGE." |
|---|
| 26 |
(maybe-intern (apply #'format nil control arguments) package)) |
|---|
| 27 |
|
|---|
| 28 |
(defun make-keyword (name) |
|---|
| 29 |
"Interns the string designated by NAME in the KEYWORD package." |
|---|
| 30 |
(intern (string name) :keyword)) |
|---|
| 31 |
|
|---|
| 32 |
(defun make-gensym (name) |
|---|
| 33 |
"If NAME is a non-negative integer, calls GENSYM using it. Otherwise NAME |
|---|
| 34 |
must be a string designator, in which case calls GENSYM using the designated |
|---|
| 35 |
string as the argument." |
|---|
| 36 |
(gensym (if (typep name '(integer 0)) |
|---|
| 37 |
name |
|---|
| 38 |
(string name)))) |
|---|
| 39 |
|
|---|
| 40 |
(defun make-gensym-list (length &optional (x "G")) |
|---|
| 41 |
"Returns a list of LENGTH gensyms, each generated as if with a call to MAKE-GENSYM, |
|---|
| 42 |
using the second (optional, defaulting to \"G\") argument." |
|---|
| 43 |
(let ((g (if (typep x '(integer 0)) x (string x)))) |
|---|
| 44 |
(loop repeat length |
|---|
| 45 |
collect (gensym g)))) |
|---|
| 46 |
|
|---|
| 47 |
(defun symbolicate (&rest things) |
|---|
| 48 |
"Concatenate together the names of some strings and symbols, |
|---|
| 49 |
producing a symbol in the current package." |
|---|
| 50 |
(let* ((length (reduce #'+ things |
|---|
| 51 |
:key (lambda (x) (length (string x))))) |
|---|
| 52 |
(name (make-array length :element-type 'character))) |
|---|
| 53 |
(let ((index 0)) |
|---|
| 54 |
(dolist (thing things (values (intern name))) |
|---|
| 55 |
(let* ((x (string thing)) |
|---|
| 56 |
(len (length x))) |
|---|
| 57 |
(replace name x :start1 index) |
|---|
| 58 |
(incf index len)))))) |
|---|