compiler: add else' support in
try'
This is a bit tricky, since we'll also have to support `finally' in the end, I've introduced an Else statement on my own to be able to recognize it. This fixes #74 Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
48d5a0abc0
commit
f8131d3c36
10
NEWS
10
NEWS
@ -1,3 +1,13 @@
|
|||||||
|
Changes from Hy 0.9.4
|
||||||
|
|
||||||
|
[ Syntax Fixes ]
|
||||||
|
|
||||||
|
* `try' now accepts `else': (JD)
|
||||||
|
(try BODY
|
||||||
|
(except [] BODY)
|
||||||
|
(else BODY))
|
||||||
|
|
||||||
|
|
||||||
Changes from Hy 0.9.4
|
Changes from Hy 0.9.4
|
||||||
|
|
||||||
[ Syntax Fixes ]
|
[ Syntax Fixes ]
|
||||||
|
@ -199,6 +199,7 @@ class HyASTCompiler(object):
|
|||||||
expr.start_line,
|
expr.start_line,
|
||||||
expr.start_column)
|
expr.start_column)
|
||||||
|
|
||||||
|
orelse = []
|
||||||
if len(expr) == 0:
|
if len(expr) == 0:
|
||||||
# (try) or (try body)
|
# (try) or (try body)
|
||||||
handlers = [ast.ExceptHandler(
|
handlers = [ast.ExceptHandler(
|
||||||
@ -209,8 +210,27 @@ class HyASTCompiler(object):
|
|||||||
body=[ast.Pass(lineno=expr.start_line,
|
body=[ast.Pass(lineno=expr.start_line,
|
||||||
col_offset=expr.start_column)])]
|
col_offset=expr.start_column)])]
|
||||||
else:
|
else:
|
||||||
# (try body except except…)
|
handlers = []
|
||||||
handlers = [self.compile(s) for s in expr]
|
for e in expr:
|
||||||
|
if not len(e):
|
||||||
|
raise TypeError("Empty list not allowed in `try'")
|
||||||
|
|
||||||
|
if e[0] in (HySymbol("except"), HySymbol("catch")):
|
||||||
|
handlers.append(self.compile(e))
|
||||||
|
elif e[0] == HySymbol("else"):
|
||||||
|
if orelse:
|
||||||
|
raise TypeError(
|
||||||
|
"`try' cannot have more than one `else'")
|
||||||
|
else:
|
||||||
|
orelse = self._code_branch(self.compile(e[1:]),
|
||||||
|
e.start_line,
|
||||||
|
e.start_column)
|
||||||
|
else:
|
||||||
|
raise TypeError("Unknown expression in `try'")
|
||||||
|
|
||||||
|
if handlers == []:
|
||||||
|
raise TypeError(
|
||||||
|
"`try' must have at least `except' or `finally'")
|
||||||
|
|
||||||
return Try(
|
return Try(
|
||||||
lineno=expr.start_line,
|
lineno=expr.start_line,
|
||||||
@ -218,7 +238,7 @@ class HyASTCompiler(object):
|
|||||||
body=body,
|
body=body,
|
||||||
handlers=handlers,
|
handlers=handlers,
|
||||||
finalbody=[],
|
finalbody=[],
|
||||||
orelse=[])
|
orelse=orelse)
|
||||||
|
|
||||||
@builds("catch")
|
@builds("catch")
|
||||||
@builds("except")
|
@builds("except")
|
||||||
|
@ -116,8 +116,16 @@ def test_ast_good_try():
|
|||||||
"Make sure AST can compile valid try"
|
"Make sure AST can compile valid try"
|
||||||
hy_compile(tokenize("(try)"))
|
hy_compile(tokenize("(try)"))
|
||||||
hy_compile(tokenize("(try 1)"))
|
hy_compile(tokenize("(try 1)"))
|
||||||
hy_compile(tokenize("(try 1 bla)"))
|
hy_compile(tokenize("(try 1 (except) (else 1))"))
|
||||||
hy_compile(tokenize("(try 1 bla bla)"))
|
hy_compile(tokenize("(try 1 (else 1) (except))"))
|
||||||
|
|
||||||
|
|
||||||
|
def test_ast_bad_try():
|
||||||
|
"Make sure AST can't compile invalid try"
|
||||||
|
cant_compile("(try 1 bla)")
|
||||||
|
cant_compile("(try 1 bla bla)")
|
||||||
|
cant_compile("(try (do) (else 1) (else 2))")
|
||||||
|
cant_compile("(try 1 (else 1))")
|
||||||
|
|
||||||
|
|
||||||
def test_ast_good_catch():
|
def test_ast_good_catch():
|
||||||
|
@ -235,7 +235,39 @@
|
|||||||
(print foobar42ofthebaz)
|
(print foobar42ofthebaz)
|
||||||
(catch []
|
(catch []
|
||||||
(setv foobar42ofthebaz 42)
|
(setv foobar42ofthebaz 42)
|
||||||
(assert (= foobar42ofthebaz 42)))))
|
(assert (= foobar42ofthebaz 42))))
|
||||||
|
|
||||||
|
(let [[passed false]]
|
||||||
|
(try
|
||||||
|
(try (pass) (except) (else (bla)))
|
||||||
|
(except [NameError] (setv passed true)))
|
||||||
|
(assert passed))
|
||||||
|
|
||||||
|
(let [[x 0]]
|
||||||
|
(try
|
||||||
|
(raise IOError)
|
||||||
|
(except [IOError]
|
||||||
|
(setv x 45))
|
||||||
|
(else (setv x 44)))
|
||||||
|
(assert (= x 45)))
|
||||||
|
|
||||||
|
(let [[x 0]]
|
||||||
|
(try
|
||||||
|
(raise KeyError)
|
||||||
|
(except []
|
||||||
|
(setv x 45))
|
||||||
|
(else (setv x 44)))
|
||||||
|
(assert (= x 45)))
|
||||||
|
|
||||||
|
(let [[x 0]]
|
||||||
|
(try
|
||||||
|
(try
|
||||||
|
(raise KeyError)
|
||||||
|
(except [IOError]
|
||||||
|
(setv x 45))
|
||||||
|
(else (setv x 44)))
|
||||||
|
(except))
|
||||||
|
(assert (= x 0))))
|
||||||
|
|
||||||
(defn test-earmuffs []
|
(defn test-earmuffs []
|
||||||
"NATIVE: Test earmuffs"
|
"NATIVE: Test earmuffs"
|
||||||
|
Loading…
Reference in New Issue
Block a user