macros.zy 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. (def l %(1 2 3))
  2. (def b 4)
  3. (assert (== ^(0 ~@l ~b) %(0 1 2 3 4)))
  4. // note that we use ^ caret to start a template,
  5. // as opposed to the traditional lisp `` backtick.
  6. // This lets us use Go-style string literals that
  7. // are demarcated by backticks.
  8. (defmac when [predicate & body]
  9. ^(cond ~predicate
  10. (begin
  11. ~@body) %()))
  12. (assert (null? (when false %c)))
  13. (assert (== %a (when true %c %b %a)))
  14. (def h (hash a:1 b:2))
  15. // check that arrays and hashes are getting scanned for ~ syntax unquotes.
  16. (defmac sizer [myHash] ^(let [n (len ~myHash) g (hash sz: (len ~myHash))] (+ n (:sz g))))
  17. (assert (== (sizer h) 4))
  18. // this shouldn't give an error, but it was: error in __main:5: Error on line 1: Unexpected end of input
  19. (defn greet [name] ^(hello ~name))
  20. /* We rolled back the change that made issue 54 feature work:
  21. a) macros run can corrupt the datastack;
  22. b) the user didn't really need it badly; it was a corner case for them,
  23. and they said better to skip it.
  24. Since it is more important to have the Go/zygo script interface
  25. work, and this depends on datastack leaving the right values
  26. for Go to find, we have rolled back the change that enabled
  27. the issues/54 feature. So we also comment out this test.
  28. // zygomys/issues/54 (gensym) in defmac giving same symbol
  29. (assert (!= (gensym) (gensym)))
  30. (defmac aaa [] (gensym) ^())
  31. (aaa) // was causing gensym not to increment env.nextsymbol
  32. (assert (!= (gensym) (gensym)))
  33. // zygomys/issues/54 corner case, user wants macros to be able to arbitrarily alter
  34. // the current environment.
  35. (def myfunc "")
  36. (def myout1 "")
  37. (def myout2 "")
  38. (defmac new1 [] (let [name (gensym "func")] (set myfunc name) ^(defn ~name [] (setq myout1 "function1"))))
  39. (defmac new2 [] (let [name (gensym "func")] (set myfunc name) ^(defn ~name [] (setq myout2 "function2"))))
  40. (new1)
  41. (def prevfunc myfunc)
  42. (printf "prevfunc is '%v'\n" (str prevfunc))
  43. (new2)
  44. (printf "myfunc is now '%v'\n" (str myfunc))
  45. // assert that two different myfunc names were generated by the two different gensym invocations.
  46. (assert (!= myfunc prevfunc))
  47. */