test(spec): macros, reader, host-interop, namespaces — fix def-doc, resolve, %&
Final spec areas. Bugs caught and fixed: - (def name docstring value) used the docstring as the value; now the 3-arg docstring form binds the value and records :doc meta - resolve was a nil stub; now a special form resolving a symbol to its var (nil if unresolved). Added find-ns (non-creating lookup) and ns-name. - in-ns didn't evaluate its arg, so (in-ns 'foo) failed; now evaluates it per Clojure (the integration test's unquoted form updated to the quoted idiom) - #(... %& ...) built %& as a positional param instead of a & rest param; now emits (fn* [... & gen] ...) so %& captures the rest Full public-API spec layer now in place. conformance 218/218, jpm test green.
This commit is contained in:
parent
e3d2aa8d14
commit
ad5539b0de
8 changed files with 140 additions and 12 deletions
|
|
@ -2432,7 +2432,11 @@
|
|||
@[{:jolt/type :symbol :ns nil :name "ex-info"} msg-form {}]]])
|
||||
|
||||
# resolve stub — returns nil (symbols not found in Jolt's clojure.core)
|
||||
(defn core-resolve [sym] nil)
|
||||
(defn core-resolve [sym] nil) # shadowed by the resolve special form (needs ctx)
|
||||
(defn core-ns-name [ns]
|
||||
# ns object -> its name as a symbol (works whether ns is a table/struct/phm)
|
||||
(let [nm (core-get ns :name)]
|
||||
(if nm {:jolt/type :symbol :ns nil :name (string nm)} nil)))
|
||||
|
||||
# update — works on both structs and tables
|
||||
(defn core-update [m k f & args]
|
||||
|
|
@ -3532,6 +3536,7 @@
|
|||
"defrecord" core-defrecord
|
||||
"comment" core-comment
|
||||
"resolve" core-resolve
|
||||
"ns-name" core-ns-name
|
||||
"update" core-update
|
||||
"update-in" core-update-in
|
||||
"assoc-in" core-assoc-in
|
||||
|
|
|
|||
|
|
@ -580,8 +580,12 @@
|
|||
ns (ctx-find-ns ctx ns-name)
|
||||
# Create var first (unbound) so self-referencing defs resolve
|
||||
v (ns-intern ns (name-sym :name))
|
||||
val (eval-form ctx bindings (in form 2))]
|
||||
# (def name docstring value): docstring is form 2, value form 3
|
||||
has-doc (and (> (length form) 3) (string? (in form 2)))
|
||||
val (eval-form ctx bindings (in form (if has-doc 3 2)))]
|
||||
(bind-root v val)
|
||||
(when has-doc
|
||||
(put v :meta (merge (or (get v :meta) {}) {:doc (in form 2)})))
|
||||
(when dynamic?
|
||||
(put v :dynamic true))
|
||||
# def returns the var (Clojure semantics); REPL prints #'ns/name
|
||||
|
|
@ -695,10 +699,19 @@
|
|||
"ns-aliases" (let [ns (ctx-find-ns ctx (ctx-current-ns ctx))] (ns :aliases))
|
||||
"ns-imports" (let [ns (ctx-find-ns ctx (ctx-current-ns ctx))] (ns :imports))
|
||||
"ns-resolve" (ns-resolve (ctx-find-ns ctx (ctx-current-ns ctx)) (in form 1))
|
||||
"in-ns" (let [ns-name (sym-name-str (in form 1))]
|
||||
(ctx-set-current-ns ctx ns-name)
|
||||
"in-ns" (let [sym (eval-form ctx bindings (in form 1))
|
||||
ns-name (if (and (struct? sym) (= :symbol (sym :jolt/type))) (sym :name) (string sym))]
|
||||
(ctx-find-ns ctx ns-name)
|
||||
(ctx-set-current-ns ctx ns-name)
|
||||
nil)
|
||||
"resolve" (let [sym (eval-form ctx bindings (in form 1))]
|
||||
(if (and (struct? sym) (= :symbol (sym :jolt/type)))
|
||||
(let [r (protect (resolve-var ctx bindings sym))]
|
||||
(if (= (r 0) true) (r 1) nil))
|
||||
nil))
|
||||
"find-ns" (let [sym (eval-form ctx bindings (in form 1))
|
||||
nm (if (and (struct? sym) (= :symbol (sym :jolt/type))) (sym :name) (string sym))]
|
||||
(get (get (ctx :env) :namespaces) nm))
|
||||
"fn*" (let [# optional name: (fn* name [args] ...) / (fn* name ([args] ...)...)
|
||||
named? (and (struct? (in form 1)) (= :symbol ((in form 1) :jolt/type)))
|
||||
fn-name (if named? ((in form 1) :name) nil)
|
||||
|
|
|
|||
|
|
@ -303,14 +303,15 @@
|
|||
f))
|
||||
(def replaced (replace-pct form))
|
||||
(def arg-names @[])
|
||||
# Sort %1 %2 %3 ..., then %, then %&
|
||||
(def sorted-keys (sort (keys arg-map)))
|
||||
(each k sorted-keys
|
||||
# Positional params %, %1, %2, ... in order; %& becomes a `& rest` param.
|
||||
(def pos-keys (sort (filter |(not= $ "%&") (keys arg-map))))
|
||||
(each k pos-keys
|
||||
(array/push arg-names {:jolt/type :symbol :ns nil :name (get arg-map k)}))
|
||||
(when (get arg-map "%&")
|
||||
(array/push arg-names (sym "&"))
|
||||
(array/push arg-names {:jolt/type :symbol :ns nil :name (get arg-map "%&")}))
|
||||
(def result @[(sym "fn*")])
|
||||
(if (> (length arg-names) 0)
|
||||
(array/push result (tuple ;arg-names))
|
||||
(array/push result (tuple))) # no args
|
||||
(array/push result (tuple ;arg-names))
|
||||
(array/push result replaced)
|
||||
[result new-pos]))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue