File: generators.ls

package info (click to toggle)
node-livescript 1.6.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 672 kB
  • sloc: makefile: 45
file content (197 lines) | stat: -rw-r--r-- 3,056 bytes parent folder | download | duplicates (3)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# Generators
# -----------------
#
# * Generator Definition

# generator as argument
ok ->* 1

# named generator function
ok <| :fn ->* 2

# generator definition
x = ->*
  yield 0
  yield 1
  yield 2

y = x!
z = y.next!
eq z.value, 0
eq z.done, false

z = y.next!
eq z.value, 1
eq z.done, false

z = y.next!
eq z.value, 2
eq z.done, false

z = y.next!
eq z.value, void
eq z.done, true

# function declaration generator
function* f
  yield 0
  yield 1
  yield 2

y = f!
z = y.next!
eq z.value, 0
eq z.done, false

z = y.next!
eq z.value, 1
eq z.done, false

z = y.next!
eq z.value, 2
eq z.done, false

z = y.next!
eq z.value, void
eq z.done, true

# yield from
first = ->*
  i = 0
  loop => yield i++
second = ->*
  yield from first!
list = second!
for i to 3
  {value} = list.next!
  eq value, i

# curried bound generators
class A
  val: 5
  curried: (x, y) ~~>*
    yield @val + x + y
fn = (new A).curried
yield-add = fn 2
y = yield-add 3
z = y.next!
eq z.value, 10
eq z.done, false
z = y.next!
eq z.value, void
eq z.done, true

# bound generator
obj =
  bound: ->
    do ~>*
      yield this
  unbound: ->
    do ->*
      yield this

eq obj, obj.bound().next().value
ok obj isnt obj.unbound().next().value

# yield as expression, yield precendence
f1 = ->*
    x = yield "foo"
    yield x + 2
g1 = f1!
eq "foo" g1.next!.value
eq 5 g1.next(3).value

# generator returns
f2 = ->*
    yield 1
    2
g2 = f2!
eq 1 g2.next!.value
eq 2 g2.next!.value

# backcall
test-val = 0
do
    f3 = (gen) ->
        g3 = gen!
        test-val := g3.next!.value

    *<- f3
    yield 1
eq 1 test-val

# don't spread
f4 = ->*
    yield [1, 2]
g4 = f4!
deep-equal [1, 2] g4.next!.value

# parens, consumer yield
f5 = ->*
    if (yield) and not (yield)
        ok true
    else
        ok false
g5 = f5!
g5.next!
g5.next true
g5.next false

# yield expression as argument, as callable
is-two = -> it == 2
f6 = ->*
    is-two yield 1
    ok (yield 1)(2)
    ok (2 |> yield 1)
g6 = f6!
eq 1 g6.next(2).value
g6.next is-two
g6.next is-two

# in switch
f7 = (x) ->*
    y = switch x
    | true => yield 1
    | _    => yield 2
    y
g7 = f7 true
eq 1 g7.next!.value

f8 = ->*
    result = for let i in [1,2,3]
        yield i
        -> i * 2
    result
g8 = f8!
eq 1 g8.next!value
eq 2 g8.next!value
eq 3 g8.next!value
g8_result = g8.next!value
eq 2 g8_result[0]()
eq 4 g8_result[1]()
eq 6 g8_result[2]()

# splats should expand generators (https://github.com/gkz/LiveScript/issues/963)
eq '0,1,2' "#{[...f!]}"

# [LiveScript#1019](https://github.com/gkz/LiveScript/issues/1019)
# in `let` blocks
fn = ->*
  let a = 1
    yield a
eq 1 fn!next!value

# [LiveScript#1023](https://github.com/gkz/LiveScript/issues/1023)
# Loop guards (`when`, `case`, `|`) didn't work with `for..let` loops with `yield` in their bodies
fn = (remainder) ->*
  obj = a: 1, b: 2, c: 3, d: 4
  for own let k, v of obj when v % 2 == remainder
    yield v
gen = fn 0
eq 2 gen.next!value
eq 4 gen.next!value
eq true gen.next!done
gen = fn 1
eq 1 gen.next!value
eq 3 gen.next!value
eq true gen.next!done