aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/control/pipe.lux
blob: 9c3c5ce36280252aac1576706ebb8953c8831f3e (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
112
113
114
115
(.module:
  [library
   [lux "*"
    [abstract
     [monad {"+" [do]}]]
    [control
     ["[0]" try]
     ["<>" parser
      ["<[0]>" code {"+" [Parser]}]]]
    [data
     ["[0]" identity]
     [collection
      ["[0]" list ("[1]\[0]" monad)]]]
    [macro {"+" [with_identifiers]}
     [syntax {"+" [syntax:]}]
     ["[0]" code]]
    [math
     [number
      ["n" nat]
      ["i" int]]]]])

(def: body^
  (Parser (List Code))
  (<code>.tuple (<>.some <code>.any)))

(syntax: .public (new> [start <code>.any
                        body body^
                        prev <code>.any])
  (in (list (` (|> (~ start) (~+ body))))))

(syntax: .public (let> [binding <code>.any
                        body <code>.any
                        prev <code>.any])
  (in (list (` (let [(~ binding) (~ prev)]
                 (~ body))))))

(def: _reversed_
  (Parser Any)
  (function (_ tokens)
    (#try.Success [(list.reversed tokens) []])))

(syntax: .public (cond> [_ _reversed_
                         prev <code>.any
                         else body^
                         _ _reversed_
                         branches (<>.some (<>.and body^ body^))])
  (with_identifiers [g!temp]
    (in (list (` (let [(~ g!temp) (~ prev)]
                   (cond (~+ (do list.monad
                               [[test then] branches]
                               (list (` (|> (~ g!temp) (~+ test)))
                                     (` (|> (~ g!temp) (~+ then))))))
                         (|> (~ g!temp) (~+ else)))))))))

(syntax: .public (if> [test body^
                       then body^
                       else body^
                       prev <code>.any])
  (in (list (` (cond> [(~+ test)] [(~+ then)]
                      [(~+ else)]
                      (~ prev))))))

(syntax: .public (when> [test body^
                         then body^
                         prev <code>.any])
  (in (list (` (cond> [(~+ test)] [(~+ then)]
                      []
                      (~ prev))))))

(syntax: .public (loop> [test body^
                         then body^
                         prev <code>.any])
  (with_identifiers [g!temp]
    (in (list (` (loop [(~ g!temp) (~ prev)]
                   (if (|> (~ g!temp) (~+ test))
                     ((~' recur) (|> (~ g!temp) (~+ then)))
                     (~ g!temp))))))))

(syntax: .public (do> [monad <code>.any
                       steps (<>.some body^)
                       prev <code>.any])
  (with_identifiers [g!temp]
    (case (list.reversed steps)
      (^ (list& last_step prev_steps))
      (let [step_bindings (do list.monad
                            [step (list.reversed prev_steps)]
                            (list g!temp (` (|> (~ g!temp) (~+ step)))))]
        (in (list (` ((~! do) (~ monad)
                      [.let [(~ g!temp) (~ prev)]
                       (~+ step_bindings)]
                      (|> (~ g!temp) (~+ last_step)))))))

      _
      (in (list prev)))))

(syntax: .public (exec> [body body^
                         prev <code>.any])
  (with_identifiers [g!temp]
    (in (list (` (let [(~ g!temp) (~ prev)]
                   (exec (|> (~ g!temp) (~+ body))
                     (~ g!temp))))))))

(syntax: .public (tuple> [paths (<>.many body^)
                          prev <code>.any])
  (with_identifiers [g!temp]
    (in (list (` (let [(~ g!temp) (~ prev)]
                   [(~+ (list\each (function (_ body) (` (|> (~ g!temp) (~+ body))))
                                   paths))]))))))

(syntax: .public (case> [branches (<>.many (<>.and <code>.any <code>.any))
                         prev <code>.any])
  (in (list (` (case (~ prev)
                 (~+ (|> branches
                         (list\each (function (_ [pattern body]) (list pattern body)))
                         list\conjoint)))))))