Don't treat [else…] or ("else"…) as else clauses

This commit is contained in:
Kodi Arfer 2017-09-20 16:34:56 -07:00
parent f8fbcf3f06
commit 1e456c6ced
3 changed files with 47 additions and 3 deletions

1
NEWS
View File

@ -44,6 +44,7 @@ Changes from 0.13.0
instead of silently ignoring them
* Multiple expressions are now allowed in the else clause of
a for loop
* `else` clauses in `for` and `while` are recognized more reliably
* Argument destructuring no longer interferes with function docstrings.
[ Misc. Improvements ]

View File

@ -376,6 +376,14 @@ def is_unpack(kind, x):
and x[0] == "unpack_" + kind)
def ends_with_else(expr):
return (expr and
isinstance(expr[-1], HyExpression) and
expr[-1] and
isinstance(expr[-1][0], HySymbol) and
expr[-1][0] == HySymbol("else"))
class HyASTCompiler(object):
def __init__(self, module_name):
@ -1825,7 +1833,7 @@ class HyASTCompiler(object):
orel = Result()
# (for* [] body (else …))
if expression and expression[-1][0] == HySymbol("else"):
if ends_with_else(expression):
else_expr = expression.pop()
for else_body in else_expr[1:]:
orel += self.compile(else_body)
@ -1854,7 +1862,7 @@ class HyASTCompiler(object):
orel = Result()
# (while cond body (else …))
if expr and expr[-1][0] == HySymbol("else"):
if ends_with_else(expr):
else_expr = expr.pop()
for else_body in else_expr[1:]:
orel += self.compile(else_body)

View File

@ -221,6 +221,22 @@
(+= count 10)))
(assert (= count 161))
; don't be fooled by constructs that look like else
(setv s "")
(setv (get (globals) "else") True)
(for [x "abcde"]
(+= s x)
[else (+= s "_")])
(assert (= s "a_b_c_d_e_"))
(setv s "")
(setv (get (globals) "else") True)
(with [(pytest.raises TypeError)]
(for [x "abcde"]
(+= s x)
("else" (+= s "z"))))
(assert (= s "az"))
(assert (= (list ((fn [] (for [x [[1] [2 3]] y x] (yield y)))))
(list-comp y [x [[1] [2 3]] y x])))
(assert (= (list ((fn [] (for [x [[1] [2 3]] y x z (range 5)] (yield z)))))
@ -308,7 +324,26 @@
(while True
(break)
(else (setv myvariable 53)))
(assert (= myvariable 26)))
(assert (= myvariable 26))
; don't be fooled by constructs that look like else clauses
(setv x 2)
(setv a [])
(setv (get (globals) "else") True)
(while x
(.append a x)
(-= x 1)
[else (.append a "e")])
(assert (= a [2 "e" 1 "e"]))
(setv x 2)
(setv a [])
(with [(pytest.raises TypeError)]
(while x
(.append a x)
(-= x 1)
("else" (.append a "e"))))
(assert (= a [2 "e"])))
(defn test-branching []