-
Notifications
You must be signed in to change notification settings - Fork 3
/
computations.lisp
92 lines (76 loc) · 3.18 KB
/
computations.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
82
83
84
85
86
87
88
89
90
91
92
#+xcvb (module (:depends-on ("grain-interface" "grain-registry")))
(in-package :xcvb)
;;(defparameter *computations-inputing-grain*
;; (make-hash-table :test 'equal)
;; "hash mapping each grain to a list of computations that take said grain as input")
(defclass computation ()
((inputs ;; a list of grains
:initarg :inputs
:accessor computation-inputs)
(outputs ;; a list of grains
:initarg :outputs
:accessor computation-outputs)
;; (side-effects) ; for additional files being side-effected
(command ;; SEXP in the command language as used by e.g. Makefile-commands-for-computation
:initarg :command
:accessor computation-command)))
(defgeneric make-computation (env &key))
(defmethod make-computation ((env null) &rest keys &key &allow-other-keys)
(let ((computation (apply #'make-instance 'computation keys)))
(link-computation-outputs computation)
(link-computation-inputs computation)
(push computation *computations*)
computation))
(defun link-computation-outputs (computation)
(loop :for target :in (computation-outputs computation)
:for n :from 0 :do
(when (slot-boundp target 'computation)
(error "Grain ~S already is the output of an existing computation!" target))
(setf (grain-computation target) computation
(grain-computation-index target) n)))
(defun link-computation-inputs (computation)
(loop :for input :in (computation-inputs computation) :do
(pushnew computation (grain-users input))))
(defun make-nop-computation (dependencies &optional targets)
(make-computation ()
:inputs dependencies
:outputs targets
:command nil))
(defun make-phony-grain (&key name dependencies)
(let* ((grain (make-grain 'phony-grain :fullname name)))
(make-nop-computation dependencies (list grain))
grain))
(defmethod print-object ((x computation) stream)
(print-unreadable-object (x stream :type t :identity nil)
(with-slots (inputs outputs command) x
(let ((*print-pretty* t)
(*print-miser-width* 80))
(fresh-line stream)
(format stream " :inputs~% ~S~%" (mapcar #'fullname inputs))
(format stream " :outputs~% ~S~%" (mapcar #'fullname outputs))
(format stream " :command~% ~S" command))))
(fresh-line stream))
(defun computation-target (computation)
(first (computation-outputs computation)))
(defun grain-computation-target (grain)
(let ((computation (grain-computation grain)))
(if computation
(computation-target computation)
grain)))
(defun computation-children (computation)
(mappend #'grain-users (computation-outputs computation)))
(defun map-computations (fun &key from-end)
(dolist (c (if from-end *computations* (reverse *computations*)))
(funcall fun c)))
(defun map-computation-grains (fun &key from-end)
(let ((h (make-hash-table)))
(map-computations
(lambda (c)
(loop :for g :in (append (computation-inputs c) (computation-outputs c))
:unless (gethash g h) :do
(setf (gethash g h) t)
(funcall fun g)))
:from-end from-end)))
(defun list-computation-grains (&key from-end)
(while-collecting (c)
(map-computation-grains #'c :from-end from-end)))