Merge branch 'master' into bugfix/paultag/fix-try-except
This commit is contained in:
commit
98134e7396
@ -193,9 +193,13 @@ class Result(object):
|
|||||||
This is useful when we want to use the stored expression in a
|
This is useful when we want to use the stored expression in a
|
||||||
statement context (for instance in a code branch).
|
statement context (for instance in a code branch).
|
||||||
|
|
||||||
|
We drop ast.Names if they are appended to statements, as they
|
||||||
|
can't have any side effect. "Bare" names still get converted to
|
||||||
|
statements.
|
||||||
|
|
||||||
If there is no expression context, return an empty result.
|
If there is no expression context, return an empty result.
|
||||||
"""
|
"""
|
||||||
if self.expr:
|
if self.expr and not (isinstance(self.expr, ast.Name) and self.stmts):
|
||||||
return Result() + ast.Expr(lineno=self.expr.lineno,
|
return Result() + ast.Expr(lineno=self.expr.lineno,
|
||||||
col_offset=self.expr.col_offset,
|
col_offset=self.expr.col_offset,
|
||||||
value=self.expr)
|
value=self.expr)
|
||||||
@ -402,6 +406,9 @@ class HyASTCompiler(object):
|
|||||||
if expr == "&rest" and lambda_keyword is None:
|
if expr == "&rest" and lambda_keyword is None:
|
||||||
lambda_keyword = expr
|
lambda_keyword = expr
|
||||||
elif expr == "&optional":
|
elif expr == "&optional":
|
||||||
|
if len(defaults) > 0:
|
||||||
|
raise HyCompileError("There can only be &optional "
|
||||||
|
"arguments or one &key argument")
|
||||||
lambda_keyword = expr
|
lambda_keyword = expr
|
||||||
elif expr == "&key":
|
elif expr == "&key":
|
||||||
lambda_keyword = expr
|
lambda_keyword = expr
|
||||||
@ -427,8 +434,8 @@ class HyASTCompiler(object):
|
|||||||
"argument")
|
"argument")
|
||||||
else:
|
else:
|
||||||
if len(defaults) > 0:
|
if len(defaults) > 0:
|
||||||
raise HyCompileError("There can only be "
|
raise HyCompileError("There can only be &optional "
|
||||||
"one &key argument")
|
"arguments or one &key argument")
|
||||||
# As you can see, Python has a funny way of
|
# As you can see, Python has a funny way of
|
||||||
# defining keyword arguments.
|
# defining keyword arguments.
|
||||||
for k, v in expr.items():
|
for k, v in expr.items():
|
||||||
@ -436,8 +443,17 @@ class HyASTCompiler(object):
|
|||||||
ret += self.compile(v)
|
ret += self.compile(v)
|
||||||
defaults.append(ret.force_expr)
|
defaults.append(ret.force_expr)
|
||||||
elif lambda_keyword == "&optional":
|
elif lambda_keyword == "&optional":
|
||||||
# not implemented yet.
|
if isinstance(expr, HyList):
|
||||||
pass
|
if not len(expr) == 2:
|
||||||
|
raise TypeError("optional args should be bare names "
|
||||||
|
"or 2-item lists")
|
||||||
|
k, v = expr
|
||||||
|
else:
|
||||||
|
k = expr
|
||||||
|
v = HySymbol("None").replace(k)
|
||||||
|
args.append(k)
|
||||||
|
ret += self.compile(v)
|
||||||
|
defaults.append(ret.force_expr)
|
||||||
elif lambda_keyword == "&kwargs":
|
elif lambda_keyword == "&kwargs":
|
||||||
if kwargs:
|
if kwargs:
|
||||||
raise HyCompileError("There can only be one "
|
raise HyCompileError("There can only be one "
|
||||||
|
@ -352,6 +352,13 @@ def test_ast_non_kwapplyable():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test_ast_lambda_lists():
|
||||||
|
"""Ensure the compiler chokes on invalid lambda-lists"""
|
||||||
|
cant_compile('(fn [&key {"a" b} &key {"foo" bar}] [a foo])')
|
||||||
|
cant_compile('(fn [&optional a &key {"foo" bar}] [a foo])')
|
||||||
|
cant_compile('(fn [&optional [a b c]] a)')
|
||||||
|
|
||||||
|
|
||||||
def test_ast_print():
|
def test_ast_print():
|
||||||
code = hy_compile(tokenize("(print \"foo\")")).body[0]
|
code = hy_compile(tokenize("(print \"foo\")")).body[0]
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# Copyright (c) 2013 Julien Danjou <julien@danjou.info>
|
# Copyright (c) 2013 Julien Danjou <julien@danjou.info>
|
||||||
|
# Copyright (c) 2013 Nicolas Dandrimont <nicolas.dandrimont@crans.org>
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
# copy of this software and associated documentation files (the "Software"),
|
# copy of this software and associated documentation files (the "Software"),
|
||||||
@ -29,6 +30,7 @@ else:
|
|||||||
|
|
||||||
from hy.models.expression import HyExpression
|
from hy.models.expression import HyExpression
|
||||||
from hy.models.list import HyList
|
from hy.models.list import HyList
|
||||||
|
from hy.models.symbol import HySymbol
|
||||||
from hy.compiler import HyASTCompiler
|
from hy.compiler import HyASTCompiler
|
||||||
|
|
||||||
|
|
||||||
@ -63,3 +65,26 @@ class HyASTCompilerTest(unittest.TestCase):
|
|||||||
self.assertIsInstance(stmt.body[0], ast.Pass)
|
self.assertIsInstance(stmt.body[0], ast.Pass)
|
||||||
|
|
||||||
self.assertIsInstance(ret.expr, ast.Name)
|
self.assertIsInstance(ret.expr, ast.Name)
|
||||||
|
|
||||||
|
def test_compiler_bare_names(self):
|
||||||
|
"""
|
||||||
|
Check that the compiler doesn't drop bare names from code branches
|
||||||
|
"""
|
||||||
|
ret = self.c.compile(self._make_expression(HySymbol("do"),
|
||||||
|
HySymbol("a"),
|
||||||
|
HySymbol("b"),
|
||||||
|
HySymbol("c")))
|
||||||
|
|
||||||
|
# We expect two statements and a final expr.
|
||||||
|
self.assertEqual(len(ret.stmts), 2)
|
||||||
|
stmt = ret.stmts[0]
|
||||||
|
self.assertIsInstance(stmt, ast.Expr)
|
||||||
|
self.assertIsInstance(stmt.value, ast.Name)
|
||||||
|
self.assertEqual(stmt.value.id, "a")
|
||||||
|
stmt = ret.stmts[1]
|
||||||
|
self.assertIsInstance(stmt, ast.Expr)
|
||||||
|
self.assertIsInstance(stmt.value, ast.Name)
|
||||||
|
self.assertEqual(stmt.value.id, "b")
|
||||||
|
expr = ret.expr
|
||||||
|
self.assertIsInstance(expr, ast.Name)
|
||||||
|
self.assertEqual(expr.id, "c")
|
||||||
|
@ -637,6 +637,22 @@
|
|||||||
(assert (= (foo 10 20 30) [10 (, 20 30) {}])))
|
(assert (= (foo 10 20 30) [10 (, 20 30) {}])))
|
||||||
|
|
||||||
|
|
||||||
|
(defn test-key-arguments []
|
||||||
|
"NATIVE: test &key function arguments"
|
||||||
|
(defn foo [&key {"a" None "b" 1}] [a b])
|
||||||
|
(assert (= (foo) [None 1]))
|
||||||
|
(assert (= (kwapply (foo) {"a" 2}) [2 1]))
|
||||||
|
(assert (= (kwapply (foo) {"b" 42}) [None 42])))
|
||||||
|
|
||||||
|
|
||||||
|
(defn test-optional-arguments []
|
||||||
|
"NATIVE: test &optional function arguments"
|
||||||
|
(defn foo [a b &optional c [d 42]] [a b c d])
|
||||||
|
(assert (= (foo 1 2) [1 2 None 42]))
|
||||||
|
(assert (= (foo 1 2 3) [1 2 3 42]))
|
||||||
|
(assert (= (foo 1 2 3 4) [1 2 3 4])))
|
||||||
|
|
||||||
|
|
||||||
(defn test-quoted-hoistable []
|
(defn test-quoted-hoistable []
|
||||||
"NATIVE: test quoted hoistable"
|
"NATIVE: test quoted hoistable"
|
||||||
(setf f (quote (if true true true)))
|
(setf f (quote (if true true true)))
|
||||||
|
Loading…
Reference in New Issue
Block a user