3 ;;;; generalized function names
4 (defvar *valid-fun-names-alist* nil)
6 (defun %define-fun-name-syntax (symbol checker)
7 (let ((found (assoc symbol *valid-fun-names-alist* :test #'eq)))
9 (setf (cdr found) checker)
10 (setq *valid-fun-names-alist*
11 (acons symbol checker *valid-fun-names-alist*)))))
13 (defmacro define-function-name-syntax (symbol (var) &body body)
15 "Define function names of the form of a list headed by SYMBOL to be
16 a legal function name, subject to restrictions imposed by BODY. BODY
17 is evaluated with VAR bound to the form required to check, and should
18 return two values: the first value is a generalized boolean indicating
19 legality, and the second a symbol for use as a BLOCK name or similar
21 (declare (type symbol symbol))
22 (let ((syntax-checker (symbolicate '%check- symbol '-fun-name)))
24 (defun ,syntax-checker (,var) ,@body)
25 ;; FIXME: is it too expensive to go through a runtime call to
26 ;; FDEFINITION each time we want to check a name's syntax?
27 (%define-fun-name-syntax ',symbol ',syntax-checker))))
29 ;;; FIXME: this is a really lame name for something that has two
31 (defun valid-function-name-p (name)
33 "The primary return value indicates whether NAME is a valid function
34 name; if it is, the second return value will be a symbol suitable for
35 use as a BLOCK name in the function in question."
38 (when (symbolp (car name))
39 (let ((syntax-checker (cdr (assoc (car name) *valid-fun-names-alist*
42 (funcall syntax-checker name)))))
43 (symbol (values t name))
46 (define-function-name-syntax setf (name)
49 (destructuring-bind (fun &rest rest) (cdr name)
52 ;; ordinary (SETF FOO) case
53 (symbol (values t fun))
54 ;; reasonable (SETF (QUUX BAZ)) case [but not (SETF (SETF
56 (cons (unless (eq (car fun) 'setf)
57 (valid-function-name-p fun))))))))
60 (defun !function-names-cold-init ()
61 (setf *valid-fun-names-alist* '#.*valid-fun-names-alist*))