Skip to content

Commit

Permalink
Merge branch 'master' into pr/796
Browse files Browse the repository at this point in the history
  • Loading branch information
paultag committed Apr 30, 2015
2 parents 2ad2d5a + 5f1776f commit 42983d1
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 1 deletion.
13 changes: 13 additions & 0 deletions hy/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -1949,6 +1949,19 @@ def compile_function_def(self, expression):
raise HyTypeError(expression,
"First argument to (fn) must be a list")
ret, args, defaults, stararg, kwargs = self._parse_lambda_list(arglist)
for i, arg in enumerate(args):
if isinstance(arg, HyList):
# Destructuring argument
if not arg:
raise HyTypeError(arglist,
"Cannot destruct empty list")
args[i] = var = HySymbol(self.get_anon_var())
expression = HyExpression([
HyExpression([
HyString("setv"), arg, var
])]
) + expression
expression = expression.replace(arg[0])

if PY34:
# Python 3.4+ requires that args are an ast.arg object, rather
Expand Down
31 changes: 30 additions & 1 deletion hy/core/shadow.hy
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,33 @@
(reduce operator.truediv args)))))


(setv *exports* ['+ '- '* '/])
(defn comp-op [op args]
"Helper for shadow comparison operators"
(if (< (len args) 2)
(raise (TypeError "Need at least 2 arguments to compare"))
(reduce operator.and_
(list-comp (op x y)
[(, x y) (zip args (slice args 1))]))))
(defn < [&rest args]
"Shadow < operator for when we need to import / map it against something"
(comp-op operator.lt args))
(defn <= [&rest args]
"Shadow <= operator for when we need to import / map it against something"
(comp-op operator.le args))
(defn = [&rest args]
"Shadow = operator for when we need to import / map it against something"
(comp-op operator.eq args))
(defn != [&rest args]
"Shadow != operator for when we need to import / map it against something"
(comp-op operator.ne args))
(defn >= [&rest args]
"Shadow >= operator for when we need to import / map it against something"
(comp-op operator.ge args))
(defn > [&rest args]
"Shadow > operator for when we need to import / map it against something"
(comp-op operator.gt args))

; TODO figure out a way to shadow "is", "is_not", "and", "or"


(setv *exports* ['+ '- '* '/ '< '<= '= '!= '>= '>])
6 changes: 6 additions & 0 deletions tests/compilers/test_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,12 @@ def test_ast_tuple():
assert type(code) == ast.Tuple


def test_argument_destructuring():
""" Ensure argument destructuring compilers. """
can_compile("(fn [[a b]] (print a b))")
cant_compile("(fn [[]] 0)")


def test_lambda_list_keywords_rest():
""" Ensure we can compile functions with lambda list keywords."""
can_compile("(fn (x &rest xs) (print xs))")
Expand Down
5 changes: 5 additions & 0 deletions tests/native_tests/language.hy
Original file line number Diff line number Diff line change
Expand Up @@ -1154,3 +1154,8 @@
(assert
(= (identify-keywords 1 "bloo" :foo)
["other" "other" "keyword"])))

(defn test-argument-destr []
"Make sure argument destructuring works"
(defn f [[a b] [c]] (, a b c))
(assert (= (f [1 2] [3]) (, 1 2 3))))
39 changes: 39 additions & 0 deletions tests/native_tests/shadow.hy
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,42 @@
(assert (= (x 8 2) 4))
(assert (= (x 8 2 2) 2))
(assert (= (x 8 2 2 2) 1))))


(defn test-shadow-compare []
"NATIVE: test shadow compare"
(for [x [< <= = != >= >]]
(assert (try
(x)
(catch [TypeError] True)
(else (throw AssertionError))))
(assert (try
(x 1)
(catch [TypeError] True)
(else (throw AssertionError)))))
(for [(, x y) [[< >=]
[<= >]
[= !=]]]
(for [args [[1 2]
[2 1]
[1 1]
[2 2]]]
(assert (= (apply x args) (not (apply y args))))))
(let [[s-lt <]
[s-gt >]
[s-le <=]
[s-ge >=]
[s-eq =]
[s-ne !=]]
(assert (apply s-lt [1 2 3]))
(assert (not (apply s-lt [3 2 1])))
(assert (apply s-gt [3 2 1]))
(assert (not (apply s-gt [1 2 3])))
(assert (apply s-le [1 1 2 2 3 3]))
(assert (not (apply s-le [1 1 2 2 1 1])))
(assert (apply s-ge [3 3 2 2 1 1]))
(assert (not (apply s-ge [3 3 2 2 3 3])))
(assert (apply s-eq [1 1 1 1 1]))
(assert (not (apply s-eq [1 1 2 1 1])))
(assert (apply s-ne [1 2 3 4 5]))
(assert (not (apply s-ne [1 1 2 3 4])))))

0 comments on commit 42983d1

Please sign in to comment.