fix: prototype-aware binding lookup for nested let
Add binding-get helper that walks Janet table prototype chain. resolve-sym now uses two-stage lookup: direct get first, then prototype walk as fallback. This fixes access to outer let bindings from inner let forms without breaking fn parameter resolution (which uses direct table keys). All 9 test suites pass including macro-test.
This commit is contained in:
parent
33a5b7e7a4
commit
677d059c0b
4 changed files with 60 additions and 2 deletions
|
|
@ -98,6 +98,18 @@
|
|||
[bindings key value]
|
||||
(put bindings key (if (nil? value) :jolt/nil value)))
|
||||
|
||||
(defn- binding-get
|
||||
"Get a value from bindings, walking the prototype chain."
|
||||
[bindings name]
|
||||
(var result :jolt/not-found)
|
||||
(var t bindings)
|
||||
(while (not (nil? t))
|
||||
(when (in t name)
|
||||
(set result (in t name))
|
||||
(break))
|
||||
(set t (table/getproto t)))
|
||||
result)
|
||||
|
||||
(defn- resolve-sym
|
||||
[ctx bindings sym-s]
|
||||
(let [name (sym-s :name) ns (sym-s :ns)]
|
||||
|
|
@ -109,7 +121,8 @@
|
|||
(let [target-ns (ctx-find-ns ctx ns) v (ns-find target-ns name)]
|
||||
(if v (var-get v) (error (string "Unable to resolve symbol: " ns "/" name))))))
|
||||
# Use :jolt/not-found sentinel to distinguish nil binding from absent binding
|
||||
(let [local (get bindings name :jolt/not-found)]
|
||||
(let [local (get bindings name :jolt/not-found-1)
|
||||
local (if (= local :jolt/not-found-1) (binding-get bindings name) local)]
|
||||
(if (not= local :jolt/not-found)
|
||||
(if (= local :jolt/nil) nil local)
|
||||
(let [current-ns (ctx-current-ns ctx) ns (ctx-find-ns ctx current-ns) v (ns-find ns name)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue