-
Notifications
You must be signed in to change notification settings - Fork 3
/
dependencies-interpreter.lisp
157 lines (128 loc) · 6.07 KB
/
dependencies-interpreter.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#+xcvb (module (:depends-on ("normalize-dependency" "traversal")))
(in-package :xcvb)
;;; BUILD-COMMAND-FOR
(defgeneric build-command-for (env name))
(defgeneric build-command-for-lisp (env name))
(defgeneric build-command-for-fasl (env name))
(defgeneric build-command-for-cfasl (env name))
(defgeneric build-command-for-lisp-object (env name)) ;; XXX or should have link-commands instead ?
(defgeneric build-command-for-asdf (env name))
(defgeneric build-command-for-require (env name))
(defgeneric build-command-for-static-library (env name))
(defgeneric build-command-for-dynamic-library (env name))
(defgeneric build-command-for-source (env name &key in))
(defgeneric build-command-for-build (env name))
(defgeneric build-command-for-compile-build (env name))
(defgeneric build-command-for-build-named (env name))
(defgeneric build-command-for-when (env expression &rest dependencies))
(defgeneric build-command-for-cond (env &rest cond-expressions))
(defgeneric simple-build-command-for-grain (env command grain))
(define-simple-dispatcher build-command-for #'build-command-for-atom :generic t)
(defmethod build-command-for (env spec)
(build-command-for-dispatcher env (tweak-dependency env spec)))
(defun build-command-for* (env specs)
(dolist (spec specs)
(build-command-for env spec)))
(defun build-command-for-atom (env spec)
(declare (ignore env))
(error "Cannot produce a build command for the invalid dependency ~S" spec))
(define-build-command-for :lisp (env name)
(simple-build-command-for
env `(:load-file ,name) `(:lisp ,name)))
(define-build-command-for :fasl (env name)
(simple-build-command-for
env `(:load-file (:fasl ,name)) `(:fasl ,name)))
(define-build-command-for :cfasl (env name)
(simple-build-command-for
env `(:load-file (:cfasl ,name)) `(:cfasl ,name)))
(define-build-command-for :lisp-object (env name)
(simple-build-command-for
env `(:load-file (:lisp-object ,name)) `(:lisp-object ,name)))
(define-build-command-for :dynamic-library (env name)
(simple-build-command-for
env `(:load-file (:dynamic-library ,name)) `(:dynamic-library ,name)))
(define-build-command-for :static-library (env name)
(simple-build-command-for
env `(:load-file (:static-library ,name)) `(:static-library ,name)))
(define-build-command-for :asdf (env name)
(build-command-for env `(:build "/asdf"))
(simple-build-command-for env `(:load-asdf ,name) `(:asdf ,name)))
(define-build-command-for :require (env name)
(simple-build-command-for env `(:require ,name) `(:require ,name)))
(defun simple-build-command-for (env command fullname)
(call-with-dependency-grain
env fullname
(lambda (grain) (simple-build-command-for-grain env command grain))))
(defmethod simple-build-command-for-grain (env command grain)
(with-dependency-loading (env grain)
(build-commands-for-build-dependencies env grain)
(build-commands-for-load-dependencies env grain)
(issue-build-command env command)))
(define-build-command-for :source (env name &key in)
;; Suffices to know data file exists. No need to issue load command.
(call-with-dependency-grain
env `(:source ,name :in ,in)
(lambda (grain)
(with-dependency-loading (env grain)
(values)))))
(defun call-with-dependency-grain (environment dep fun)
(let* ((grain (graph-for environment dep)))
(with-dependency (:type type) dep
(unless (typep grain type)
(error "Expected a grain of type ~S for ~S, instead got ~S"
type dep grain))
(funcall fun grain))))
(define-build-command-for :build (env name)
(let ((build (registered-build name :ensure-build t)))
(finalize-grain build)
(if (target-ecl-p)
(build-command-for env `(:dynamic-library ,name))
(with-dependency-loading (env build)
(build-commands-for-load-dependencies env build)))))
(define-build-command-for :compile-build (env name)
(let ((build (registered-build name :ensure-build t)))
(finalize-grain build)
(with-dependency-loading (env build)
(build-commands-for-build-dependencies env build)
(build-commands-for-compile-dependencies env build))))
(defun build-commands-for-load-dependencies (env grain)
(build-command-for* env (load-dependencies grain)))
(defun build-commands-for-compile-dependencies (env grain)
(build-command-for* env (compile-dependencies grain)))
(defun build-commands-for-cload-dependencies (env grain)
(build-command-for* env (cload-dependencies grain)))
(defun build-commands-for-build-dependencies (env grain)
(build-command-for* env (build-dependencies grain)))
(define-build-command-for :when (env expression &rest dependencies)
(when (evaluate-condition env expression)
(build-command-for* env dependencies)))
(define-build-command-for :cond (env &rest cond-expressions)
(loop :for cond-expression :in cond-expressions
:when (evaluate-condition env (car cond-expression))
:do (return (build-command-for* env (cdr cond-expression)))))
(define-simple-dispatcher evaluate-condition #'evaluate-condition-atom)
(defun evaluate-condition (env expression)
(evaluate-condition-dispatcher env expression))
(defun evaluate-condition-atom (env atom)
(declare (ignore env))
(if (typep atom 'boolean)
atom
(error "Invalid condition ~S" atom)))
(define-evaluate-condition :featurep (env feature-expression)
(evaluate-featurep env feature-expression))
(defun evaluate-featurep (env feature-expression)
(evaluate-featurep-dispatcher env feature-expression))
(define-simple-dispatcher evaluate-featurep #'evaluate-featurep-atom)
(defun evaluate-featurep-atom (env atom)
(declare (ignore env))
(unless (keywordp atom)
(error "Invalid feature ~S" atom))
(target-feature-p atom))
(define-evaluate-featurep :and (env &rest feature-expressions)
(loop :for feature-expression :in feature-expressions
:always (evaluate-featurep env feature-expression)))
(define-evaluate-featurep :or (env &rest feature-expressions)
(loop :for feature-expression :in feature-expressions
:thereis (evaluate-featurep env feature-expression)))
(define-evaluate-featurep :not (env feature-expression)
(not (evaluate-featurep env feature-expression)))