1 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; This software is derived from the CMU CL system, which was
5 ;;;; written at Carnegie Mellon University and released into the
6 ;;;; public domain. The software is in the public domain and is
7 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
8 ;;;; files for more information.
12 (/show0
"parse-lambda-list.lisp 12")
14 ;;; Break something like a lambda list (but not necessarily actually a
15 ;;; lambda list, e.g. the representation of argument types which is
16 ;;; used within an FTYPE specification) into its component parts. We
17 ;;; return twelve values:
18 ;;; 1. a list of the required args;
19 ;;; 2. a list of the &OPTIONAL arg specs;
20 ;;; 3. true if a &REST arg was specified;
22 ;;; 5. true if &KEY args are present;
23 ;;; 6. a list of the &KEY arg specs;
24 ;;; 7. true if &ALLOW-OTHER-KEYS was specified.;
25 ;;; 8. true if any &AUX is present (new in SBCL vs. CMU CL);
26 ;;; 9. a list of the &AUX specifiers;
27 ;;; 10. true if a &MORE arg was specified;
28 ;;; 11. the &MORE context var;
29 ;;; 12. the &MORE count var.
31 ;;; The top level lambda list syntax is checked for validity, but the
32 ;;; arg specifiers are just passed through untouched. If something is
33 ;;; wrong, we use COMPILER-ERROR, aborting compilation to the last
35 (declaim (ftype (function (list)
36 (values list list boolean t boolean list boolean
37 boolean list boolean t t
))
38 parse-lambda-list-like-thing
40 (defun parse-lambda-list-like-thing (list)
54 (declare (type (member :allow-other-keys
:aux
56 :more-context
:more-count
62 (if (and (symbolp arg
)
63 (let ((name (symbol-name arg
)))
64 (and (plusp (length name
))
65 (char= (char name
0) #\
&))))
68 (unless (eq state
:required
)
69 (compiler-error "misplaced &OPTIONAL in lambda list: ~S"
71 (setq state
:optional
))
73 (unless (member state
'(:required
:optional
))
74 (compiler-error "misplaced &REST in lambda list: ~S" list
))
77 (unless (member state
'(:required
:optional
))
78 (compiler-error "misplaced &MORE in lambda list: ~S" list
))
83 '(:required
:optional
:post-rest
:post-more
))
84 (compiler-error "misplaced &KEY in lambda list: ~S" list
))
88 (unless (eq state
':key
)
89 (compiler-error "misplaced &ALLOW-OTHER-KEYS in ~
93 state
:allow-other-keys
))
95 (when (member state
'(:rest
:more-context
:more-count
))
96 (compiler-error "misplaced &AUX in lambda list: ~S" list
))
99 ;; FIXME: I don't think ANSI says this is an error. (It
100 ;; should certainly be good for a STYLE-WARNING,
103 (compiler-error "unknown &KEYWORD in lambda list: ~S" arg
)))
105 (:required
(required arg
))
106 (:optional
(optional arg
))
112 (setq more-context arg
120 (compiler-error "found garbage in lambda list when expecting ~
123 (when (eq state
:rest
)
124 (compiler-error "&REST without rest variable"))
126 (values (required) (optional) restp rest keyp
(keys) allowp auxp
(aux)
127 morep more-context more-count
))))
129 ;;; like PARSE-LAMBDA-LIST-LIKE-THING, except our LAMBDA-LIST argument
130 ;;; really *is* a lambda list, not just a "lambda-list-like thing", so
131 ;;; can barf on things which're illegal as arguments in lambda lists
132 ;;; even if they could conceivably be legal in not-quite-a-lambda-list
134 (defun parse-lambda-list (lambda-list)
136 ;; Classify parameters without checking their validity individually.
137 (multiple-value-bind (required optional restp rest keyp keys allowp auxp aux
138 morep more-context more-count
)
139 (parse-lambda-list-like-thing lambda-list
)
141 ;; Check validity of parameters.
142 (flet ((need-symbol (x why
)
144 (compiler-error "~A is not a symbol: ~S" why x
))))
146 (need-symbol i
"Required argument"))
151 (destructuring-bind (var &optional init-form supplied-p
) i
152 (declare (ignore init-form supplied-p
))
153 (need-symbol var
"&OPTIONAL parameter name")))
155 (compiler-error "&OPTIONAL parameter is not a symbol or cons: ~S"
158 (need-symbol rest
"&REST argument"))
164 (destructuring-bind (var-or-kv &optional init-form supplied-p
) i
165 (declare (ignore init-form supplied-p
))
166 (if (consp var-or-kv
)
167 (destructuring-bind (keyword-name var
) var-or-kv
168 (declare (ignore keyword-name
))
169 (need-symbol var
"&KEY parameter name"))
170 (need-symbol var-or-kv
"&KEY parameter name"))))
172 (compiler-error "&KEY parameter is not a symbol or cons: ~S"
176 (values required optional restp rest keyp keys allowp auxp aux
177 morep more-context more-count
)))
179 (/show0
"parse-lambda-list.lisp end of file")