Merge pull request #1418 from rkday/while_else
Allow else after a while loop
This commit is contained in:
commit
9ba22a3be2
1
AUTHORS
1
AUTHORS
@ -83,3 +83,4 @@
|
||||
* Jordan Danford <jordandanford@gmail.com>
|
||||
* Andrew Silva <asilva@law.harvard.edu>
|
||||
* Zaheer Soebhan <z.soebhan@gmail.com>
|
||||
* Rob Day <rkd@rkd.me.uk>
|
||||
|
1
NEWS
1
NEWS
@ -18,6 +18,7 @@ Changes from 0.13.0
|
||||
* new `comment` macro
|
||||
* support EDN `#_` syntax to discard the next term
|
||||
* `return` has been implemented as a special form
|
||||
* `while` loops may now contain an `else` clause, like `for` loops
|
||||
|
||||
[ Bug Fixes ]
|
||||
* Numeric literals are no longer parsed as symbols when followed by a dot
|
||||
|
@ -2146,12 +2146,20 @@ class HyASTCompiler(object):
|
||||
expr.pop(0) # "while"
|
||||
ret = self.compile(expr.pop(0))
|
||||
|
||||
orel = Result()
|
||||
# (while cond body (else …))
|
||||
if expr and expr[-1][0] == HySymbol("else"):
|
||||
else_expr = expr.pop()
|
||||
for else_body in else_expr[1:]:
|
||||
orel += self.compile(else_body)
|
||||
orel += orel.expr_as_stmt()
|
||||
|
||||
body = self._compile_branch(expr)
|
||||
body += body.expr_as_stmt()
|
||||
|
||||
ret += ast.While(test=ret.force_expr,
|
||||
body=body.stmts,
|
||||
orelse=[],
|
||||
orelse=orel.stmts,
|
||||
lineno=expr.start_line,
|
||||
col_offset=expr.start_column)
|
||||
|
||||
|
@ -324,6 +324,7 @@ def test_ast_bad_with():
|
||||
def test_ast_valid_while():
|
||||
"Make sure AST can't compile invalid while"
|
||||
can_compile("(while foo bar)")
|
||||
can_compile("(while foo bar (else baz))")
|
||||
|
||||
|
||||
def test_ast_valid_for():
|
||||
|
@ -266,6 +266,39 @@
|
||||
(assert (= count 0))
|
||||
(assert (= fact 120)))
|
||||
|
||||
(defn test-while-loop-else []
|
||||
(setv count 5)
|
||||
(setv fact 1)
|
||||
(setv myvariable 18)
|
||||
(while (> count 0)
|
||||
(setv fact (* fact count))
|
||||
(setv count (- count 1))
|
||||
(else (setv myvariable 26)))
|
||||
(assert (= count 0))
|
||||
(assert (= fact 120))
|
||||
(assert (= myvariable 26))
|
||||
|
||||
; multiple statements in a while loop should work
|
||||
(setv count 5)
|
||||
(setv fact 1)
|
||||
(setv myvariable 18)
|
||||
(setv myothervariable 15)
|
||||
(while (> count 0)
|
||||
(setv fact (* fact count))
|
||||
(setv count (- count 1))
|
||||
(else (setv myvariable 26)
|
||||
(setv myothervariable 24)))
|
||||
(assert (= count 0))
|
||||
(assert (= fact 120))
|
||||
(assert (= myvariable 26))
|
||||
(assert (= myothervariable 24))
|
||||
|
||||
; else clause shouldn't get run after a break
|
||||
(while True
|
||||
(break)
|
||||
(else (setv myvariable 53)))
|
||||
(assert (= myvariable 26)))
|
||||
|
||||
|
||||
(defn test-branching []
|
||||
"NATIVE: test if branching"
|
||||
|
Loading…
Reference in New Issue
Block a user