-
Notifications
You must be signed in to change notification settings - Fork 7
/
clojure-printer.lisp
52 lines (44 loc) · 1.57 KB
/
clojure-printer.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
(in-package #:cloture)
(in-readtable clojure-shortcut)
(defun self-evaluating? (x)
(typep x '(or keyword number string)))
(defun maybe-quote (x)
(if (self-evaluating? x) x
`(#_quote ,x)))
(defun pp-seq (stream seq)
(pprint-logical-block (stream nil :prefix "[")
(iterate (for x in-fset-seq seq)
(pprint-pop)
(write-char #\Space stream)
(pprint-newline :linear stream)
(write (maybe-quote x) :stream stream))
(format stream " ]")))
(defun pp-map (stream map)
(pprint-logical-block (stream nil :prefix "{")
(iterate (for (x y) in-map map)
(pprint-pop)
(write-char #\Space stream)
(pprint-newline :linear stream)
;; TODO quote if necessary
(write (maybe-quote x) :stream stream)
(write-char #\Space stream)
(write (maybe-quote y) :stream stream))
(format stream "}")))
(defun pp-quote (stream list)
(write-char #\' stream)
(write (only-elt (rest list)) :stream stream))
(defparameter *clojure-pprint-dispatch*
(lret ((table (copy-pprint-dispatch nil)))
(set-pprint-dispatch 'fset:seq #'pp-seq 0 table)
(set-pprint-dispatch 'fset:map #'pp-map 0 table)
(set-pprint-dispatch '(cons (eql #_quote)) #'pp-quote 0 table)
(set-pprint-dispatch '(cons (eql quote)) nil 0 table)
(set-pprint-dispatch '(cons (eql function)) nil 0 table)))
(defun call/clojure-printer (fn)
(let ((*print-pretty* t)
(*print-pprint-dispatch*
*clojure-pprint-dispatch*))
(funcall fn)))
(defmacro with-clojure-printer ((&key) &body body)
(with-thunk (body)
`(call/clojure-printer ,body)))