aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/meta/macro/vocabulary.lux
blob: 48ae4bff69c239e0edb6146486fd8e97621cea73 (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
... This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
... If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.

... [Not everything is an expression](https://codewords.recurse.com/issues/two/not-everything-is-an-expression)

(.require
 [library
  [lux (.except local def)
   [abstract
    [monad (.only do)]]
   [control
    ["?" parser (.use "[1]#[0]" functor)]
    ["[0]" exception (.only Exception)]]]]
 ["[0]" // (.only)
  [syntax (.only syntax)
   ["[0]" export]]
  ["/[1]" // (.only)
   ["[0]" code (.only)
    ["?[1]" \\parser (.only Parser)]]
   ["[0]" type (.only)
    ["[0]" nominal (.except def)]]]])

(exception.def .public (invalid_type [expected actual])
  (Exception [Type Type])
  (exception.report
   (list ["Expected" (type.absolute_format expected)]
         ["Actual" (type.absolute_format actual)])))

(.def local
  (Parser [Code Code])
  (?code.tuple (export.with (?#each code.local ?code.local))))

(.def .public def
  (syntax (_ [[public|private@type type] ..local
              [public|private@micro micro] ..local
              [public|private@macro macro] ..local
              [public|private@by_name by_name] ..local])
    (//.with_symbols [g!_ g!type g!value]
      (in (list (` (nominal.def (, public|private@type) (, type)
                     Macro

                     (.def (, public|private@micro) (, micro)
                       (-> Macro (, type))
                       (|>> abstraction))

                     (.def (, public|private@macro) (, macro)
                       (-> (, type) Macro)
                       (|>> representation))))

                (` (.def (, public|private@by_name) ((, by_name) (, g!_))
                     (-> Symbol (Meta Macro))
                     (do ///.monad
                       [[(, g!type) (, g!value)] (///.export (, g!_))]
                       (if (of type.equivalence (,' =) (, type) (, g!type))
                         ((,' in) ((, macro) (as (, type) (, g!value))))
                         (///.failure (exception.error ..invalid_type [(, type) (, g!type)])))))))))))