Fix bug: loop replaced strings equal to "recur"

This commit is contained in:
Kodi Arfer 2017-03-30 15:49:10 -07:00
parent f8e5645c2e
commit 5aadeba3fe
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
returns.
* `setv` no longer unnecessarily tries to get attributes
* `loop` no longer replaces string literals equal to "recur"
[ Misc. Improvements ]
* New contrib module `hy-repr`

View File

@ -24,6 +24,8 @@
;;; The loop/recur macro allows you to construct functions that use tail-call
;;; optimization to allow arbitrary levels of recursion.
(import [hy.contrib.walk [prewalk]])
(defn --trampoline-- [f]
"Wrap f function and make it tail-call optimized."
;; Takes the function "f" and returns a wrapper that may be used for tail-
@ -47,18 +49,11 @@
(assoc active 0 False)
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]
(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
(import [hy.contrib.loop [--trampoline--]])
(with-decorator

View File

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