core: move defn and defn- to the syntax tier
defn drops an optional leading docstring/attr-map then emits (def name (fn* ...)). Single- and multi-arity both reduce to (fn* ~@body) so no arity branching is needed. map? is true for symbol forms in Jolt, so the attr-map strip is guarded with symbol?. defn- delegates to defn (privacy isn't enforced, as in Clojure's own defn-). Placed before fresh-sym, which is itself a defn- now. All five fundamental macros (fn/let/loop/defn/defn-) are now in the overlay. conformance 228x3, fixpoint, clojure-test-suite 3930, full suite green.
This commit is contained in:
parent
4eb2cf5c46
commit
08c796c145
2 changed files with 16 additions and 37 deletions
|
|
@ -80,6 +80,21 @@
|
|||
(defmacro loop [bindings & body]
|
||||
`(loop* ~bindings ~@body))
|
||||
|
||||
;; defn: drop an optional leading docstring and attr-map, then (def name (fn* ...)).
|
||||
;; Both single- and multi-arity reduce to (fn* ~@body) — fn* takes either a params
|
||||
;; vector + body or a sequence of ([params] body) clauses, so no arity branching is
|
||||
;; needed. (map? is true for symbol forms too, so guard the attr-map with symbol?.)
|
||||
;; Defined before fresh-sym below, which is a defn-.
|
||||
(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)]
|
||||
`(def ~fn-name (fn* ~@body))))
|
||||
|
||||
;; Jolt doesn't enforce privacy, so defn- is just defn (matching how Clojure's own
|
||||
;; defn- delegates to defn with :private metadata).
|
||||
(defmacro defn- [fn-name & body] `(defn ~fn-name ~@body))
|
||||
|
||||
;; A fresh jolt symbol inside a macro body (a bare (gensym) returns a Janet symbol
|
||||
;; the destructurer rejects). This defn compiles fine: by the time a tier triggers
|
||||
;; the analyzer build the kernel is in place (the build is gated until then).
|
||||
|
|
|
|||
|
|
@ -2093,40 +2093,6 @@
|
|||
|
||||
(defn core-intern [ns-name sym-name val] val)
|
||||
|
||||
(defn- defn->def
|
||||
"Shared expansion for defn/defn-: (name doc-string? attr-map? params body...)
|
||||
or (name doc-string? attr-map? ([params] body)... attr-map?) -> (def name (fn* ...))."
|
||||
[fn-name rest]
|
||||
(var items (array/slice rest))
|
||||
# strip optional docstring
|
||||
(when (and (> (length items) 0) (string? (first items)))
|
||||
(set items (array/slice items 1)))
|
||||
# strip optional attr-map (a map literal, i.e. struct/table that isn't a symbol)
|
||||
(when (and (> (length items) 0)
|
||||
(let [x (first items)]
|
||||
(and (or (struct? x) (table? x))
|
||||
(not (and (struct? x) (= :symbol (get x :jolt/type)))))))
|
||||
(set items (array/slice items 1)))
|
||||
(def fn-form @[{:jolt/type :symbol :ns nil :name "fn*"}])
|
||||
(if (and (> (length items) 0) (array? (first items)) (indexed? (first (first items))))
|
||||
# multi-arity: each remaining item is an ([params] body...) clause
|
||||
(each pair items (array/push fn-form pair))
|
||||
# single-arity: items = [params-vector body...]
|
||||
(do
|
||||
(array/push fn-form (first items))
|
||||
(each b (tuple/slice items 1) (array/push fn-form b))))
|
||||
@[{:jolt/type :symbol :ns nil :name "def"} fn-name fn-form])
|
||||
|
||||
(defn core-defn
|
||||
"Macro: (defn name doc-string? attr-map? [args] body...) (or multi-arity)
|
||||
-> (def name (fn* ...))"
|
||||
[fn-name & rest]
|
||||
(defn->def fn-name rest))
|
||||
|
||||
# defn- — same as defn (private not enforced in Jolt)
|
||||
(defn core-defn- [fn-name & rest]
|
||||
(defn->def fn-name rest))
|
||||
|
||||
# Hierarchy stubs for sci bootstrap
|
||||
(def core-make-hierarchy make-hierarchy)
|
||||
(defn core-derive
|
||||
|
|
@ -3390,8 +3356,6 @@
|
|||
"remove-watch" core-remove-watch
|
||||
"not" core-not
|
||||
"when-let" core-when-let
|
||||
"defn" core-defn
|
||||
"defn-" core-defn-
|
||||
"derive" core-derive
|
||||
"isa?" core-isa?
|
||||
"parents" core-parents
|
||||
|
|
@ -3467,7 +3431,7 @@
|
|||
(defn core-macro-names
|
||||
"Set of core binding names that are macros."
|
||||
[]
|
||||
@{"when-let" true "defn" true "defn-" true "defrecord" true "defprotocol" true "extend-type" true "extend-protocol" true "extend" true "reify" true "proxy" true "definterface" true "lazy-seq" true "lazy-cat" true})
|
||||
@{"when-let" true "defrecord" true "defprotocol" true "extend-type" true "extend-protocol" true "extend" true "reify" true "proxy" true "definterface" true "lazy-seq" true "lazy-cat" true})
|
||||
|
||||
(def init-core!
|
||||
(fn [& args]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue