Remove get2 variant of get.
[sbcl.git] / src / code / symbol.lisp
index f2f7f35..978074e 100644 (file)
@@ -15,7 +15,7 @@
 
 (in-package "SB!IMPL")
 
-(declaim (maybe-inline get get2 get3 %put getf remprop %putf get-properties keywordp))
+(declaim (maybe-inline get get3 %put getf remprop %putf get-properties keywordp))
 
 (defun symbol-value (symbol)
   #!+sb-doc
   (declare (optimize (safety 1)))
   (symbol-value symbol))
 
+#-sb-xc-host
+(define-compiler-macro symbol-value (&whole form symbol &environment env)
+  (when (sb!xc:constantp symbol env)
+    (let ((name (constant-form-value symbol env)))
+      (when (symbolp name)
+        (check-deprecated-variable name))))
+  form)
+
 (defun boundp (symbol)
   #!+sb-doc
   "Return non-NIL if SYMBOL is bound to a value."
@@ -52,8 +60,7 @@ distinct from the global value. Can also be SETF."
 
 (declaim (inline %makunbound))
 (defun %makunbound (symbol)
-  (%set-symbol-value symbol (%primitive sb!c:make-other-immediate-type
-                                        0 sb!vm:unbound-marker-widetag)))
+  (%set-symbol-value symbol (%primitive sb!c:make-unbound-marker)))
 
 (defun makunbound (symbol)
   #!+sb-doc
@@ -116,20 +123,6 @@ distinct from the global value. Can also be SETF."
   is found, return the associated value, else return DEFAULT."
   (get3 symbol indicator default))
 
-(defun get2 (symbol indicator)
-  (get3 symbol indicator nil))
-#|
-  (let (cdr-pl)
-    (do ((pl (symbol-plist symbol) (cdr cdr-pl)))
-        ((atom pl) nil)
-      (setf cdr-pl (cdr pl))
-      (cond ((atom cdr-pl)
-             (error "~S has an odd number of items in its property list."
-                    symbol))
-            ((eq (car pl) indicator)
-             (return (car cdr-pl)))))))
-|#
-
 (defun get3 (symbol indicator default)
   (let (cdr-pl)
     (do ((pl (symbol-plist symbol) (cdr cdr-pl)))
@@ -274,7 +267,7 @@ distinct from the global value. Can also be SETF."
     (multiple-value-bind (prefix int)
         (etypecase thing
           (simple-string (values thing old))
-          (fixnum (values "G" thing))
+          (unsigned-byte (values "G" thing))
           (string (values (coerce thing 'simple-string) old)))
       (declare (simple-string prefix))
       (make-symbol (%make-symbol-name prefix int)))))
@@ -289,3 +282,54 @@ distinct from the global value. Can also be SETF."
   (loop for name = (%make-symbol-name prefix (incf *gentemp-counter*))
         while (nth-value 1 (find-symbol name package))
         finally (return (values (intern name package)))))
+
+;;; This function is to be called just before a change which would affect the
+;;; symbol value. We don't absolutely have to call this function before such
+;;; changes, since such changes to constants are given as undefined behavior,
+;;; it's nice to do so. To circumvent this you need code like this:
+;;;
+;;;   (defvar foo)
+;;;   (defun set-foo (x) (setq foo x))
+;;;   (defconstant foo 42)
+;;;   (set-foo 13)
+;;;   foo => 13, (constantp 'foo) => t
+;;;
+;;; ...in which case you frankly deserve to lose.
+(defun about-to-modify-symbol-value (symbol action &optional (new-value nil valuep) bind)
+  (declare (symbol symbol))
+  (flet ((describe-action ()
+           (ecase action
+             (set "set SYMBOL-VALUE of ~S")
+             (progv "bind ~S")
+             (compare-and-swap "compare-and-swap SYMBOL-VALUE of ~S")
+             (defconstant "define ~S as a constant")
+             (makunbound "make ~S unbound"))))
+    (let ((kind (info :variable :kind symbol)))
+      (multiple-value-bind (what continue)
+          (cond ((eq :constant kind)
+                 (cond ((eq symbol t)
+                        (values "Veritas aeterna. (can't ~@?)" nil))
+                       ((eq symbol nil)
+                        (values "Nihil ex nihil. (can't ~@?)" nil))
+                       ((keywordp symbol)
+                        (values "Can't ~@?." nil))
+                       (t
+                        (values "Constant modification: attempt to ~@?." t))))
+                ((and bind (eq :global kind))
+                 (values "Can't ~@? (global variable)." nil)))
+        (when what
+          (if continue
+              (cerror "Modify the constant." what (describe-action) symbol)
+              (error what (describe-action) symbol)))
+        (when valuep
+          ;; :VARIABLE :TYPE is in the db only if it is declared, so no need to
+          ;; check.
+          (let ((type (info :variable :type symbol)))
+            (unless (sb!kernel::%%typep new-value type nil)
+              (let ((spec (type-specifier type)))
+                (error 'simple-type-error
+                       :format-control "~@<Cannot ~@? to ~S, not of type ~S.~:@>"
+                       :format-arguments (list (describe-action) symbol new-value spec)
+                       :datum new-value
+                       :expected-type spec))))))))
+  (values))