commit
52bea0b620
26 changed files with 1214 additions and 114 deletions
|
|
@ -110,7 +110,12 @@
|
|||
;; then. Its body resolves fn/map/reduce/cond at EXPANSION time, by which point all
|
||||
;; of 00-syntax has loaded, so using them here is fine.
|
||||
(defmacro ns [nm & clauses]
|
||||
(let [calls (reduce
|
||||
;; ^{:map} metadata on the ns name reads as a (with-meta sym {...}) form, not an
|
||||
;; annotated symbol (jolt-8w2). Real libraries put :author/:doc there
|
||||
;; (clojure.tools.logging), so unwrap to the bare symbol; jolt does not track
|
||||
;; namespace metadata, so the map is dropped.
|
||||
(let [nm (if (and (seq? nm) (= 'with-meta (first nm))) (second nm) nm)
|
||||
calls (reduce
|
||||
(fn [acc clause]
|
||||
(if (seq? clause)
|
||||
(let [head (first clause) args (rest clause)]
|
||||
|
|
@ -341,10 +346,14 @@
|
|||
(defmacro defn [fn-name & body]
|
||||
(let [body (if (and (seq body) (string? (first body))) (rest body) body)
|
||||
body (if (and (seq body) (map? (first body)) (not (symbol? (first body))))
|
||||
(rest body) body)]
|
||||
(rest body) body)
|
||||
;; ^{:map} metadata on the name reads as a (with-meta sym …) form, not an
|
||||
;; annotated symbol (jolt-8w2). def attaches the metadata, but fn needs a
|
||||
;; bare symbol, so unwrap it for the fn name.
|
||||
fn-only-name (if (symbol? fn-name) fn-name (first (rest fn-name)))]
|
||||
;; pass the name through to fn: the compiled fn's janet name carries it,
|
||||
;; so stack traces read app.deep/level3 instead of a gensym (jolt-2o7.1)
|
||||
`(def ~fn-name (fn ~fn-name ~@body))))
|
||||
`(def ~fn-name (fn ~fn-only-name ~@body))))
|
||||
|
||||
;; Jolt doesn't enforce privacy, so defn- is just defn (matching how Clojure's own
|
||||
;; defn- delegates to defn with :private metadata).
|
||||
|
|
|
|||
|
|
@ -519,7 +519,11 @@
|
|||
;; via the host dir primitives. Paths (strings), not File objects. (Lives below
|
||||
;; tree-seq: forward references are analysis errors now — jolt-2o7.3.)
|
||||
(defn file-seq [root]
|
||||
(tree-seq __dir? __list-dir root))
|
||||
(if (__file? root)
|
||||
;; java.io.File tree: walk via the File method surface so leaves are File
|
||||
;; values callers can invoke .isFile/.getName/slurp on (jolt-hjw).
|
||||
(tree-seq (fn [f] (.isDirectory f)) (fn [f] (seq (.listFiles f))) root)
|
||||
(tree-seq __dir? __list-dir root)))
|
||||
|
||||
;; Canonical flatten via tree-seq: the leaves (non-sequential nodes) in order.
|
||||
;; Flattens lists too (sequential?), matching Clojure/CLJS.
|
||||
|
|
|
|||
|
|
@ -21,8 +21,15 @@
|
|||
;; clojure.core fns) so they compile as plain invokes. name/mm are passed quoted;
|
||||
;; the dispatch fn, options, and dispatch value evaluate normally, and the method
|
||||
;; body becomes a compiled (fn …).
|
||||
(defmacro defmulti [name dispatch & opts]
|
||||
`(defmulti-setup (quote ~name) ~dispatch ~@opts))
|
||||
;; Clojure allows (defmulti name docstring? attr-map? dispatch-fn & options);
|
||||
;; drop a leading docstring and/or attr-map so the dispatch fn isn't mistaken for
|
||||
;; one (migratus's multimethods carry docstrings).
|
||||
(defmacro defmulti [name & args]
|
||||
(let [args (if (string? (first args)) (rest args) args)
|
||||
args (if (and (map? (first args)) (not (symbol? (first args)))) (rest args) args)
|
||||
dispatch (first args)
|
||||
opts (rest args)]
|
||||
`(defmulti-setup (quote ~name) ~dispatch ~@opts)))
|
||||
|
||||
(defmacro defmethod [mm dispatch-val & fn-tail]
|
||||
`(defmethod-setup (quote ~mm) ~dispatch-val (fn ~@fn-tail)))
|
||||
|
|
@ -39,11 +46,14 @@
|
|||
(defmacro remove-all-methods [mm]
|
||||
`(remove-all-methods-setup (quote ~mm)))
|
||||
|
||||
;; methods/get-method take the multimethod VALUE (Clojure semantics); the setup
|
||||
;; maps it back to its var via the registry, so a bare multifn ref works from a
|
||||
;; compiled fn in any namespace (jolt multimethod table-visibility fix).
|
||||
(defmacro get-method [mm dval]
|
||||
`(get-method-setup (quote ~mm) ~dval))
|
||||
`(get-method-setup ~mm ~dval))
|
||||
|
||||
(defmacro methods [mm]
|
||||
`(methods-setup (quote ~mm)))
|
||||
`(methods-setup ~mm))
|
||||
|
||||
;; prefers reads the store off the VAR (the multifn value can't carry it) —
|
||||
;; same symbol-passing shape as the other multimethod table ops.
|
||||
|
|
|
|||
|
|
@ -177,3 +177,30 @@
|
|||
(defmethod print-method :jolt/chan [c w]
|
||||
(.write w "#<channel>")
|
||||
nil)
|
||||
|
||||
;; Minimal synchronous agent shim. jolt has no thread pool or STM, so this is
|
||||
;; enough for libraries that hold an agent but don't depend on asynchronous
|
||||
;; dispatch (e.g. clojure.tools.logging's *logging-agent*, which only sends from
|
||||
;; within a transaction — never the case here, so it always logs directly). An
|
||||
;; agent is an atom; send/send-off apply the action immediately. NOT concurrent.
|
||||
(defn agent
|
||||
"Creates an agent (an atom on jolt — synchronous, no async dispatch)."
|
||||
[state & _opts]
|
||||
(atom state))
|
||||
|
||||
(defn send-off
|
||||
"Apply (action state & args) to the agent's state immediately; return the agent."
|
||||
[a f & args]
|
||||
(apply swap! a f args)
|
||||
a)
|
||||
|
||||
(defn send
|
||||
"Like send-off on jolt (no separate thread pool)."
|
||||
[a f & args]
|
||||
(apply swap! a f args)
|
||||
a)
|
||||
|
||||
(defn agent-error
|
||||
"jolt agents never enter an error state."
|
||||
[_a]
|
||||
nil)
|
||||
|
|
|
|||
|
|
@ -182,9 +182,16 @@
|
|||
(when (< (count items) 3)
|
||||
(uncompilable "def with no init"))
|
||||
(let [nm (form-sym-name name-sym)
|
||||
cur (compile-ns ctx)]
|
||||
cur (compile-ns ctx)
|
||||
;; (def name docstring value): docstring is form 2, value form 3.
|
||||
;; Matches the interpreter; without this the docstring was taken
|
||||
;; as the value and the real init dropped (jolt-6ym).
|
||||
has-doc (and (> (count items) 3) (string? (nth items 2)))
|
||||
val-form (nth items (if has-doc 3 2))
|
||||
base-meta (or (form-sym-meta name-sym) {})
|
||||
node-meta (if has-doc (assoc base-meta :doc (nth items 2)) base-meta)]
|
||||
(host-intern! ctx cur nm)
|
||||
(def-node cur nm (analyze ctx (nth items 2) env) (form-sym-meta name-sym))))
|
||||
(def-node cur nm (analyze ctx val-form env) node-meta)))
|
||||
"let*" (let [bvec (vec (form-vec-items (nth items 1)))
|
||||
r (analyze-bindings ctx bvec env)]
|
||||
(let-node (first r) (analyze-seq ctx (drop 2 items) (second r))))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue