aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/macro/syntax/definition.lux
blob: feb0f908a3b6da1f84c9df2c277fd4d2f013371b (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
(.module:
  [library
   [lux {"-" [Definition]}
    [abstract
     [equivalence {"+" [Equivalence]}]
     [monad {"+" [do]}]]
    [control
     ["[0]" exception {"+" [exception:]}]
     ["<>" parser
      ["<[0]>" code {"+" [Parser]}]]]
    [data
     ["[0]" sum]
     ["[0]" product]
     ["[0]" bit]
     ["[0]" name]
     ["[0]" text
      ["%" format]]
     [collection
      ["[0]" list]]]
    ["[0]" macro
     ["[0]" code]]
    ["[0]" meta
     ["[0]" location]]]]
  ["[0]" //
   ["[1][0]" check {"+" [Check]}]])

(type: .public Definition
  (Record
   [#name Text
    #value (Either Check
                   Code)
    #export? Bit]))

(def: .public equivalence
  (Equivalence Definition)
  ($_ product.equivalence
      text.equivalence
      ($_ sum.equivalence
          //check.equivalence
          code.equivalence
          )
      bit.equivalence
      ))

(def: extension
  "lux def")

(def: dummy
  Code
  (` [.#module (~ (code.text (value@ .#module location.dummy)))
      .#line   (~ (code.nat (value@ .#line location.dummy)))
      .#column (~ (code.nat (value@ .#column location.dummy)))]))

(def: .public (format (^slots [#name #value #export?]))
  (-> Definition Code)
  (` ((~ (code.text ..extension))
      (~ (code.local_identifier #name))
      (~ (case #value
           {.#Left check}
           (//check.format check)

           {.#Right value}
           value))
      (~ (code.bit #export?)))))

(def: .public (parser compiler)
  (-> Lux (Parser Definition))
  (do [! <>.monad]
    [raw <code>.any
     me_raw (|> raw
                macro.full_expansion
                (meta.result compiler)
                <>.lifted)]
    (<| (<code>.local me_raw)
        <code>.form
        (<>.after (<code>.text! ..extension))
        ($_ <>.and
            <code>.local_identifier
            (<>.or //check.parser
                   <code>.any)
            <code>.bit
            ))))

(exception: .public (lacks_type [definition Definition])
  (exception.report
   ["Definition" (%.code (..format definition))]))

(def: .public (typed compiler)
  (-> Lux (Parser Definition))
  (do <>.monad
    [definition (..parser compiler)
     _ (case (value@ #value definition)
         {.#Left _}
         (in [])

         {.#Right _}
         (<>.lifted (exception.except ..lacks_type [definition])))]
    (in definition)))