Utility predicates for packing: UNBOUNDED-SC-P and UNBOUNDED-TN-P
[sbcl.git] / src / code / pp-backq.lisp
index 2552673..fd1fb13 100644 (file)
    ((atom form)
     (backq-unparse-expr form splicing))
    ((not (null (cdr (last form))))
-    ;; FIXME: Shouldn't this be an ERROR?
-    "### illegal dotted backquote form ###")
+    ;; FIXME: this probably throws a recursive error
+    (bug "found illegal dotted backquote form: ~S" form))
    (t
     (case (car form)
       (backq-list
        (mapcar #'backq-unparse (cdr form)))
       (backq-list*
        (do ((tail (cdr form) (cdr tail))
-           (accum nil))
-          ((null (cdr tail))
-           (nconc (nreverse accum)
-                  (backq-unparse (car tail) t)))
-        (push (backq-unparse (car tail)) accum)))
+            (accum nil))
+           ((null (cdr tail))
+            (nconc (nreverse accum)
+                   (backq-unparse (car tail) t)))
+         (push (backq-unparse (car tail)) accum)))
       (backq-append
-       (mapcan (lambda (el) (backq-unparse el t))
-              (cdr form)))
+       (apply #'append
+              (mapcar (lambda (el) (backq-unparse el t))
+                      (cdr form))))
       (backq-nconc
-       (mapcan (lambda (el) (backq-unparse el :nconc))
-              (cdr form)))
+       (apply #'append
+              (mapcar (lambda (el) (backq-unparse el :nconc))
+                      (cdr form))))
       (backq-cons
        (cons (backq-unparse (cadr form) nil)
-            (backq-unparse (caddr form) t)))
+             (backq-unparse (caddr form) t)))
       (backq-vector
        (coerce (backq-unparse (cadr form)) 'vector))
       (quote
-       (cadr form))
+       (cond
+         ((atom (cadr form)) (cadr form))
+         ((and (consp (cadr form))
+               (member (caadr form) *backq-tokens*))
+          (backq-unparse-expr form splicing))
+         (t (cons (backq-unparse `(quote ,(caadr form)))
+                  (backq-unparse `(quote ,(cdadr form)))))))
       (t
        (backq-unparse-expr form splicing))))))
 
     (backq-comma
      (write-char #\, stream))
     (backq-comma-at
-     (princ ",@" stream))
+     (write-string ",@" stream))
     (backq-comma-dot
-     (princ ",." stream)))
+     (write-string ",." stream)))
+  ;; Ha!  an example of where the per-process specials for stream
+  ;; attributes rather than per-stream actually makes life easier.
+  ;; Since all of the attributes are shared in the dynamic state, we
+  ;; can do... -- CSR, 2003-09-30
+  ;;
+  ;; [...] above referred to the trick of printing to a string stream,
+  ;; and then simply printing the resulting sequence to the pretty
+  ;; stream, possibly with a space prepended.  However, this doesn't
+  ;; work for pretty streams which need to do margin calculations.  Oh
+  ;; well.  It was good while it lasted.  -- CSR, 2003-12-15
+  ;;
+  ;; This is an evil hack. If we print to a string and then print again,
+  ;; the circularity detection logic behaves as though it's already
+  ;; printed that data... and it has, to a string stream that we send
+  ;; to the bitbucket in the sky.  -- PK, 2013-03-30
+  (when (eql (car form) 'backq-comma)
+    (let ((output (with-output-to-string (s)
+                    ;; Patching evil with more evil.  The next step is
+                    ;; likely to stop the madness and unconditionally
+                    ;; insert a space.
+                    (let (*circularity-hash-table*
+                          *circularity-counter*)
+                      (write (cadr form) :stream s)))))
+      (when (and (plusp (length output))
+                 (or (char= (char output 0) #\.)
+                     (char= (char output 0) #\@)))
+        (write-char #\Space stream))))
   (write (cadr form) :stream stream))
 
 ;;; This is called by !PPRINT-COLD-INIT, fairly late, because