diff --git a/hy/compiler.py b/hy/compiler.py index 7294008..d97df00 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -27,6 +27,8 @@ from hy.models.symbol import HySymbol from hy.models.list import HyList from hy.models.dict import HyDict +from hy.util import flatten_literal_list + import ast import sys @@ -63,23 +65,18 @@ class HyASTCompiler(object): def _mangle_branch(self, tree): ret = [] + tree = list(flatten_literal_list(tree)) tree.reverse() if self.returnable and len(tree) > 0: el = tree[0] - if not isinstance(el, (ast.stmt, list)): + if not isinstance(el, ast.stmt): el = tree.pop(0) ret.append(ast.Return(value=el, lineno=el.lineno, col_offset=el.col_offset)) for el in tree: - if type(el) == list: - blob = self._mangle_branch(el) - blob.reverse() - ret += blob - continue - if isinstance(el, ast.stmt): ret.append(el) continue diff --git a/hy/util.py b/hy/util.py new file mode 100644 index 0000000..f2ffdf1 --- /dev/null +++ b/hy/util.py @@ -0,0 +1,28 @@ +# Copyright (c) 2013 Paul Tagliamonte +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. + + +def flatten_literal_list(entry): + for e in entry: + if type(e) == list: + for x in flatten_literal_list(e): + yield x # needs more yield-from + else: + yield e diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index 79fa344..153f548 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -223,15 +223,17 @@ (with-as (open "README.md" "r") fd (pass))) + (defn test-for-doodle [] "NATIVE: test for-do" - (setf (, x y) (, 0 0)) + (do (do (do (do (do (do (do (do (do (setf (, x y) (, 0 0))))))))))) (foreach [- [1 2]] (do (setf x (+ x 1)) (setf y (+ y 1)))) (assert (= y x 2))) + (defn test-comprehensions [] "NATIVE: test list comprehensions" (assert (= (list-comp (* x 2) (x (range 2))) [0 2])) @@ -241,6 +243,7 @@ (assert (= (list-comp (, x y) (x (range 2) y (range 2))) [(, 0 0) (, 0 1) (, 1 0) (, 1 1)]))) + (defn test-defn-order [] "NATIVE: test defn evaluation order" (setv acc []) @@ -251,12 +254,14 @@ (my-fun) (assert (= acc ["Foo" "Bar" "Baz"]))) + (defn test-defn-return [] "NATIVE: test defn return" (defn my-fun [x] (+ x 1)) (assert (= 43 (my-fun 42)))) + (defn test-defn-do [] "NATIVE: test defn evaluation order with do" (setv acc []) @@ -268,6 +273,7 @@ (my-fun) (assert (= acc ["Foo" "Bar" "Baz"]))) + (defn test-defn-do-return [] "NATIVE: test defn return with do" (defn my-fun [x]