Add support for unary operators (not, ~)

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2013-04-06 10:37:21 +02:00
parent 485c98c799
commit 3e9a2178c5
3 changed files with 52 additions and 0 deletions

View File

@ -415,6 +415,22 @@ class HyASTCompiler(object):
return call
@builds("not")
@builds("~")
def compile_unary_operator(self, expression):
if len(expression) != 2:
raise TypeError("Unary operator expects only 1 argument, got %d"
% (len(expression) - 1))
ops = {"not": ast.Not,
"~": ast.Invert}
operator = expression.pop(0)
operand = expression.pop(0)
return ast.UnaryOp(op=ops[operator](),
operand=self.compile(operand),
lineno=operator.start_line,
col_offset=operator.start_column)
@builds("=")
@builds("!=")
@builds("<")

View File

@ -34,6 +34,14 @@ def _ast_spotcheck(arg, root, secondary):
assert getattr(root, arg) == getattr(secondary, arg)
def cant_compile(expr):
try:
hy_compile(tokenize(expr))
assert False
except TypeError:
pass
def test_ast_bad_type():
"Make sure AST breakage can happen"
try:
@ -66,6 +74,21 @@ def test_ast_valid_if():
hy_compile(tokenize("(if foo bar)"))
def test_ast_valid_unary_op():
"Make sure AST can compile valid unary operator"
hy_compile(tokenize("(not 2)"))
hy_compile(tokenize("(~ 1)"))
def test_ast_invalid_unary_op():
"Make sure AST can't compile invalid unary operator"
cant_compile("(not 2 3 4)")
cant_compile("(not)")
cant_compile("(not 2 3 4)")
cant_compile("(~ 2 2 3 4)")
cant_compile("(~)")
def test_ast_bad_while_0_arg():
"Make sure AST can't compile invalid while"
try:

View File

@ -43,6 +43,19 @@
(assert (= fact 120)))
(defn test-not []
"NATIVE: test not"
(assert (not (= 1 2)))
(assert (= true (not false)))
(assert (= false (not 42))) )
(defn test-inv []
"NATIVE: test inv"
(assert (= (~ 1) -2))
(assert (= (~ -2) 1)))
(defn test-in []
"NATIVE: test in"
(assert (in "a" ["a" "b" "c" "d"]))