This repository was archived by the owner on May 26, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathunparse.lisp
81 lines (72 loc) · 2.74 KB
/
unparse.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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
(in-package #:sandalphon.lambda-list)
(defmethod print-object ((o lambda-list) stream)
(print-unreadable-object (o stream :type t)
(write (lambda-list-unparse o) :stream stream)))
(defgeneric lambda-list-unparse (lambda-list)
(:method ((lambda-list lambda-list))
(loop for clause in (lambda-list-clauses lambda-list)
appending (clause-unparse clause))))
(defgeneric clause-unparse (clause))
(defgeneric multiple-clause-unparse-spec (clause spec))
;;; standard unparsers
(defmethod clause-unparse ((clause singleton-clause))
(if (clause-spec clause)
(list (first (clause-keywords clause)) (clause-spec clause))
nil))
(defmethod clause-unparse ((clause multiple-clause))
(flet ((unparse (spec)
(multiple-clause-unparse-spec clause spec)))
(cond ((null (multiple-clause-specs clause)) nil)
((member nil (clause-keywords clause))
(mapcar #'unparse (multiple-clause-specs clause)))
(t (list* (first (clause-keywords clause))
(mapcar #'unparse
(multiple-clause-specs clause)))))))
(defmethod multiple-clause-unparse-spec ((clause regular-clause) spec)
spec)
(defmethod multiple-clause-unparse-spec
((clause specialized-regular-clause) spec)
spec)
(defmethod multiple-clause-unparse-spec ((clause optional-clause) spec)
(if (third spec)
spec
;; always display the default; we could check the default-default
;; but that's work
(list (first spec) (second spec))))
(defmethod clause-unparse ((clause key-clause))
(let ((main (call-next-method)))
(if (key-clause-aok-p clause)
(append main '(&allow-other-keys))
main)))
(defmethod multiple-clause-unparse-spec ((clause key-clause) spec)
(let ((first (if (string= (symbol-name (first (first spec)))
(symbol-name (second (first spec))))
(second (first spec))
(first spec))))
(if (third spec)
(list* first (rest spec))
;; ditto &optional
(list first (second spec)))))
(defmethod multiple-clause-unparse-spec ((clause aux-clause) spec)
spec)
(defun maybe-unparse (llist)
(if (symbolp llist)
llist
(lambda-list-unparse llist)))
(defmethod multiple-clause-unparse-spec
((clause destructuring-regular-clause) spec)
(maybe-unparse spec))
(defmethod multiple-clause-unparse-spec
((clause destructuring-optional-clause) spec)
(cond ((third spec) (list* (maybe-unparse (first spec)) (rest spec)))
(t (list (maybe-unparse (first spec)) (second spec)))))
(defmethod multiple-clause-unparse-spec
((clause destructuring-key-clause) spec)
(destructuring-bind ((key var) default -p) spec
(let ((first (if (and (symbolp var)
(string= (symbol-name key) (symbol-name var)))
var
(list key (maybe-unparse var)))))
(if -p
(list first default -p)
(list first default)))))