-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathgrain-registry.lisp
38 lines (30 loc) · 1.51 KB
/
grain-registry.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
;;;;; Registry mapping names to grains, particularly BUILD files.
#+xcvb (module (:depends-on ("grain-interface" "specials")))
(in-package :xcvb)
;;; The registry itself
;; TODO: have distinct registries for builds and grains?
(defun registered-grain (name)
(gethash name *grains*))
(defun (setf registered-grain) (grain name)
(let ((previous (registered-grain name)))
(when (and previous (not (eq grain previous)))
(error "There already exists a grain named ~A: ~S"
name (registered-grain name))))
(setf (gethash name *grains*) grain))
(defun call-with-grain-registration (fullname function &rest args)
(let ((previous (registered-grain fullname)))
(or previous (register-computed-grain fullname function args))))
(defun register-computed-grain (fullname function &optional args)
(let* ((grain (apply function args))
(gname (fullname grain)))
;; This happens because graph-for's main method is called with (:lisp ...)
;; and gets a grain with a different fullname. Hum. This is a sign
;; that we're conflating several kinds of grains in our architecture.
(unless (or (equal gname fullname)
(equal gname `(:lisp ,fullname))
(equal gname `(:build ,fullname)))
(log-format 7 "Registered grain for name ~S has fullname ~S" fullname gname))
(setf (registered-grain fullname) grain)
grain))
(defun make-grain (class &rest args &key fullname &allow-other-keys)
(apply #'call-with-grain-registration fullname #'make-instance class args))