blob: af96eb4e29f4457f6454c28ffbb3e799a8850eed (
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
|
(.module:
[library
[lux "*"
[data
[collection
["[0]" list ("[1]#[0]" mix)]]]
[math
[number
["n" nat]]]
[meta
["[0]" location]]]]
[//
[functor {"+" Functor}]])
(type: .public (CoMonad w)
(Interface
(: (Functor w)
&functor)
(: (All (_ a)
(-> (w a) a))
out)
(: (All (_ a)
(-> (w a) (w (w a))))
disjoint)))
(macro: .public (be tokens state)
(case (: (Maybe [(Maybe Text) Code (List Code) Code])
(case tokens
(^ (list [_ {.#Tuple (list [_ {.#Identifier ["" name]}] comonad)}] [_ {.#Tuple bindings}] body))
{.#Some [{.#Some name} comonad bindings body]}
(^ (list comonad [_ {.#Tuple bindings}] body))
{.#Some [{.#None} comonad bindings body]}
_
{.#None}))
{.#Some [?name comonad bindings body]}
(if (|> bindings list.size (n.% 2) (n.= 0))
(let [[module short] (symbol ..be)
identifier (: (-> Text Code)
(|>> ($_ "lux text concat" module " " short " ") [""] {.#Identifier} [location.dummy]))
g!_ (identifier "_")
g!each (identifier "each")
g!disjoint (identifier "disjoint")
body' (list#mix (: (-> [Code Code] Code Code)
(function (_ binding body')
(with_expansions [<default> (` (|> (~ value) (~ g!disjoint) ((~ g!each) (function ((~ g!_) (~ var)) (~ body')))))]
(let [[var value] binding]
(case var
[_ {.#Identifier ["" _]}]
<default>
[_ {.#Identifier _}]
(` ((~ var) (~ value) (~ body')))
_
<default>)))))
body
(list.reversed (list.pairs bindings)))]
{.#Right [state (list (case ?name
{.#Some name}
(let [name [location.dummy {.#Identifier ["" name]}]]
(` (.case (~ comonad)
(~ name)
(.case (~ name)
[(~ g!each) (~' out) (~ g!disjoint)]
(~ body')))))
{.#None}
(` (.case (~ comonad)
[(~ g!each) (~' out) (~ g!disjoint)]
(~ body')))))]})
{.#Left "'be' bindings must have an even number of parts."})
{.#None}
{.#Left "Wrong syntax for 'be'"}))
|