File: macros_first_class.hy

package info (click to toggle)
hy 1.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,632 kB
  • sloc: python: 7,299; makefile: 38; sh: 27
file content (103 lines) | stat: -rw-r--r-- 3,181 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
"Tests of using macros as first-class objects: listing, creating, and
deleting them, and retrieving their docstrings. We also test `get-macro`
(with regular, non-reader macros)."

(import
  builtins)

;; * Core macros

(defn test-core []
  (assert (in "when" (.keys builtins._hy_macros)))
  (assert (not-in "global1" (.keys builtins._hy_macros)))
  (assert (not-in "nonexistent" (.keys builtins._hy_macros)))

  (assert (is
    (get-macro when)
    (get-macro "when")
    (get builtins._hy_macros "when")))

  (setv s (. (get-macro when) __doc__))
  (assert s)
  (assert (is (type s) str)))

;; * Global macros

;; ** Creation

; There are three ways to define a global macro:
; 1. `defmacro` in global scope
(defmacro global1 []
  "global1 docstring"
  "from global1")
; 2. `require` in global scope
(require tests.resources.tlib [qplah :as global2])
; 3. Manually updating `_hy_macros`
(eval-and-compile (setv (get _hy_macros "global3") (fn []
  "from global3")))
(eval-and-compile (setv (get _hy_macros (hy.mangle "global☘")) (fn []
  "global☘ docstring"
  "from global☘")))

(defn test-globals []
  (assert (not-in "when" (.keys _hy_macros)))
  (assert (not-in "nonexistent" (.keys _hy_macros)))
  (assert (all (gfor
    k ["global1" "global2" "global3" "global☘"]
    (in (hy.mangle k) (.keys _hy_macros)))))
  (assert (= (global3) "from global3"))
  (assert (= (global☘) "from global☘"))
  (assert (= (. (get-macro global1) __doc__) "global1 docstring"))
  ; https://github.com/hylang/hy/issues/1946
  (assert (= (. (get-macro global☘) __doc__) "global☘ docstring"))
  (assert (= (. (get-macro hyx_globalXshamrockX) __doc__) "global☘ docstring")))

;; ** Deletion
; Try creating and then deleting a global macro.

(defn global4 []
  "from global4 function")
(setv global4-f1 (global4))   ; Calls the function
(defmacro global4 []
  "from global4 macro")
(setv global4-m (global4))    ; Calls the macro
(eval-when-compile (del (get-macro global4)))
(setv global4-f2 (global4))   ; Calls the function again

(defn test-global-delete []
  (assert (= (global4) global4-f1 global4-f2 "from global4 function"))
  (assert (= global4-m "from global4 macro")))

;; ** Shadowing a core macro
; Try overriding a core macro, then deleting the override.

(pragma :warn-on-core-shadow False)
(defmacro / [a b]
  f"{(int a)}/{(int b)}")
(setv div1 (/ 1 2))
(eval-when-compile (del (get-macro /)))
(setv div2 (/ 1 2))

(defn test-global-shadowing-builtin []
  (assert (= div1 "1/2"))
  (assert (= div2 0.5)))

;; * Local macros

(defn test-local-get []
  (defmacro local1 [] "local1 doc" 1)
  (defmacro local2 [] "local2 outer" 2)
  (require tests.resources.local-req-example :as LRE)

  (assert (= (. (get-macro local1) __doc__) "local1 doc"))
  (assert (= (. (get-macro local2) __doc__) "local2 outer"))
  (assert (= (. (get-macro LRE.wiz) __doc__) "remote wiz doc"))

  (defn inner []
    (defmacro local2 [] "local2 inner" 2)
    (defmacro local3 [] "local3 doc" 2)
    (assert (= (. (get-macro local2) __doc__) "local2 inner"))
    (assert (= (. (get-macro local3) __doc__) "local3 doc"))
    (assert (= (. (get-macro LRE.wiz) __doc__) "remote wiz doc")))

  (inner))