aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/extension.lux
blob: cabab0a8f1b7ac0d25d22a3698900fc679383ecd (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
(.using
 [library
  [lux "*"
   [abstract
    ["[0]" monad]]
   [control
    ["<>" parser ("[1]#[0]" monad)
     ["<c>" code {"+" Parser}]
     ["<a>" analysis]
     ["<s>" synthesis]]]
   [data
    ["[0]" product]
    [collection
     ["[0]" list ("[1]#[0]" functor)]]]
   [macro {"+" with_symbols}
    ["[0]" code]
    [syntax {"+" syntax:}]]
   [tool
    [compiler
     ["[0]" phase]]]]])

(type: Declaration
  (Record
   [#name Code
    #label Text
    #phase Text
    #archive Text
    #inputs (List Code)]))

(def: (declaration default)
  (-> Code (Parser Declaration))
  (<c>.form ($_ <>.and
                <c>.any
                <c>.local_symbol
                <c>.local_symbol
                <c>.local_symbol
                (<c>.tuple (<>.some <c>.any)))))

(template [<any> <end> <and> <result> <extension> <name>]
  [(syntax: .public (<name> [[name extension phase archive inputs] (..declaration (` <any>))
                             body <c>.any])
     (let [g!name (code.local_symbol extension)
           g!phase (code.local_symbol phase)
           g!archive (code.local_symbol archive)]
       (with_symbols [g!handler g!inputs g!error g!_]
         (in (list (` (<extension> (~ name)
                                   (.function ((~ g!handler) (~ g!name) (~ g!phase) (~ g!archive) (~ g!inputs))
                                     (.case ((~! <result>)
                                             ((~! monad.do) (~! <>.monad)
                                              [(~+ inputs)
                                               (~ g!_) <end>]
                                              (.# (~! <>.monad) (~' in) (~ body)))
                                             (~ g!inputs))
                                       {.#Right (~ g!_)}
                                       (~ g!_)

                                       {.#Left (~ g!error)}
                                       ((~! phase.failure) (~ g!error)))
                                     ))))))))]

  [<c>.any <c>.end! <c>.and <c>.result "lux def analysis" analysis:]
  [<a>.any <a>.end! <a>.and <a>.result "lux def synthesis" synthesis:]
  [<s>.any <s>.end! <s>.and <s>.result "lux def generation" generation:]
  [<c>.any <c>.end! <c>.and <c>.result "lux def directive" directive:]
  )