1
0
mirror of https://github.com/janet-lang/janet synced 2025-06-07 00:54:12 +00:00

Address #1401 - restore if-let tail calls.

Changes to avoid multiple macro expansions of the "false" branch caused
a regression in this functionality.
This commit is contained in:
Calvin Rose 2024-02-15 06:29:33 -06:00
parent c293c7de93
commit 9e0daaee09

View File

@ -665,6 +665,9 @@
(each x xs (*= accum x)) (each x xs (*= accum x))
accum) accum)
# declare ahead of time
(var- macexvar nil)
(defmacro if-let (defmacro if-let
``Make multiple bindings, and if all are truthy, ``Make multiple bindings, and if all are truthy,
evaluate the `tru` form. If any are false or nil, evaluate evaluate the `tru` form. If any are false or nil, evaluate
@ -673,20 +676,19 @@
(def len (length bindings)) (def len (length bindings))
(if (= 0 len) (error "expected at least 1 binding")) (if (= 0 len) (error "expected at least 1 binding"))
(if (odd? len) (error "expected an even number of bindings")) (if (odd? len) (error "expected an even number of bindings"))
(def res (gensym)) (def fal2 (if macexvar (macexvar fal) fal))
(defn aux [i] (defn aux [i]
(if (>= i len) (if (>= i len)
~(do (set ,res ,tru) true) tru
(do (do
(def bl (in bindings i)) (def bl (in bindings i))
(def br (in bindings (+ 1 i))) (def br (in bindings (+ 1 i)))
(if (symbol? bl) (if (symbol? bl)
~(if (def ,bl ,br) ,(aux (+ 2 i))) ~(if (def ,bl ,br) ,(aux (+ 2 i)) ,fal2)
~(if (def ,(def sym (gensym)) ,br) ~(if (def ,(def sym (gensym)) ,br)
(do (def ,bl ,sym) ,(aux (+ 2 i)))))))) (do (def ,bl ,sym) ,(aux (+ 2 i)))
~(do ,fal2)))))
(var ,res nil) (aux 0))
(if ,(aux 0) ,res ,fal)))
(defmacro when-let (defmacro when-let
"Same as `(if-let bindings (do ;body))`." "Same as `(if-let bindings (do ;body))`."
@ -2248,6 +2250,8 @@
(set current (macex1 current on-binding))) (set current (macex1 current on-binding)))
current) current)
(set macexvar macex)
(defmacro varfn (defmacro varfn
``Create a function that can be rebound. `varfn` has the same signature ``Create a function that can be rebound. `varfn` has the same signature
as `defn`, but defines functions in the environment as vars. If a var `name` as `defn`, but defines functions in the environment as vars. If a var `name`