Combine macro and function pprint dispatch entry

The macro printer already has a fallback to pprint-fun-call
so just let it do that on anything not satisfying MACRO-FUNCTION.
This commit is contained in:
Douglas Katzman 2022-09-07 11:08:53 -04:00
parent c262bc7d00
commit dac8bd608c
2 changed files with 22 additions and 19 deletions

View file

@ -1352,21 +1352,24 @@ line break."
;;; by looking for &BODY. A dotted list is indented as it it had &BODY.
;;; ANSI says that a dotted tail is like &REST, but the pretty-printer
;;; can do whatever it likes anyway. I happen to think this makes sense.
(defun macro-indentation (name)
(defun macro-indentation (macro-function)
(do ((n 0)
(list (%fun-lambda-list (macro-function name)) (cdr list)))
(list (%fun-lambda-list macro-function) (cdr list)))
((or (atom list) (eq (car list) '&body))
(if (null list) nil n))
(unless (eq (car list) '&optional)
(incf n))))
;;; Pretty-Print macros by looking where &BODY appears in a macro's
;;; lambda-list.
(defun pprint-macro-call (stream list &rest noise)
;;; lambda-list. If LIST is not macro invocation, or a macro without a &BODY arg
;;; then print it as a function.
(defun pprint-call-form (stream list &rest noise)
(declare (ignore noise))
(let ((indentation (and (car list) (macro-indentation (car list)))))
(let ((indentation (binding* ((car (car list) :exit-if-null)
(mf (macro-function car) :exit-if-null))
(macro-indentation mf))))
(unless indentation
(return-from pprint-macro-call
(return-from pprint-call-form
(pprint-fun-call stream list)))
(pprint-logical-block (stream list :prefix "(" :suffix ")")
(output-object (pprint-pop) stream)
@ -1528,13 +1531,10 @@ line break."
;; fewer type tests when dispatching.
(initial-entry (and array (not (or string bit-vector)))
pprint-array -1)
;; MACRO-FUNCTION must have effectively higher priority than FBOUNDP.
;; The implementation happens to check identical priorities in the order added,
;; but that's unspecified behavior. Both must be _strictly_ lower than the
;; default cons entries though.
(initial-entry (cons (and symbol (satisfies macro-function)))
pprint-macro-call -1)
(initial-entry (cons (and symbol (satisfies fboundp))) pprint-fun-call -1)
;; but that's unspecified behavior. (SATISFIES FBOUNDP) must be _strictly_
;; lower than the default cons entries though.
(initial-entry (cons (and symbol (satisfies fboundp))) pprint-call-form -1)
(initial-entry (cons symbol) pprint-data-list -2)
(initial-entry cons pprint-fill -2 #'consp)
(initial-entry sb-impl::comma pprint-unquoting-comma -3 #'comma-p)))

View file

@ -424,6 +424,9 @@
;; force MACDADDY to be a closure over X.
(let ((x 3)) (defmacro macdaddy (a b &body z) a b z `(who-cares ,x)) (incf x))
(defun indentation-of (name)
(sb-pretty::macro-indentation (macro-function name)))
(with-test (:name :closure-macro-arglist)
;; assert correct test setup - MACDADDY is a closure if compiling,
;; or a funcallable-instance if not
@ -433,7 +436,7 @@
;; MACRO-INDENTATION used %simple-fun-arglist instead of %fun-arglist.
;; Depending on your luck it would either not return the right answer,
;; or crash, depending on what lay at 4 words past the function address.
(assert (= (sb-pretty::macro-indentation 'macdaddy) 2)))
(assert (= (indentation-of 'macdaddy) 2)))
(defmacro try1 (a b &body fool) `(baz ,a ,b ,fool))
(defmacro try2 (a b &optional &body fool) `(baz ,a ,b ,fool))
@ -442,12 +445,12 @@
(defmacro try5 (a b &optional . fool) `(baz ,a ,b ,fool))
(defmacro try6 (a b &optional c . fool) `(baz ,a ,b ,c ,fool))
(with-test (:name :macro-indentation)
(assert (= (sb-pretty::macro-indentation 'try1) 2))
(assert (= (sb-pretty::macro-indentation 'try2) 2))
(assert (= (sb-pretty::macro-indentation 'try3) 3))
(assert (= (sb-pretty::macro-indentation 'try4) 2))
(assert (= (sb-pretty::macro-indentation 'try5) 2))
(assert (= (sb-pretty::macro-indentation 'try6) 3)))
(assert (= (indentation-of 'try1) 2))
(assert (= (indentation-of 'try2) 2))
(assert (= (indentation-of 'try3) 3))
(assert (= (indentation-of 'try4) 2))
(assert (= (indentation-of 'try5) 2))
(assert (= (indentation-of 'try6) 3)))
(defclass ship () ())
(let ((ppd (copy-pprint-dispatch)))