Make defmacro! work with optional args
This commit is contained in:
parent
f22195dfbc
commit
edbe8e3b7f
1
NEWS.rst
1
NEWS.rst
@ -54,6 +54,7 @@ New Features
|
|||||||
* `while` and `for` are allowed to have empty bodies
|
* `while` and `for` are allowed to have empty bodies
|
||||||
* `for` supports the various new clause types offered by `lfor`
|
* `for` supports the various new clause types offered by `lfor`
|
||||||
* Added a new module ``hy.model_patterns``
|
* Added a new module ``hy.model_patterns``
|
||||||
|
* `defmacro!` now allows optional args
|
||||||
|
|
||||||
Bug Fixes
|
Bug Fixes
|
||||||
------------------------------
|
------------------------------
|
||||||
|
@ -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.
|
"Like `defmacro/g!`, with automatic once-only evaluation for 'o!' params.
|
||||||
|
|
||||||
Such 'o!' params are available within `body` as the equivalent 'g!' symbol."
|
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)))))
|
gs (lfor s os (HySymbol (+ "g!" (cut s 2)))))
|
||||||
`(defmacro/g! ~name ~args
|
`(defmacro/g! ~name ~args
|
||||||
`(do (setv ~@(interleave ~gs ~os))
|
`(do (setv ~@(interleave ~gs ~os))
|
||||||
|
@ -257,7 +257,14 @@
|
|||||||
;; test that o! is evaluated once only
|
;; test that o! is evaluated once only
|
||||||
(setv foo 40)
|
(setv foo 40)
|
||||||
(foo! (+= foo 1))
|
(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 []
|
(defn test-if-not []
|
||||||
|
Loading…
Reference in New Issue
Block a user