Merge pull request #1263 from Kodiologist/walk-loop

Fix bug: `loop` replaced strings equal to "recur"
This commit is contained in:
Tuukka Turto 2017-04-01 08:19:44 +03:00 committed by GitHub
commit 61daf98111
3 changed files with 10 additions and 10 deletions

1
NEWS
View File

@ -21,6 +21,7 @@ Changes from 0.12.1
* A `yield` inside of a `with` statement will properly suppress implicit * A `yield` inside of a `with` statement will properly suppress implicit
returns. returns.
* `setv` no longer unnecessarily tries to get attributes * `setv` no longer unnecessarily tries to get attributes
* `loop` no longer replaces string literals equal to "recur"
* The REPL now prints the correct value of `do` and `try` forms * The REPL now prints the correct value of `do` and `try` forms
[ Misc. Improvements ] [ Misc. Improvements ]

View File

@ -24,6 +24,8 @@
;;; The loop/recur macro allows you to construct functions that use tail-call ;;; The loop/recur macro allows you to construct functions that use tail-call
;;; optimization to allow arbitrary levels of recursion. ;;; optimization to allow arbitrary levels of recursion.
(import [hy.contrib.walk [prewalk]])
(defn --trampoline-- [f] (defn --trampoline-- [f]
"Wrap f function and make it tail-call optimized." "Wrap f function and make it tail-call optimized."
;; Takes the function "f" and returns a wrapper that may be used for tail- ;; Takes the function "f" and returns a wrapper that may be used for tail-
@ -47,18 +49,11 @@
(assoc active 0 False) (assoc active 0 False)
result))) result)))
(defn recursive-replace [old-term new-term body]
"Recurses through lists of lists looking for old-term and replacing it with new-term."
((type body)
(list-comp (cond
[(= term old-term) new-term]
[(instance? hy.HyList term)
(recursive-replace old-term new-term term)]
[True term]) [term body])))
(defmacro/g! fnr [signature &rest body] (defmacro/g! fnr [signature &rest body]
(setv new-body (recursive-replace 'recur g!recur-fn body)) (setv new-body (prewalk
(fn [x] (if (and (symbol? x) (= x "recur")) g!recur-fn x))
body))
`(do `(do
(import [hy.contrib.loop [--trampoline--]]) (import [hy.contrib.loop [--trampoline--]])
(with-decorator (with-decorator

View File

@ -44,3 +44,7 @@
(assert True)) (assert True))
(else (else
(assert False)))) (assert False))))
(defn test-recur-string []
"test that `loop` doesn't touch a string named `recur`"
(assert (= (loop [] (+ "recur" "1")) "recur1")))