From 6c076f76f7e1f81b8a947becdac05e92da6f5b2b Mon Sep 17 00:00:00 2001 From: Ryan Gonzalez Date: Thu, 30 Jul 2015 17:31:57 -0500 Subject: [PATCH] Allow 'for' and 'cond' to take a multi-expression body (closes #868) --- docs/language/api.rst | 9 ++++----- hy/core/macros.hy | 15 ++++++++------- tests/native_tests/contrib/walk.hy | 2 +- tests/native_tests/language.hy | 10 ++++++---- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/docs/language/api.rst b/docs/language/api.rst index 9b8c0b4..b18eaef 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -267,11 +267,10 @@ is only called on every other value in the list. ;; collection is a list of numerical values (for [x collection] - (do - (side-effect1 x) - (if (% x 2) - (continue)) - (side-effect2 x))) + (side-effect1 x) + (if (% x 2) + (continue)) + (side-effect2 x)) dict-comp diff --git a/hy/core/macros.hy b/hy/core/macros.hy index d816ff9..ff8f1fd 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -73,10 +73,11 @@ "check `cond` branch for validity, return the corresponding `if` expr" (if (not (= (type branch) HyList)) (macro-error branch "cond branches need to be a list")) - (if (!= (len branch) 2) - (macro-error branch "cond branches need two items: a test and a code branch")) - (setv (, test thebranch) branch) - `(if ~test ~thebranch)) + (if (< (len branch) 2) + (macro-error branch "cond branches need at least two items: a test and one or more code branches")) + (setv test (car branch)) + (setv thebranch (cdr branch)) + `(if ~test (do ~@thebranch))) (setv root (check-branch branch)) (setv latest-branch root) @@ -96,14 +97,14 @@ (for* [x foo] (for* [y bar] baz))" - (cond + (cond [(odd? (len args)) (macro-error args "`for' requires an even number of args.")] [(empty? body) (macro-error None "`for' requires a body to evaluate")] [(empty? args) `(do ~@body)] - [(= (len args) 2) `(for* [~@args] ~@body)] - [true + [(= (len args) 2) `(for* [~@args] (do ~@body))] + [true (let [[alist (cut args 0 nil 2)]] `(for* [(, ~@alist) (genexpr (, ~@alist) [~@args])] ~@body))])) diff --git a/tests/native_tests/contrib/walk.hy b/tests/native_tests/contrib/walk.hy index abd4360..b282fda 100644 --- a/tests/native_tests/contrib/walk.hy +++ b/tests/native_tests/contrib/walk.hy @@ -32,4 +32,4 @@ (defn test-macroexpand-all [] (assert (= (macroexpand-all '(with [a b c] (for [d c] foo))) - '(with* [a] (with* [b] (with* [c] (do (for* [d c] foo)))))))) + '(with* [a] (with* [b] (with* [c] (do (for* [d c] (do foo))))))))) diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index ed6df0e..085e503 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -86,10 +86,12 @@ (defn test-for-loop [] "NATIVE: test for loops" - (setv count 0) + (setv count1 0 count2 0) (for [x [1 2 3 4 5]] - (setv count (+ count x))) - (assert (= count 15)) + (setv count1 (+ count1 x)) + (setv count2 (+ count2 x))) + (assert (= count1 15)) + (assert (= count2 15)) (setv count 0) (for [x [1 2 3 4 5] y [1 2 3 4 5]] @@ -224,7 +226,7 @@ "NATIVE: test if cond sorta works." (cond [(= 1 2) (assert (is true false))] - [(is null null) (assert (is true true))])) + [(is null null) (setv x true) (assert x)])) (defn test-index []