Merge branch 'master' into feature/quoting
This commit is contained in:
commit
a948cf2870
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
|
||||
|
||||
[ Syntax Fixes ]
|
||||
|
@ -38,7 +38,21 @@ import sys
|
||||
|
||||
|
||||
class HyCompileError(HyError):
|
||||
pass
|
||||
def __init__(self, exception,
|
||||
start_line=0, start_column=0):
|
||||
self.exception = exception
|
||||
self.start_line = start_line
|
||||
self.start_column = start_column
|
||||
|
||||
def __str__(self):
|
||||
if self.start_line == 0:
|
||||
return("Internal Compiler Bug\n⤷ %s: %s"
|
||||
% (self.exception.__class__.__name__,
|
||||
self.exception))
|
||||
return ("Compilation error at line %d, column %d\n%s: %s"
|
||||
% (self.start_line, self.start_column,
|
||||
self.exception.__class__.__name__,
|
||||
self.exception))
|
||||
|
||||
|
||||
_compile_table = {}
|
||||
@ -111,12 +125,15 @@ class HyASTCompiler(object):
|
||||
for _type in _compile_table:
|
||||
if type(tree) == _type:
|
||||
return _compile_table[_type](self, tree)
|
||||
except HyCompileError:
|
||||
# compile calls compile, so we're going to have multiple raise
|
||||
# nested; so let's re-raise this exception, let's not wrap it in
|
||||
# another HyCompileError!
|
||||
raise
|
||||
except Exception as e:
|
||||
err = HyCompileError(str(e))
|
||||
err.exception = e
|
||||
err.start_line = getattr(e, "start_line", None)
|
||||
err.start_column = getattr(e, "start_column", None)
|
||||
raise err
|
||||
raise HyCompileError(exception=e,
|
||||
start_line=getattr(e, "start_line", 0),
|
||||
start_column=getattr(e, "start_column", 0))
|
||||
|
||||
raise HyCompileError("Unknown type - `%s'" % (str(type(tree))))
|
||||
|
||||
@ -183,10 +200,10 @@ class HyASTCompiler(object):
|
||||
|
||||
@builds("throw")
|
||||
@builds("raise")
|
||||
@checkargs(min=1)
|
||||
@checkargs(max=1)
|
||||
def compile_throw_expression(self, expr):
|
||||
expr.pop(0)
|
||||
exc = self.compile(expr.pop(0))
|
||||
exc = self.compile(expr.pop(0)) if expr else None
|
||||
return ast.Raise(
|
||||
lineno=expr.start_line,
|
||||
col_offset=expr.start_column,
|
||||
@ -215,6 +232,7 @@ class HyASTCompiler(object):
|
||||
expr.start_line,
|
||||
expr.start_column)
|
||||
|
||||
orelse = []
|
||||
if len(expr) == 0:
|
||||
# (try) or (try body)
|
||||
handlers = [ast.ExceptHandler(
|
||||
@ -225,8 +243,27 @@ class HyASTCompiler(object):
|
||||
body=[ast.Pass(lineno=expr.start_line,
|
||||
col_offset=expr.start_column)])]
|
||||
else:
|
||||
# (try body except except…)
|
||||
handlers = [self.compile(s) for s in expr]
|
||||
handlers = []
|
||||
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(
|
||||
lineno=expr.start_line,
|
||||
@ -234,17 +271,17 @@ class HyASTCompiler(object):
|
||||
body=body,
|
||||
handlers=handlers,
|
||||
finalbody=[],
|
||||
orelse=[])
|
||||
orelse=orelse)
|
||||
|
||||
@builds("catch")
|
||||
@builds("except")
|
||||
def compile_catch_expression(self, expr):
|
||||
expr.pop(0) # catch
|
||||
catch = expr.pop(0) # catch
|
||||
|
||||
try:
|
||||
exceptions = expr.pop(0)
|
||||
except IndexError:
|
||||
exceptions = []
|
||||
exceptions = HyList()
|
||||
# exceptions catch should be either:
|
||||
# [[list of exceptions]]
|
||||
# or
|
||||
@ -255,8 +292,10 @@ class HyASTCompiler(object):
|
||||
# [exception]
|
||||
# or
|
||||
# []
|
||||
if not isinstance(exceptions, HyList):
|
||||
raise TypeError("`%s' exceptions list is not a list" % catch)
|
||||
if len(exceptions) > 2:
|
||||
raise TypeError("`catch' exceptions list is too long")
|
||||
raise TypeError("`%s' exceptions list is too long" % catch)
|
||||
|
||||
# [variable [list of exceptions]]
|
||||
# let's pop variable and use it as name
|
||||
@ -294,7 +333,7 @@ class HyASTCompiler(object):
|
||||
elif isinstance(exceptions_list, HySymbol):
|
||||
_type = self.compile(exceptions_list)
|
||||
else:
|
||||
raise TypeError("`catch' needs a valid exception list to catch")
|
||||
raise TypeError("`%s' needs a valid exception list" % catch)
|
||||
|
||||
body = self._code_branch([self.compile(x) for x in expr],
|
||||
expr.start_line,
|
||||
|
@ -94,30 +94,40 @@ def test_ast_good_do():
|
||||
|
||||
def test_ast_good_throw():
|
||||
"Make sure AST can compile valid throw"
|
||||
hy_compile(tokenize("(throw)"))
|
||||
hy_compile(tokenize("(throw 1)"))
|
||||
|
||||
|
||||
def test_ast_bad_throw():
|
||||
"Make sure AST can't compile invalid throw"
|
||||
cant_compile("(throw)")
|
||||
cant_compile("(raise 1 2 3)")
|
||||
|
||||
|
||||
def test_ast_good_raise():
|
||||
"Make sure AST can compile valid raise"
|
||||
hy_compile(tokenize("(raise)"))
|
||||
hy_compile(tokenize("(raise 1)"))
|
||||
|
||||
|
||||
def test_ast_bad_raise():
|
||||
"Make sure AST can't compile invalid raise"
|
||||
cant_compile("(raise)")
|
||||
cant_compile("(raise 1 2 3)")
|
||||
|
||||
|
||||
def test_ast_good_try():
|
||||
"Make sure AST can compile valid try"
|
||||
hy_compile(tokenize("(try)"))
|
||||
hy_compile(tokenize("(try 1)"))
|
||||
hy_compile(tokenize("(try 1 bla)"))
|
||||
hy_compile(tokenize("(try 1 bla bla)"))
|
||||
hy_compile(tokenize("(try 1 (except) (else 1))"))
|
||||
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():
|
||||
@ -134,6 +144,7 @@ def test_ast_good_catch():
|
||||
def test_ast_bad_catch():
|
||||
"Make sure AST can't compile invalid catch"
|
||||
cant_compile("(catch 1)")
|
||||
cant_compile("(catch \"A\")")
|
||||
cant_compile("(catch [1 3])")
|
||||
cant_compile("(catch [x [FooBar] BarBar])")
|
||||
|
||||
|
@ -178,6 +178,26 @@
|
||||
|
||||
(try (pass) (except [IOError]) (except))
|
||||
|
||||
;; Test correct (raise)
|
||||
(let [[passed false]]
|
||||
(try
|
||||
(try
|
||||
(raise IndexError)
|
||||
(except [IndexError] (raise)))
|
||||
(except [IndexError]
|
||||
(setv passed true)))
|
||||
(assert passed))
|
||||
|
||||
;; Test incorrect (raise)
|
||||
(let [[passed false]]
|
||||
(try
|
||||
(raise)
|
||||
;; Python 2 raises TypeError
|
||||
;; Python 3 raises RuntimeError
|
||||
(except [[TypeError RuntimeError]]
|
||||
(setv passed true)))
|
||||
(assert passed))
|
||||
|
||||
(try
|
||||
(raise (KeyError))
|
||||
(catch [[IOError]] (assert false))
|
||||
@ -235,7 +255,39 @@
|
||||
(print foobar42ofthebaz)
|
||||
(catch []
|
||||
(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 []
|
||||
"NATIVE: Test earmuffs"
|
||||
|
Loading…
x
Reference in New Issue
Block a user