aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/documentation/lux/macro.lux
blob: bd73247432c39c799e19994220c6ca0dcb5b4425 (plain)
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
104
105
106
107
108
109
110
111
(.module:
  [library
   [lux {"-" char}
    ["$" documentation {"+" documentation:}]
    [data
     [text {"+" \n}
      ["%" format {"+" format}]]
     [collection
      ["[0]" list]]]]]
  ["[0]" / "_"
   ["[1][0]" code]
   ["[1][0]" local]
   ["[1][0]" syntax]
   ["[1][0]" template]]
  [\\library
   ["[0]" /]])

(documentation: /.single_expansion
  (format "Given code that requires applying a macro, does it once and returns the result."
          \n "Otherwise, returns the code as-is.")
  [(single_expansion syntax)])

(documentation: /.expansion
  (format "Given code that requires applying a macro, expands repeatedly until no more direct macro-calls are left."
          \n "Otherwise, returns the code as-is.")
  [(expansion syntax)])

(documentation: /.full_expansion
  "Expands all macro-calls everywhere recursively, until only primitive/base code remains."
  [(full_expansion syntax)])

(documentation: /.symbol
  (format "Generates a unique name as an Code node (ready to be used in code templates)."
          \n "A prefix can be given (or just be empty text) to better identify the code for debugging purposes.")
  [(symbol prefix)])

(documentation: /.wrong_syntax_error
  "A generic error message for macro syntax failures.")

(documentation: /.with_symbols
  "Creates new symbols and offers them to the body expression."
  [(syntax: (synchronized [lock any
                           body any])
     (with_symbols [g!lock g!body g!_]
       (in (list (` (let [(~ g!lock) (~ lock)
                          (~ g!_) ("jvm monitorenter" (~ g!lock))
                          (~ g!body) (~ body)
                          (~ g!_) ("jvm monitorexit" (~ g!lock))]
                      (~ g!body)))))))])

(documentation: /.one_expansion
  "Works just like expand, except that it ensures that the output is a single Code token."
  [(one_expansion token)])

(documentation: /.log_single_expansion!
  (format "Performs a macro-expansion and logs the resulting code."
          \n "You can either use the resulting code, or omit them."
          \n "By omitting them, this macro produces nothing (just like the lux.comment macro).")
  [(log_single_expansion!
    (def: (foo bar baz)
      (-> Int Int Int)
      (int.+ bar baz)))
   (log_single_expansion! "omit"
                          (def: (foo bar baz)
                            (-> Int Int Int)
                            (int.+ bar baz)))])

(documentation: /.log_expansion!
  (format "Performs a macro-expansion and logs the resulting code."
          \n "You can either use the resulting code, or omit them."
          \n "By omitting them, this macro produces nothing (just like the lux.comment macro).")
  [(log_expansion!
    (def: (foo bar baz)
      (-> Int Int Int)
      (int.+ bar baz)))
   (log_expansion! "omit"
                   (def: (foo bar baz)
                     (-> Int Int Int)
                     (int.+ bar baz)))])

(documentation: /.log_full_expansion!
  (format "Performs a macro-expansion and logs the resulting code."
          \n "You can either use the resulting code, or omit them."
          \n "By omitting them, this macro produces nothing (just like the lux.comment macro).")
  [(log_full_expansion!
    (def: (foo bar baz)
      (-> Int Int Int)
      (int.+ bar baz)))
   (log_full_expansion! "omit"
                        (def: (foo bar baz)
                          (-> Int Int Int)
                          (int.+ bar baz)))])

(.def: .public documentation
  (.List $.Module)
  ($.module /._
            ""
            [..single_expansion
             ..expansion
             ..full_expansion
             ..symbol
             ..wrong_syntax_error
             ..with_symbols
             ..one_expansion
             ..log_single_expansion!
             ..log_expansion!
             ..log_full_expansion!]
            [/code.documentation
             /local.documentation
             /syntax.documentation
             /template.documentation]))