support (nonlocal) in let
This commit is contained in:
parent
34038ff433
commit
ba898aa8d8
@ -161,7 +161,7 @@ as can nested let forms.
|
||||
;; else expand if applicable
|
||||
(if (and (in form bound-symbols)
|
||||
(not-in form protected-symbols))
|
||||
`(get ~g!let ~(name form))
|
||||
(HySymbol (+ g!let "::" form))
|
||||
form))]
|
||||
;; We have to treat special forms differently.
|
||||
;; Quotation should suppress symbol expansion,
|
||||
@ -232,15 +232,10 @@ as can nested let forms.
|
||||
[True form]))
|
||||
(expand-symbols #{}
|
||||
`(do
|
||||
(setv ~g!let {}
|
||||
~@bindings)
|
||||
(setv ~@bindings)
|
||||
~@body)))
|
||||
|
||||
#_[special cases for let
|
||||
;; this means we can't use a list for our let scope
|
||||
;; we're using a dict instead.
|
||||
'del',
|
||||
|
||||
;; Symbols containing a dot should be converted to this form.
|
||||
;; attrs should not get expanded,
|
||||
;; but [] lookups should.
|
||||
|
@ -135,8 +135,8 @@
|
||||
(do
|
||||
foo
|
||||
(assert False))
|
||||
(except [ke LookupError]
|
||||
(setv error ke)))
|
||||
(except [ne NameError]
|
||||
(setv error ne)))
|
||||
(setv foo 16)
|
||||
(assert (= foo 16))
|
||||
(setv [foo bar baz] [1 2 3])
|
||||
@ -153,6 +153,14 @@
|
||||
(if done (break))))
|
||||
(assert (= x 1)))
|
||||
|
||||
(defn test-let-continue []
|
||||
(let [foo []]
|
||||
(for [x (range 10)]
|
||||
(let [odd (odd? x)]
|
||||
(if odd (continue))
|
||||
(.append foo x)))
|
||||
(assert (= foo [0 2 4 6 8]))))
|
||||
|
||||
(defn test-let-yield []
|
||||
(defn grind []
|
||||
(yield 0)
|
||||
@ -231,16 +239,15 @@
|
||||
&rest 12]
|
||||
(defn foo [a b &rest xs]
|
||||
(-= a 1)
|
||||
(-= c 1)
|
||||
(setv xs (list xs))
|
||||
(.append xs 42)
|
||||
(, &rest a b c xs))
|
||||
(assert (= xs 6))
|
||||
(assert (= a 88))
|
||||
(assert (= (foo 1 2 3 4)
|
||||
(, 12 0 2 63 [3 4 42])))
|
||||
(, 12 0 2 64 [3 4 42])))
|
||||
(assert (= xs 6))
|
||||
(assert (= c 63))
|
||||
(assert (= c 64))
|
||||
(assert (= a 88))))
|
||||
|
||||
(defn test-let-kwargs []
|
||||
@ -275,12 +282,17 @@
|
||||
(, 10 20 30)))
|
||||
(assert (= (, a b d)
|
||||
(, 1 6 2)))))
|
||||
;; TODO
|
||||
;; test-let-continue
|
||||
;; test-let-closure
|
||||
;; test-let-global
|
||||
|
||||
(defn test-let-closure []
|
||||
(let [count [0]]
|
||||
(defn +count [&optional [x 1]]
|
||||
(+= (get count 0) x)
|
||||
(get count 0)))
|
||||
;; let bindings can still exist outside of a let body
|
||||
(assert (= 1 (+count)))
|
||||
(assert (= 2 (+count)))
|
||||
(assert (= 42 (+count 40))))
|
||||
|
||||
;; TODO
|
||||
;;; Python 3 only
|
||||
;; test-let-nonlocal
|
||||
;; test-let-kwonly
|
||||
;; test-let-global
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
(defn test-exception-cause []
|
||||
(try (raise ValueError :from NameError)
|
||||
(except [e [ValueError]]
|
||||
(assert (= (type (. e __cause__)) NameError)))))
|
||||
(except [e [ValueError]]
|
||||
(assert (= (type (. e __cause__)) NameError)))))
|
||||
|
||||
|
||||
(defn test-kwonly []
|
||||
@ -21,8 +21,8 @@
|
||||
;; keyword-only without default ...
|
||||
(defn kwonly-foo-no-default [&kwonly foo] foo)
|
||||
(setv attempt-to-omit-default (try
|
||||
(kwonly-foo-no-default)
|
||||
(except [e [Exception]] e)))
|
||||
(kwonly-foo-no-default)
|
||||
(except [e [Exception]] e)))
|
||||
;; works
|
||||
(assert (= (kwonly-foo-no-default :foo "quux") "quux"))
|
||||
;; raises TypeError with appropriate message if not supplied
|
||||
@ -64,9 +64,36 @@
|
||||
(assert 0))
|
||||
(defn yield-from-test []
|
||||
(for* [i (range 3)]
|
||||
(yield i))
|
||||
(yield i))
|
||||
(try
|
||||
(yield-from (yield-from-subgenerator-test))
|
||||
(except [e AssertionError]
|
||||
(yield 4))))
|
||||
(yield-from (yield-from-subgenerator-test))
|
||||
(except [e AssertionError]
|
||||
(yield 4))))
|
||||
(assert (= (list (yield-from-test)) [0 1 2 1 2 3 4])))
|
||||
|
||||
(require [hy.contrib.walk [let]])
|
||||
(defn test-let-nonlocal []
|
||||
(let [a 88
|
||||
c 64]
|
||||
(defn foo [a b]
|
||||
(nonlocal c)
|
||||
(-= a 1)
|
||||
(-= c 1)
|
||||
(, a b c))
|
||||
(assert (= a 88))
|
||||
(assert (= (foo 1 2)
|
||||
(, 0 2 63)))
|
||||
(assert (= c 63))
|
||||
(assert (= a 88))))
|
||||
|
||||
(defn test-let-optional []
|
||||
(let [a 1
|
||||
b 6
|
||||
d 2]
|
||||
(defn foo [&kwonly [a a] b [c d]]
|
||||
(, a b c))
|
||||
(assert (= (foo :b "b")
|
||||
(, 1 "b" 2)))
|
||||
(assert (= (foo :b 20 :a 10 :c 30)
|
||||
(, 10 20 30)))))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user