1 ;;;; pretty-printing of backquote expansions
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
12 (in-package "SB!IMPL")
14 (defun backq-unparse-expr (form splicing
)
19 `((backq-comma-at ,form
)))
21 `((backq-comma-dot ,form
)))
24 (defun backq-unparse (form &optional splicing
)
26 "Given a lisp form containing the magic functions BACKQ-LIST, BACKQ-LIST*,
27 BACKQ-APPEND, etc. produced by the backquote reader macro, will return a
28 corresponding backquote input form. In this form, `,' `,@' and `,.' are
29 represented by lists whose cars are BACKQ-COMMA, BACKQ-COMMA-AT, and
30 BACKQ-COMMA-DOT respectively, and whose cadrs are the form after the comma.
31 SPLICING indicates whether a comma-escape return should be modified for
32 splicing with other forms: a value of T or :NCONC meaning that an extra
33 level of parentheses should be added."
36 (backq-unparse-expr form splicing
))
37 ((not (null (cdr (last form
))))
38 ;; FIXME: this probably throws a recursive error
39 (bug "found illegal dotted backquote form: ~S" form
))
43 (mapcar #'backq-unparse
(cdr form
)))
45 (do ((tail (cdr form
) (cdr tail
))
48 (nconc (nreverse accum
)
49 (backq-unparse (car tail
) t
)))
50 (push (backq-unparse (car tail
)) accum
)))
53 (mapcar (lambda (el) (backq-unparse el t
))
57 (mapcar (lambda (el) (backq-unparse el
:nconc
))
60 (cons (backq-unparse (cadr form
) nil
)
61 (backq-unparse (caddr form
) t
)))
63 (coerce (backq-unparse (cadr form
)) 'vector
))
66 ((atom (cadr form
)) (cadr form
))
67 ((and (consp (cadr form
))
68 (member (caadr form
) *backq-tokens
*))
69 (backq-unparse-expr form splicing
))
70 (t (cons (backq-unparse `(quote ,(caadr form
)))
71 (backq-unparse `(quote ,(cdadr form
)))))))
73 (backq-unparse-expr form splicing
))))))
75 (defun pprint-backquote (stream form
&rest noise
)
76 (declare (ignore noise
))
77 (write-char #\
` stream
)
78 (write (backq-unparse form
) :stream stream
))
80 (defun pprint-backq-comma (stream form
&rest noise
)
81 (declare (ignore noise
))
84 (write-char #\
, stream
))
86 (write-string ",@" stream
))
88 (write-string ",." stream
)))
89 ;; Ha! an example of where the per-process specials for stream
90 ;; attributes rather than per-stream actually makes life easier.
91 ;; Since all of the attributes are shared in the dynamic state, we
92 ;; can do... -- CSR, 2003-09-30
94 ;; [...] above referred to the trick of printing to a string stream,
95 ;; and then simply printing the resulting sequence to the pretty
96 ;; stream, possibly with a space prepended. However, this doesn't
97 ;; work for pretty streams which need to do margin calculations. Oh
98 ;; well. It was good while it lasted. -- CSR, 2003-12-15
99 (let ((output (with-output-to-string (s)
100 (write (cadr form
) :stream s
))))
101 (unless (= (length output
) 0)
102 (when (and (eql (car form
) 'backq-comma
)
103 (or (char= (char output
0) #\.
)
104 (char= (char output
0) #\
@)))
105 (write-char #\Space stream
))
106 (write (cadr form
) :stream stream
))))
108 ;;; This is called by !PPRINT-COLD-INIT, fairly late, because
109 ;;; SET-PPRINT-DISPATCH doesn't work until the compiler works.
111 ;;; FIXME: It might be cleaner to just make these be toplevel forms and
112 ;;; enforce the delay by putting this file late in the build sequence.
113 (defun !backq-pp-cold-init
()
114 (set-pprint-dispatch '(cons (eql backq-list
)) #'pprint-backquote
)
115 (set-pprint-dispatch '(cons (eql backq-list
*)) #'pprint-backquote
)
116 (set-pprint-dispatch '(cons (eql backq-append
)) #'pprint-backquote
)
117 (set-pprint-dispatch '(cons (eql backq-nconc
)) #'pprint-backquote
)
118 (set-pprint-dispatch '(cons (eql backq-cons
)) #'pprint-backquote
)
119 (set-pprint-dispatch '(cons (eql backq-vector
)) #'pprint-backquote
)
121 (set-pprint-dispatch '(cons (eql backq-comma
)) #'pprint-backq-comma
)
122 (set-pprint-dispatch '(cons (eql backq-comma-at
)) #'pprint-backq-comma
)
123 (set-pprint-dispatch '(cons (eql backq-comma-dot
)) #'pprint-backq-comma
))