1.0.22.22: (SETF FIND-CLASSOID) to drop DEFTYPE lambda-lists and source-locations
[sbcl/tcr.git] / src / code / symbol.lisp
blob58f3fc19d0b600575400af25881edce04fbbcaa2
1 ;;;; code to manipulate symbols (but not packages, which are handled
2 ;;;; elsewhere)
3 ;;;;
4 ;;;; Many of these definitions are trivial interpreter entries to
5 ;;;; functions open-coded by the compiler.
7 ;;;; This software is part of the SBCL system. See the README file for
8 ;;;; more information.
9 ;;;;
10 ;;;; This software is derived from the CMU CL system, which was
11 ;;;; written at Carnegie Mellon University and released into the
12 ;;;; public domain. The software is in the public domain and is
13 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
14 ;;;; files for more information.
16 (in-package "SB!IMPL")
18 (declaim (maybe-inline get get2 get3 %put getf remprop %putf get-properties keywordp))
20 (defun symbol-value (symbol)
21 #!+sb-doc
22 "Return SYMBOL's current bound value."
23 (declare (optimize (safety 1)))
24 (symbol-value symbol))
26 (defun boundp (symbol)
27 #!+sb-doc
28 "Return non-NIL if SYMBOL is bound to a value."
29 (boundp symbol))
31 (defun set (symbol new-value)
32 #!+sb-doc
33 "Set SYMBOL's value cell to NEW-VALUE."
34 (declare (type symbol symbol))
35 (about-to-modify-symbol-value symbol "set SYMBOL-VALUE of ~S" new-value)
36 (%set-symbol-value symbol new-value))
38 (defun %set-symbol-value (symbol new-value)
39 (%set-symbol-value symbol new-value))
41 (declaim (inline %makunbound))
42 (defun %makunbound (symbol)
43 (%set-symbol-value symbol (%primitive sb!c:make-other-immediate-type
44 0 sb!vm:unbound-marker-widetag)))
46 (defun makunbound (symbol)
47 #!+sb-doc
48 "Make SYMBOL unbound, removing any value it may currently have."
49 (with-single-package-locked-error (:symbol symbol "unbinding the symbol ~A")
50 (about-to-modify-symbol-value symbol "make ~S unbound")
51 (%makunbound symbol)
52 symbol))
54 ;;; Return the built-in hash value for SYMBOL.
55 (defun symbol-hash (symbol)
56 (symbol-hash symbol))
58 (defun symbol-function (symbol)
59 #!+sb-doc
60 "Return SYMBOL's current function definition. Settable with SETF."
61 (%coerce-name-to-fun symbol))
63 (defun (setf symbol-function) (new-value symbol)
64 (declare (type symbol symbol) (type function new-value))
65 (with-single-package-locked-error
66 (:symbol symbol "setting the symbol-function of ~A")
67 (setf (%coerce-name-to-fun symbol) new-value)))
69 (defun symbol-plist (symbol)
70 #!+sb-doc
71 "Return SYMBOL's property list."
72 (symbol-plist symbol))
74 (defun %set-symbol-plist (symbol new-value)
75 (setf (symbol-plist symbol) new-value))
77 (defun symbol-name (symbol)
78 #!+sb-doc
79 "Return SYMBOL's name as a string."
80 (symbol-name symbol))
82 (defun symbol-package (symbol)
83 #!+sb-doc
84 "Return the package SYMBOL was interned in, or NIL if none."
85 (symbol-package symbol))
87 (defun %set-symbol-package (symbol package)
88 (declare (type symbol symbol))
89 (%set-symbol-package symbol package))
91 (defun make-symbol (string)
92 #!+sb-doc
93 "Make and return a new symbol with the STRING as its print name."
94 (declare (type string string))
95 (%make-symbol (if (simple-string-p string)
96 string
97 (subseq string 0))))
99 (defun get (symbol indicator &optional (default nil))
100 #!+sb-doc
101 "Look on the property list of SYMBOL for the specified INDICATOR. If this
102 is found, return the associated value, else return DEFAULT."
103 (get3 symbol indicator default))
105 (defun get2 (symbol indicator)
106 (get3 symbol indicator nil))
108 (let (cdr-pl)
109 (do ((pl (symbol-plist symbol) (cdr cdr-pl)))
110 ((atom pl) nil)
111 (setf cdr-pl (cdr pl))
112 (cond ((atom cdr-pl)
113 (error "~S has an odd number of items in its property list."
114 symbol))
115 ((eq (car pl) indicator)
116 (return (car cdr-pl)))))))
119 (defun get3 (symbol indicator default)
120 (let (cdr-pl)
121 (do ((pl (symbol-plist symbol) (cdr cdr-pl)))
122 ((atom pl) default)
123 (setq cdr-pl (cdr pl))
124 (cond ((atom cdr-pl)
125 (error "~S has an odd number of items in its property list."
126 symbol))
127 ((eq (car pl) indicator)
128 (return (car cdr-pl)))))))
130 (defun %put (symbol indicator value)
131 #!+sb-doc
132 "The VALUE is added as a property of SYMBOL under the specified INDICATOR.
133 Returns VALUE."
134 (do ((pl (symbol-plist symbol) (cddr pl)))
135 ((endp pl)
136 (setf (symbol-plist symbol)
137 (list* indicator value (symbol-plist symbol)))
138 value)
139 (cond ((endp (cdr pl))
140 (error "~S has an odd number of items in its property list."
141 symbol))
142 ((eq (car pl) indicator)
143 (rplaca (cdr pl) value)
144 (return value)))))
146 (defun remprop (symbol indicator)
147 #!+sb-doc
148 "Look on property list of SYMBOL for property with specified
149 INDICATOR. If found, splice this indicator and its value out of
150 the plist, and return the tail of the original list starting with
151 INDICATOR. If not found, return () with no side effects.
153 NOTE: The ANSI specification requires REMPROP to return true (not false)
154 or false (the symbol NIL). Portable code should not rely on any other value."
155 (do ((pl (symbol-plist symbol) (cddr pl))
156 (prev nil pl))
157 ((atom pl) nil)
158 (cond ((atom (cdr pl))
159 (error "~S has an odd number of items in its property list."
160 symbol))
161 ((eq (car pl) indicator)
162 (cond (prev (rplacd (cdr prev) (cddr pl)))
164 (setf (symbol-plist symbol) (cddr pl))))
165 (return pl)))))
167 (defun getf (place indicator &optional (default ()))
168 #!+sb-doc
169 "Search the property list stored in Place for an indicator EQ to INDICATOR.
170 If one is found, return the corresponding value, else return DEFAULT."
171 (do ((plist place (cddr plist)))
172 ((null plist) default)
173 (cond ((atom (cdr plist))
174 (error 'simple-type-error
175 :format-control "malformed property list: ~S."
176 :format-arguments (list place)
177 :datum (cdr plist)
178 :expected-type 'cons))
179 ((eq (car plist) indicator)
180 (return (cadr plist))))))
182 (defun %putf (place property new-value)
183 (declare (type list place))
184 (do ((plist place (cddr plist)))
185 ((endp plist) (list* property new-value place))
186 (declare (type list plist))
187 (when (eq (car plist) property)
188 (setf (cadr plist) new-value)
189 (return place))))
191 (defun get-properties (place indicator-list)
192 #!+sb-doc
193 "Like GETF, except that INDICATOR-LIST is a list of indicators which will
194 be looked for in the property list stored in PLACE. Three values are
195 returned, see manual for details."
196 (do ((plist place (cddr plist)))
197 ((null plist) (values nil nil nil))
198 (cond ((atom (cdr plist))
199 (error 'simple-type-error
200 :format-control "malformed property list: ~S."
201 :format-arguments (list place)
202 :datum (cdr plist)
203 :expected-type 'cons))
204 ((memq (car plist) indicator-list)
205 (return (values (car plist) (cadr plist) plist))))))
207 (defun copy-symbol (symbol &optional (copy-props nil) &aux new-symbol)
208 #!+sb-doc
209 "Make and return a new uninterned symbol with the same print name
210 as SYMBOL. If COPY-PROPS is false, the new symbol is neither bound
211 nor fbound and has no properties, else it has a copy of SYMBOL's
212 function, value and property list."
213 (declare (type symbol symbol))
214 (setq new-symbol (make-symbol (symbol-name symbol)))
215 (when copy-props
216 (%set-symbol-value new-symbol
217 (%primitive sb!c:fast-symbol-value symbol))
218 (setf (symbol-plist new-symbol)
219 (copy-list (symbol-plist symbol)))
220 (when (fboundp symbol)
221 (setf (symbol-function new-symbol) (symbol-function symbol))))
222 new-symbol)
224 ;;; FIXME: This declaration should be redundant.
225 (declaim (special *keyword-package*))
227 (defun keywordp (object)
228 #!+sb-doc
229 "Return true if Object is a symbol in the \"KEYWORD\" package."
230 (and (symbolp object)
231 (eq (symbol-package object) *keyword-package*)))
233 ;;;; GENSYM and friends
235 (defvar *gensym-counter* 0
236 #!+sb-doc
237 "counter for generating unique GENSYM symbols")
238 (declaim (type unsigned-byte *gensym-counter*))
240 (defun gensym (&optional (thing "G"))
241 #!+sb-doc
242 "Creates a new uninterned symbol whose name is a prefix string (defaults
243 to \"G\"), followed by a decimal number. Thing, when supplied, will
244 alter the prefix if it is a string, or be used for the decimal number
245 if it is a number, of this symbol. The default value of the number is
246 the current value of *gensym-counter* which is incremented each time
247 it is used."
248 (let ((old *gensym-counter*))
249 (unless (numberp thing)
250 (let ((new (etypecase old
251 (index (1+ old))
252 (unsigned-byte (1+ old)))))
253 (declare (optimize (speed 3) (safety 0)(inhibit-warnings 3)))
254 (setq *gensym-counter* new)))
255 (multiple-value-bind (prefix int)
256 (etypecase thing
257 (simple-string (values thing old))
258 (fixnum (values "G" thing))
259 (string (values (coerce thing 'simple-string) old)))
260 (declare (simple-string prefix))
261 (make-symbol
262 (concatenate 'simple-string prefix
263 (the simple-string
264 (quick-integer-to-string int)))))))
266 (defvar *gentemp-counter* 0)
267 (declaim (type unsigned-byte *gentemp-counter*))
269 (defun gentemp (&optional (prefix "T") (package (sane-package)))
270 #!+sb-doc
271 "Creates a new symbol interned in package PACKAGE with the given PREFIX."
272 (declare (type string prefix))
273 (loop
274 (let ((*print-base* 10)
275 (*print-radix* nil)
276 (*print-pretty* nil)
277 (new-pname (format nil "~A~D" prefix (incf *gentemp-counter*))))
278 (multiple-value-bind (symbol existsp) (find-symbol new-pname package)
279 (declare (ignore symbol))
280 (unless existsp (return (values (intern new-pname package))))))))