Merge branch 'master' into pr/886

Conflicts:
	tests/compilers/test_ast.py
This commit is contained in:
Tuukka Turto 2015-08-12 08:05:19 +03:00
commit 1599f29dff
8 changed files with 67 additions and 14 deletions

View File

@ -16,7 +16,7 @@
(defn parse-rfc822-stream [fd] (defn parse-rfc822-stream [fd]
"Parse an RFC822 stream" "Parse an RFC822 stream"
(setv bits {}) (setv bits {})
(setv key null) (setv key None)
(for [line fd] (for [line fd]
(if (in ":" line) (if (in ":" line)
(do (setv line (.split line ":" 1)) (do (setv line (.split line ":" 1))

View File

@ -81,7 +81,7 @@ def load_stdlib():
# keywords in Python 3.* # keywords in Python 3.*
def _is_hy_builtin(name, module_name): def _is_hy_builtin(name, module_name):
extras = ['True', 'False', 'None', extras = ['True', 'False', 'None',
'true', 'false', 'nil', 'null'] 'true', 'false', 'nil']
if name in extras or keyword.iskeyword(name): if name in extras or keyword.iskeyword(name):
return True return True
# for non-Hy modules, check for pre-existing name in # for non-Hy modules, check for pre-existing name in
@ -459,8 +459,9 @@ class HyASTCompiler(object):
try: try:
value = next(exprs_iter) value = next(exprs_iter)
except StopIteration: except StopIteration:
msg = "Keyword argument {kw} needs a value" raise HyTypeError(expr,
raise HyCompileError(msg.format(kw=str(expr))) "Keyword argument {kw} needs "
"a value.".format(kw=str(expr[1:])))
compiled_value = self.compile(value) compiled_value = self.compile(value)
ret += compiled_value ret += compiled_value
@ -2011,6 +2012,10 @@ class HyASTCompiler(object):
result = self.compile(result) result = self.compile(result)
ld_name = self.compile(name) ld_name = self.compile(name)
if isinstance(ld_name.expr, ast.Call):
raise HyTypeError(name,
"Can't assign to a callable: `%s'" % str_name)
if result.temp_variables \ if result.temp_variables \
and isinstance(name, HyString) \ and isinstance(name, HyString) \
and '.' not in name: and '.' not in name:

View File

@ -289,7 +289,6 @@ def t_identifier(p):
"true": "True", "true": "True",
"false": "False", "false": "False",
"nil": "None", "nil": "None",
"null": "None",
} }
if obj in table: if obj in table:
@ -308,6 +307,9 @@ def t_identifier(p):
if p.endswith("?") and p != "?": if p.endswith("?") and p != "?":
p = "is_%s" % (p[:-1]) p = "is_%s" % (p[:-1])
if p.endswith("!") and p != "!":
p = "%s_bang" % (p[:-1])
return p return p
obj = ".".join([mangle(part) for part in obj.split(".")]) obj = ".".join([mangle(part) for part in obj.split(".")])

View File

@ -219,8 +219,8 @@ def test_ast_good_defclass():
def test_ast_bad_defclass(): def test_ast_bad_defclass():
"Make sure AST can't compile invalid defclass" "Make sure AST can't compile invalid defclass"
cant_compile("(defclass)") cant_compile("(defclass)")
cant_compile("(defclass a null)") cant_compile("(defclass a None)")
cant_compile("(defclass a null null)") cant_compile("(defclass a None None)")
def test_ast_good_lambda(): def test_ast_good_lambda():
@ -439,6 +439,16 @@ def test_lambda_list_keywords_mixed():
" (list x xs kwxs kwoxs))") " (list x xs kwxs kwoxs))")
def test_missing_keyword_argument_value():
"""Ensure the compiler chokes on missing keyword argument values."""
try:
can_compile("((fn [x] x) :x)")
except HyTypeError as e:
assert(e.message == "Keyword argument :x needs a value.")
else:
assert(False)
def test_ast_unicode_strings(): def test_ast_unicode_strings():
"""Ensure we handle unicode strings correctly""" """Ensure we handle unicode strings correctly"""
@ -527,3 +537,17 @@ def test_invalid_list_comprehension():
cant_compile("(genexpr [x [1 2 3 4]] x)") cant_compile("(genexpr [x [1 2 3 4]] x)")
cant_compile("(list-comp None [])") cant_compile("(list-comp None [])")
cant_compile("(list-comp [x [1 2 3]] x)") cant_compile("(list-comp [x [1 2 3]] x)")
def test_bad_setv():
"""Ensure setv handles error cases"""
cant_compile("(setv if 1)")
cant_compile("(setv (a b) [1 2])")
def test_defn():
"""Ensure that defn works correctly in various corner cases"""
cant_compile("(defn if [] 1)")
cant_compile("(defn \"hy\" [] 1)")
cant_compile("(defn :hy [] 1)")
can_compile("(defn &hy [] 1)")

View File

@ -326,6 +326,24 @@ def test_lex_mangling_qmark():
assert entry == [HySymbol(".is_foo.bar.is_baz")] assert entry == [HySymbol(".is_foo.bar.is_baz")]
def test_lex_mangling_bang():
"""Ensure that identifiers ending with a bang get mangled ok"""
entry = tokenize("foo!")
assert entry == [HySymbol("foo_bang")]
entry = tokenize("!")
assert entry == [HySymbol("!")]
entry = tokenize("im!foo")
assert entry == [HySymbol("im!foo")]
entry = tokenize(".foo!")
assert entry == [HySymbol(".foo_bang")]
entry = tokenize("foo.bar!")
assert entry == [HySymbol("foo.bar_bang")]
entry = tokenize("foo!.bar")
assert entry == [HySymbol("foo_bang.bar")]
entry = tokenize(".foo!.bar.baz!")
assert entry == [HySymbol(".foo_bang.bar.baz_bang")]
def test_simple_cons(): def test_simple_cons():
"""Check that cons gets tokenized correctly""" """Check that cons gets tokenized correctly"""
entry = tokenize("(a . b)")[0] entry = tokenize("(a . b)")[0]

View File

@ -54,8 +54,6 @@
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e))))) (except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv nil 1)) (try (eval '(setv nil 1))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e))))) (except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(setv null 1))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(defn defclass [] (print "hello"))) (try (eval '(defn defclass [] (print "hello")))
(except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e))))) (except [e [TypeError]] (assert (in "Can't assign to a builtin" (str e)))))
(try (eval '(defn get [] (print "hello"))) (try (eval '(defn get [] (print "hello")))
@ -228,7 +226,7 @@
"NATIVE: test if cond sorta works." "NATIVE: test if cond sorta works."
(cond (cond
[(= 1 2) (assert (is true false))] [(= 1 2) (assert (is true false))]
[(is null null) (setv x true) (assert x)])) [(is None None) (setv x true) (assert x)]))
(defn test-index [] (defn test-index []
@ -673,6 +671,12 @@
(assert (= 43 (my-fun 42)))) (assert (= 43 (my-fun 42))))
(defn test-defn-lambdakey []
"NATIVE: test defn with a &symbol function name"
(defn &hy [] 1)
(assert (= (&hy) 1)))
(defn test-defn-do [] (defn test-defn-do []
"NATIVE: test defn evaluation order with do" "NATIVE: test defn evaluation order with do"
(setv acc []) (setv acc [])

View File

@ -3,8 +3,8 @@
(assert (= (unless false 1) 1)) (assert (= (unless false 1) 1))
(assert (= (unless false 1 2) 2)) (assert (= (unless false 1 2) 2))
(assert (= (unless false 1 3) 3)) (assert (= (unless false 1 3) 3))
(assert (= (unless true 2) null)) (assert (= (unless true 2) None))
(assert (= (unless true 2) nil)) (assert (= (unless true 2) nil))
(assert (= (unless (!= 1 2) 42) null)) (assert (= (unless (!= 1 2) 42) None))
(assert (= (unless (!= 1 2) 42) nil)) (assert (= (unless (!= 1 2) 42) nil))
(assert (= (unless (!= 2 2) 42) 42))) (assert (= (unless (!= 2 2) 42) 42)))

View File

@ -3,8 +3,8 @@
(assert (= (when true 1) 1)) (assert (= (when true 1) 1))
(assert (= (when true 1 2) 2)) (assert (= (when true 1 2) 2))
(assert (= (when true 1 3) 3)) (assert (= (when true 1 3) 3))
(assert (= (when false 2) null)) (assert (= (when false 2) None))
(assert (= (when (= 1 2) 42) null)) (assert (= (when (= 1 2) 42) None))
(assert (= (when false 2) nil)) (assert (= (when false 2) nil))
(assert (= (when (= 1 2) 42) nil)) (assert (= (when (= 1 2) 42) nil))
(assert (= (when (= 2 2) 42) 42))) (assert (= (when (= 2 2) 42) 42)))