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
|
;; else expand if applicable
|
||||||
(if (and (in form bound-symbols)
|
(if (and (in form bound-symbols)
|
||||||
(not-in form protected-symbols))
|
(not-in form protected-symbols))
|
||||||
`(get ~g!let ~(name form))
|
(HySymbol (+ g!let "::" form))
|
||||||
form))]
|
form))]
|
||||||
;; We have to treat special forms differently.
|
;; We have to treat special forms differently.
|
||||||
;; Quotation should suppress symbol expansion,
|
;; Quotation should suppress symbol expansion,
|
||||||
@ -232,15 +232,10 @@ as can nested let forms.
|
|||||||
[True form]))
|
[True form]))
|
||||||
(expand-symbols #{}
|
(expand-symbols #{}
|
||||||
`(do
|
`(do
|
||||||
(setv ~g!let {}
|
(setv ~@bindings)
|
||||||
~@bindings)
|
|
||||||
~@body)))
|
~@body)))
|
||||||
|
|
||||||
#_[special cases for let
|
#_[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.
|
;; Symbols containing a dot should be converted to this form.
|
||||||
;; attrs should not get expanded,
|
;; attrs should not get expanded,
|
||||||
;; but [] lookups should.
|
;; but [] lookups should.
|
||||||
|
@ -135,8 +135,8 @@
|
|||||||
(do
|
(do
|
||||||
foo
|
foo
|
||||||
(assert False))
|
(assert False))
|
||||||
(except [ke LookupError]
|
(except [ne NameError]
|
||||||
(setv error ke)))
|
(setv error ne)))
|
||||||
(setv foo 16)
|
(setv foo 16)
|
||||||
(assert (= foo 16))
|
(assert (= foo 16))
|
||||||
(setv [foo bar baz] [1 2 3])
|
(setv [foo bar baz] [1 2 3])
|
||||||
@ -153,6 +153,14 @@
|
|||||||
(if done (break))))
|
(if done (break))))
|
||||||
(assert (= x 1)))
|
(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 test-let-yield []
|
||||||
(defn grind []
|
(defn grind []
|
||||||
(yield 0)
|
(yield 0)
|
||||||
@ -231,16 +239,15 @@
|
|||||||
&rest 12]
|
&rest 12]
|
||||||
(defn foo [a b &rest xs]
|
(defn foo [a b &rest xs]
|
||||||
(-= a 1)
|
(-= a 1)
|
||||||
(-= c 1)
|
|
||||||
(setv xs (list xs))
|
(setv xs (list xs))
|
||||||
(.append xs 42)
|
(.append xs 42)
|
||||||
(, &rest a b c xs))
|
(, &rest a b c xs))
|
||||||
(assert (= xs 6))
|
(assert (= xs 6))
|
||||||
(assert (= a 88))
|
(assert (= a 88))
|
||||||
(assert (= (foo 1 2 3 4)
|
(assert (= (foo 1 2 3 4)
|
||||||
(, 12 0 2 63 [3 4 42])))
|
(, 12 0 2 64 [3 4 42])))
|
||||||
(assert (= xs 6))
|
(assert (= xs 6))
|
||||||
(assert (= c 63))
|
(assert (= c 64))
|
||||||
(assert (= a 88))))
|
(assert (= a 88))))
|
||||||
|
|
||||||
(defn test-let-kwargs []
|
(defn test-let-kwargs []
|
||||||
@ -275,12 +282,17 @@
|
|||||||
(, 10 20 30)))
|
(, 10 20 30)))
|
||||||
(assert (= (, a b d)
|
(assert (= (, a b d)
|
||||||
(, 1 6 2)))))
|
(, 1 6 2)))))
|
||||||
;; TODO
|
|
||||||
;; test-let-continue
|
(defn test-let-closure []
|
||||||
;; test-let-closure
|
(let [count [0]]
|
||||||
;; test-let-global
|
(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
|
;; TODO
|
||||||
;;; Python 3 only
|
;; test-let-global
|
||||||
;; test-let-nonlocal
|
|
||||||
;; test-let-kwonly
|
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
|
|
||||||
(defn test-exception-cause []
|
(defn test-exception-cause []
|
||||||
(try (raise ValueError :from NameError)
|
(try (raise ValueError :from NameError)
|
||||||
(except [e [ValueError]]
|
(except [e [ValueError]]
|
||||||
(assert (= (type (. e __cause__)) NameError)))))
|
(assert (= (type (. e __cause__)) NameError)))))
|
||||||
|
|
||||||
|
|
||||||
(defn test-kwonly []
|
(defn test-kwonly []
|
||||||
@ -21,8 +21,8 @@
|
|||||||
;; keyword-only without default ...
|
;; keyword-only without default ...
|
||||||
(defn kwonly-foo-no-default [&kwonly foo] foo)
|
(defn kwonly-foo-no-default [&kwonly foo] foo)
|
||||||
(setv attempt-to-omit-default (try
|
(setv attempt-to-omit-default (try
|
||||||
(kwonly-foo-no-default)
|
(kwonly-foo-no-default)
|
||||||
(except [e [Exception]] e)))
|
(except [e [Exception]] e)))
|
||||||
;; works
|
;; works
|
||||||
(assert (= (kwonly-foo-no-default :foo "quux") "quux"))
|
(assert (= (kwonly-foo-no-default :foo "quux") "quux"))
|
||||||
;; raises TypeError with appropriate message if not supplied
|
;; raises TypeError with appropriate message if not supplied
|
||||||
@ -64,9 +64,36 @@
|
|||||||
(assert 0))
|
(assert 0))
|
||||||
(defn yield-from-test []
|
(defn yield-from-test []
|
||||||
(for* [i (range 3)]
|
(for* [i (range 3)]
|
||||||
(yield i))
|
(yield i))
|
||||||
(try
|
(try
|
||||||
(yield-from (yield-from-subgenerator-test))
|
(yield-from (yield-from-subgenerator-test))
|
||||||
(except [e AssertionError]
|
(except [e AssertionError]
|
||||||
(yield 4))))
|
(yield 4))))
|
||||||
(assert (= (list (yield-from-test)) [0 1 2 1 2 3 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