Skip to content

Commit

Permalink
Merge pull request #1637 from oskarkv/patch-1
Browse files Browse the repository at this point in the history
 Look for o!-syms in (flatten args) of defmacro!
  • Loading branch information
Kodiologist authored Jun 25, 2018
2 parents f22195d + 97c15c1 commit 86deff6
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 2 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,4 @@
* Yoan Tournade <[email protected]>
* Simon Gomizelj <[email protected]>
* Yigong Wang <[email protected]>
* Oskar Kvist <[email protected]>
1 change: 1 addition & 0 deletions NEWS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ New Features
* `while` and `for` are allowed to have empty bodies
* `for` supports the various new clause types offered by `lfor`
* Added a new module ``hy.model_patterns``
* `defmacro!` now allows optional args

Bug Fixes
------------------------------
Expand Down
7 changes: 6 additions & 1 deletion hy/core/macros.hy
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,12 @@ the second form, the second result is inserted into the third form, and so on."
"Like `defmacro/g!`, with automatic once-only evaluation for 'o!' params.
Such 'o!' params are available within `body` as the equivalent 'g!' symbol."
(setv os (lfor s args :if (.startswith s "o!") s)
(defn extract-o!-sym [arg]
(cond [(and (symbol? arg) (.startswith arg "o!"))
arg]
[(and (instance? list arg) (.startswith (first arg) "o!"))
(first arg)]))
(setv os (list (filter identity (map extract-o!-sym args)))
gs (lfor s os (HySymbol (+ "g!" (cut s 2)))))
`(defmacro/g! ~name ~args
`(do (setv ~@(interleave ~gs ~os))
Expand Down
9 changes: 8 additions & 1 deletion tests/native_tests/native_macros.hy
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,14 @@
;; test that o! is evaluated once only
(setv foo 40)
(foo! (+= foo 1))
(assert (= 41 foo)))
(assert (= 41 foo))
;; test &optional args
(defmacro! bar! [o!a &optional [o!b 1]] `(do ~g!a ~g!a ~g!b ~g!b))
;; test that o!s are evaluated once only
(bar! (+= foo 1) (+= foo 1))
(assert (= 43 foo))
;; test that the optional arg works
(assert (= (bar! 2) 1)))


(defn test-if-not []
Expand Down

0 comments on commit 86deff6

Please sign in to comment.