/
bindings.cljc
55 lines (42 loc) · 1.67 KB
/
bindings.cljc
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
(ns fr.jeremyschoffen.prose.alpha.document.sci.bindings
(:require
[meander.epsilon :as m :include-macros true]))
;;----------------------------------------------------------------------------------------------------------------------
;; Sci namespace bindings helpers
;;----------------------------------------------------------------------------------------------------------------------
(defn macro?
"True if the var `v` references a macro."
[v]
(some-> v
meta
:macro))
(defn var->binding
"De-reference a var and add the `sci/macro` metadata if needed."
[v]
(-> v
deref
(cond-> (macro? v) (vary-meta assoc :sci/macro true))))
(defn publics->bindings
"Make a sci bindings map from the result of a `ns-publics` result.
The vars are de-referenced and in the case of macros the `sci/macro` metadata is added."
[m]
(m/rewrite m
(m/map-of !name !var)
(m/map-of !name (m/app var->binding !var))))
(defmacro bindings
"Extract bindings using `ns-publics` and using [[publics->bindings]] the result.
The vars returned by `ns-publics` (the map's values) are de-referenced, in the case of macros
the `sci/macro` metadata is added."
[n]
`(publics->bindings (ns-publics '~n)))
(defmacro make-ns-bindings
"Make a namespaces bindings map.
Typically used as `(sci/init {:namespaces (make-ns-bindings ns1 ns2)})`."
[& nss]
(m/rewrite nss
(m/seqable (m/and !ns !ns') ...)
(m/map-of ('quote !ns)
(`bindings !ns'))))
(comment
(macroexpand-1 '(make-ns-bindings fr.jeremyschoffen.textp.alpha.lib.core))
(make-ns-bindings fr.jeremyschoffen.prose.alpha.lib.core))