rapydscript-ns 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agignore +1 -0
- package/.gitattributes +4 -0
- package/.github/workflows/ci.yml +38 -0
- package/.github/workflows/web-repl-page-deploy.yml +42 -0
- package/=template.pyj +5 -0
- package/CHANGELOG.md +456 -0
- package/CONTRIBUTORS +13 -0
- package/HACKING.md +103 -0
- package/LICENSE +24 -0
- package/README.md +2512 -0
- package/TODO.md +327 -0
- package/add-toc-to-readme +2 -0
- package/bin/export +75 -0
- package/bin/rapydscript +70 -0
- package/bin/web-repl-export +102 -0
- package/build +3 -0
- package/package.json +46 -0
- package/publish.py +37 -0
- package/release/baselib-plain-pretty.js +4370 -0
- package/release/baselib-plain-ugly.js +3 -0
- package/release/compiler.js +18394 -0
- package/release/signatures.json +31 -0
- package/session.vim +4 -0
- package/setup.cfg +2 -0
- package/src/ast.pyj +1356 -0
- package/src/baselib-builtins.pyj +279 -0
- package/src/baselib-containers.pyj +723 -0
- package/src/baselib-errors.pyj +37 -0
- package/src/baselib-internal.pyj +421 -0
- package/src/baselib-itertools.pyj +97 -0
- package/src/baselib-str.pyj +798 -0
- package/src/compiler.pyj +36 -0
- package/src/errors.pyj +30 -0
- package/src/lib/aes.pyj +646 -0
- package/src/lib/collections.pyj +695 -0
- package/src/lib/elementmaker.pyj +83 -0
- package/src/lib/encodings.pyj +126 -0
- package/src/lib/functools.pyj +148 -0
- package/src/lib/gettext.pyj +569 -0
- package/src/lib/itertools.pyj +580 -0
- package/src/lib/math.pyj +193 -0
- package/src/lib/numpy.pyj +2101 -0
- package/src/lib/operator.pyj +11 -0
- package/src/lib/pythonize.pyj +20 -0
- package/src/lib/random.pyj +118 -0
- package/src/lib/re.pyj +470 -0
- package/src/lib/traceback.pyj +63 -0
- package/src/lib/uuid.pyj +77 -0
- package/src/monaco-language-service/analyzer.js +526 -0
- package/src/monaco-language-service/builtins.js +543 -0
- package/src/monaco-language-service/completions.js +498 -0
- package/src/monaco-language-service/diagnostics.js +643 -0
- package/src/monaco-language-service/dts.js +550 -0
- package/src/monaco-language-service/hover.js +121 -0
- package/src/monaco-language-service/index.js +386 -0
- package/src/monaco-language-service/scope.js +162 -0
- package/src/monaco-language-service/signature.js +144 -0
- package/src/output/__init__.pyj +0 -0
- package/src/output/classes.pyj +296 -0
- package/src/output/codegen.pyj +492 -0
- package/src/output/comments.pyj +45 -0
- package/src/output/exceptions.pyj +105 -0
- package/src/output/functions.pyj +491 -0
- package/src/output/literals.pyj +109 -0
- package/src/output/loops.pyj +444 -0
- package/src/output/modules.pyj +329 -0
- package/src/output/operators.pyj +429 -0
- package/src/output/statements.pyj +463 -0
- package/src/output/stream.pyj +309 -0
- package/src/output/treeshake.pyj +182 -0
- package/src/output/utils.pyj +72 -0
- package/src/parse.pyj +3106 -0
- package/src/string_interpolation.pyj +72 -0
- package/src/tokenizer.pyj +702 -0
- package/src/unicode_aliases.pyj +576 -0
- package/src/utils.pyj +192 -0
- package/test/_import_one.pyj +37 -0
- package/test/_import_two/__init__.pyj +11 -0
- package/test/_import_two/level2/__init__.pyj +0 -0
- package/test/_import_two/level2/deep.pyj +4 -0
- package/test/_import_two/other.pyj +6 -0
- package/test/_import_two/sub.pyj +13 -0
- package/test/aes_vectors.pyj +421 -0
- package/test/annotations.pyj +80 -0
- package/test/baselib.pyj +319 -0
- package/test/classes.pyj +452 -0
- package/test/collections.pyj +152 -0
- package/test/decorators.pyj +77 -0
- package/test/dict_spread.pyj +76 -0
- package/test/docstrings.pyj +39 -0
- package/test/elementmaker_test.pyj +45 -0
- package/test/ellipsis.pyj +49 -0
- package/test/functions.pyj +151 -0
- package/test/generators.pyj +41 -0
- package/test/generic.pyj +370 -0
- package/test/imports.pyj +72 -0
- package/test/internationalization.pyj +73 -0
- package/test/lint.pyj +164 -0
- package/test/loops.pyj +85 -0
- package/test/numpy.pyj +734 -0
- package/test/omit_function_metadata.pyj +20 -0
- package/test/regexp.pyj +55 -0
- package/test/repl.pyj +121 -0
- package/test/scoped_flags.pyj +76 -0
- package/test/starargs.pyj +506 -0
- package/test/starred_assign.pyj +104 -0
- package/test/str.pyj +198 -0
- package/test/subscript_tuple.pyj +53 -0
- package/test/unit/fixtures/fibonacci_expected.js +46 -0
- package/test/unit/index.js +2989 -0
- package/test/unit/language-service-builtins.js +815 -0
- package/test/unit/language-service-completions.js +1067 -0
- package/test/unit/language-service-dts.js +543 -0
- package/test/unit/language-service-hover.js +455 -0
- package/test/unit/language-service-scope.js +833 -0
- package/test/unit/language-service-signature.js +458 -0
- package/test/unit/language-service.js +705 -0
- package/test/unit/run-language-service.js +41 -0
- package/test/unit/web-repl.js +484 -0
- package/tools/build-language-service.js +190 -0
- package/tools/cli.js +547 -0
- package/tools/compile.js +219 -0
- package/tools/compiler.js +108 -0
- package/tools/completer.js +131 -0
- package/tools/embedded_compiler.js +251 -0
- package/tools/export.js +316 -0
- package/tools/gettext.js +185 -0
- package/tools/ini.js +65 -0
- package/tools/lint.js +705 -0
- package/tools/msgfmt.js +187 -0
- package/tools/repl.js +223 -0
- package/tools/self.js +162 -0
- package/tools/test.js +118 -0
- package/tools/utils.js +128 -0
- package/tools/web_repl.js +95 -0
- package/try +41 -0
- package/web-repl/env.js +74 -0
- package/web-repl/index.html +163 -0
- package/web-repl/language-service.js +4084 -0
- package/web-repl/main.js +254 -0
- package/web-repl/prism.css +139 -0
- package/web-repl/prism.js +113 -0
- package/web-repl/rapydscript.js +435 -0
- package/web-repl/sha1.js +25 -0
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD
|
|
3
|
+
# RapydScript implementation of Python's itertools standard library.
|
|
4
|
+
#
|
|
5
|
+
# Supported: count, cycle, repeat, accumulate, chain, compress,
|
|
6
|
+
# dropwhile, filterfalse, groupby, islice, pairwise,
|
|
7
|
+
# starmap, takewhile, zip_longest, product,
|
|
8
|
+
# permutations, combinations, combinations_with_replacement
|
|
9
|
+
|
|
10
|
+
# Sentinel: distinguishes "initial not provided" from "initial=None"
|
|
11
|
+
_NO_INITIAL = {}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _to_array(iterable):
|
|
15
|
+
"""Convert any iterable to a plain JavaScript array."""
|
|
16
|
+
if Array.isArray(iterable):
|
|
17
|
+
return iterable.slice()
|
|
18
|
+
if jstype(iterable) is 'string':
|
|
19
|
+
return iterable.split('')
|
|
20
|
+
a = []
|
|
21
|
+
it = iter(iterable)
|
|
22
|
+
r = it.next()
|
|
23
|
+
while not r.done:
|
|
24
|
+
a.push(r.value)
|
|
25
|
+
r = it.next()
|
|
26
|
+
return a
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# ── Infinite iterators ─────────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
class count:
|
|
32
|
+
"""count(start=0, step=1) -> count from start by step indefinitely."""
|
|
33
|
+
|
|
34
|
+
def __init__(self, start=0, step=1):
|
|
35
|
+
self._n = start
|
|
36
|
+
self._step = step
|
|
37
|
+
|
|
38
|
+
def __iter__(self):
|
|
39
|
+
return self
|
|
40
|
+
|
|
41
|
+
def next(self):
|
|
42
|
+
val = self._n
|
|
43
|
+
self._n += self._step
|
|
44
|
+
return {'value': val, 'done': False}
|
|
45
|
+
|
|
46
|
+
def __next__(self):
|
|
47
|
+
return self.next()['value']
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class cycle:
|
|
51
|
+
"""cycle(p) -> p0, p1, ... plast, p0, p1, ... indefinitely."""
|
|
52
|
+
|
|
53
|
+
def __init__(self, iterable):
|
|
54
|
+
self._data = _to_array(iterable)
|
|
55
|
+
self._i = 0
|
|
56
|
+
|
|
57
|
+
def __iter__(self):
|
|
58
|
+
return self
|
|
59
|
+
|
|
60
|
+
def next(self):
|
|
61
|
+
if self._data.length == 0:
|
|
62
|
+
return {'value': undefined, 'done': True}
|
|
63
|
+
val = self._data[self._i]
|
|
64
|
+
self._i = (self._i + 1) % self._data.length
|
|
65
|
+
return {'value': val, 'done': False}
|
|
66
|
+
|
|
67
|
+
def __next__(self):
|
|
68
|
+
r = self.next()
|
|
69
|
+
if r.done:
|
|
70
|
+
raise StopIteration()
|
|
71
|
+
return r.value
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class repeat:
|
|
75
|
+
"""repeat(elem, n=None) -> repeat elem n times, or forever if n is None."""
|
|
76
|
+
|
|
77
|
+
def __init__(self, obj, times=None):
|
|
78
|
+
self._obj = obj
|
|
79
|
+
self._times = times
|
|
80
|
+
self._n = 0
|
|
81
|
+
|
|
82
|
+
def __iter__(self):
|
|
83
|
+
return self
|
|
84
|
+
|
|
85
|
+
def next(self):
|
|
86
|
+
if self._times is not None and self._n >= self._times:
|
|
87
|
+
return {'value': undefined, 'done': True}
|
|
88
|
+
self._n += 1
|
|
89
|
+
return {'value': self._obj, 'done': False}
|
|
90
|
+
|
|
91
|
+
def __next__(self):
|
|
92
|
+
r = self.next()
|
|
93
|
+
if r.done:
|
|
94
|
+
raise StopIteration()
|
|
95
|
+
return r.value
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# ── Finite iterators ───────────────────────────────────────────────────────
|
|
99
|
+
|
|
100
|
+
class accumulate:
|
|
101
|
+
"""accumulate(p, func=add, initial=no_value) -> p0, p0+p1, p0+p1+p2, ..."""
|
|
102
|
+
|
|
103
|
+
def __init__(self, iterable, func=None, initial=_NO_INITIAL):
|
|
104
|
+
self._it = iter(iterable)
|
|
105
|
+
self._func = func
|
|
106
|
+
self._has_initial = initial is not _NO_INITIAL
|
|
107
|
+
self._total = initial if self._has_initial else None
|
|
108
|
+
self._started = self._has_initial
|
|
109
|
+
self._initial_pending = self._has_initial
|
|
110
|
+
|
|
111
|
+
def __iter__(self):
|
|
112
|
+
return self
|
|
113
|
+
|
|
114
|
+
def next(self):
|
|
115
|
+
if self._initial_pending:
|
|
116
|
+
self._initial_pending = False
|
|
117
|
+
return {'value': self._total, 'done': False}
|
|
118
|
+
r = self._it.next()
|
|
119
|
+
if r.done:
|
|
120
|
+
return {'value': undefined, 'done': True}
|
|
121
|
+
if not self._started:
|
|
122
|
+
self._total = r.value
|
|
123
|
+
self._started = True
|
|
124
|
+
else:
|
|
125
|
+
if self._func is None:
|
|
126
|
+
self._total += r.value
|
|
127
|
+
else:
|
|
128
|
+
self._total = self._func(self._total, r.value)
|
|
129
|
+
return {'value': self._total, 'done': False}
|
|
130
|
+
|
|
131
|
+
def __next__(self):
|
|
132
|
+
r = self.next()
|
|
133
|
+
if r.done:
|
|
134
|
+
raise StopIteration()
|
|
135
|
+
return r.value
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class _ChainIter:
|
|
139
|
+
"""Internal: chain from a pre-built list of iterators."""
|
|
140
|
+
|
|
141
|
+
def __init__(self, iters):
|
|
142
|
+
self._iters = iters
|
|
143
|
+
self._i = 0
|
|
144
|
+
|
|
145
|
+
def __iter__(self):
|
|
146
|
+
return self
|
|
147
|
+
|
|
148
|
+
def next(self):
|
|
149
|
+
while self._i < self._iters.length:
|
|
150
|
+
r = self._iters[self._i].next()
|
|
151
|
+
if not r.done:
|
|
152
|
+
return r
|
|
153
|
+
self._i += 1
|
|
154
|
+
return {'value': undefined, 'done': True}
|
|
155
|
+
|
|
156
|
+
def __next__(self):
|
|
157
|
+
r = self.next()
|
|
158
|
+
if r.done:
|
|
159
|
+
raise StopIteration()
|
|
160
|
+
return r.value
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class _ChainFromIterable:
|
|
164
|
+
"""Internal: chain.from_iterable implementation."""
|
|
165
|
+
|
|
166
|
+
def __init__(self, iterable):
|
|
167
|
+
self._outer = iter(iterable)
|
|
168
|
+
self._inner = None
|
|
169
|
+
|
|
170
|
+
def __iter__(self):
|
|
171
|
+
return self
|
|
172
|
+
|
|
173
|
+
def next(self):
|
|
174
|
+
while True:
|
|
175
|
+
if self._inner is not None:
|
|
176
|
+
r = self._inner.next()
|
|
177
|
+
if not r.done:
|
|
178
|
+
return r
|
|
179
|
+
self._inner = None
|
|
180
|
+
outer_r = self._outer.next()
|
|
181
|
+
if outer_r.done:
|
|
182
|
+
return {'value': undefined, 'done': True}
|
|
183
|
+
self._inner = iter(_to_array(outer_r.value))
|
|
184
|
+
|
|
185
|
+
def __next__(self):
|
|
186
|
+
r = self.next()
|
|
187
|
+
if r.done:
|
|
188
|
+
raise StopIteration()
|
|
189
|
+
return r.value
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def chain(*iterables):
|
|
193
|
+
"""chain(p, q, ...) -> p0, p1, ... plast, q0, q1, ..."""
|
|
194
|
+
return _ChainIter([iter(it) for it in iterables])
|
|
195
|
+
|
|
196
|
+
chain.from_iterable = def(iterable):
|
|
197
|
+
"""chain.from_iterable([[A,B],[C,D]]) -> A B C D"""
|
|
198
|
+
return _ChainFromIterable(iterable)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class compress:
|
|
202
|
+
"""compress(data, selectors) -> (d[i] if s[i]) for each i."""
|
|
203
|
+
|
|
204
|
+
def __init__(self, data, selectors):
|
|
205
|
+
self._data = iter(data)
|
|
206
|
+
self._sel = iter(selectors)
|
|
207
|
+
|
|
208
|
+
def __iter__(self):
|
|
209
|
+
return self
|
|
210
|
+
|
|
211
|
+
def next(self):
|
|
212
|
+
while True:
|
|
213
|
+
dr = self._data.next()
|
|
214
|
+
sr = self._sel.next()
|
|
215
|
+
if dr.done or sr.done:
|
|
216
|
+
return {'value': undefined, 'done': True}
|
|
217
|
+
if sr.value:
|
|
218
|
+
return {'value': dr.value, 'done': False}
|
|
219
|
+
|
|
220
|
+
def __next__(self):
|
|
221
|
+
r = self.next()
|
|
222
|
+
if r.done:
|
|
223
|
+
raise StopIteration()
|
|
224
|
+
return r.value
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class dropwhile:
|
|
228
|
+
"""dropwhile(pred, seq) -> seq[n], seq[n+1], ... (starting where pred fails)."""
|
|
229
|
+
|
|
230
|
+
def __init__(self, predicate, iterable):
|
|
231
|
+
self._pred = predicate
|
|
232
|
+
self._it = iter(iterable)
|
|
233
|
+
self._dropping = True
|
|
234
|
+
|
|
235
|
+
def __iter__(self):
|
|
236
|
+
return self
|
|
237
|
+
|
|
238
|
+
def next(self):
|
|
239
|
+
while True:
|
|
240
|
+
r = self._it.next()
|
|
241
|
+
if r.done:
|
|
242
|
+
return {'value': undefined, 'done': True}
|
|
243
|
+
if self._dropping:
|
|
244
|
+
if not self._pred(r.value):
|
|
245
|
+
self._dropping = False
|
|
246
|
+
return {'value': r.value, 'done': False}
|
|
247
|
+
else:
|
|
248
|
+
return {'value': r.value, 'done': False}
|
|
249
|
+
|
|
250
|
+
def __next__(self):
|
|
251
|
+
r = self.next()
|
|
252
|
+
if r.done:
|
|
253
|
+
raise StopIteration()
|
|
254
|
+
return r.value
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
class filterfalse:
|
|
258
|
+
"""filterfalse(pred, seq) -> elements of seq where pred(elem) is falsy."""
|
|
259
|
+
|
|
260
|
+
def __init__(self, predicate, iterable):
|
|
261
|
+
self._pred = predicate
|
|
262
|
+
self._it = iter(iterable)
|
|
263
|
+
|
|
264
|
+
def __iter__(self):
|
|
265
|
+
return self
|
|
266
|
+
|
|
267
|
+
def next(self):
|
|
268
|
+
while True:
|
|
269
|
+
r = self._it.next()
|
|
270
|
+
if r.done:
|
|
271
|
+
return {'value': undefined, 'done': True}
|
|
272
|
+
if not self._pred(r.value):
|
|
273
|
+
return {'value': r.value, 'done': False}
|
|
274
|
+
|
|
275
|
+
def __next__(self):
|
|
276
|
+
r = self.next()
|
|
277
|
+
if r.done:
|
|
278
|
+
raise StopIteration()
|
|
279
|
+
return r.value
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
class groupby:
|
|
283
|
+
"""groupby(iterable, key=None) -> (k, group_iter) pairs for consecutive equal keys."""
|
|
284
|
+
|
|
285
|
+
def __init__(self, iterable, key=None):
|
|
286
|
+
self._it = iter(iterable)
|
|
287
|
+
self._key = key
|
|
288
|
+
self._curr = {'value': undefined, 'done': False}
|
|
289
|
+
self._curr_key = undefined
|
|
290
|
+
self._initialized = False
|
|
291
|
+
|
|
292
|
+
def __iter__(self):
|
|
293
|
+
return self
|
|
294
|
+
|
|
295
|
+
def _get_key(self, val):
|
|
296
|
+
if self._key is not None:
|
|
297
|
+
return self._key(val)
|
|
298
|
+
return val
|
|
299
|
+
|
|
300
|
+
def _advance(self):
|
|
301
|
+
self._curr = self._it.next()
|
|
302
|
+
if not self._curr.done:
|
|
303
|
+
self._curr_key = self._get_key(self._curr.value)
|
|
304
|
+
|
|
305
|
+
def next(self):
|
|
306
|
+
if not self._initialized:
|
|
307
|
+
self._initialized = True
|
|
308
|
+
self._advance()
|
|
309
|
+
if self._curr.done:
|
|
310
|
+
return {'value': undefined, 'done': True}
|
|
311
|
+
group_key = self._curr_key
|
|
312
|
+
group_items = []
|
|
313
|
+
while not self._curr.done and self._curr_key == group_key:
|
|
314
|
+
group_items.push(self._curr.value)
|
|
315
|
+
self._advance()
|
|
316
|
+
return {'value': [group_key, iter(group_items)], 'done': False}
|
|
317
|
+
|
|
318
|
+
def __next__(self):
|
|
319
|
+
r = self.next()
|
|
320
|
+
if r.done:
|
|
321
|
+
raise StopIteration()
|
|
322
|
+
return r.value
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
class islice:
|
|
326
|
+
"""islice(p, stop) or islice(p, start, stop[, step]) -> sliced iterator."""
|
|
327
|
+
|
|
328
|
+
def __init__(self, iterable, *args):
|
|
329
|
+
self._it = iter(iterable)
|
|
330
|
+
if len(args) == 1:
|
|
331
|
+
self._start = 0
|
|
332
|
+
self._stop = args[0]
|
|
333
|
+
self._step = 1
|
|
334
|
+
elif len(args) == 2:
|
|
335
|
+
self._start = args[0] if args[0] is not None else 0
|
|
336
|
+
self._stop = args[1]
|
|
337
|
+
self._step = 1
|
|
338
|
+
elif len(args) >= 3:
|
|
339
|
+
self._start = args[0] if args[0] is not None else 0
|
|
340
|
+
self._stop = args[1]
|
|
341
|
+
self._step = args[2] if args[2] is not None else 1
|
|
342
|
+
else:
|
|
343
|
+
raise TypeError('islice() requires at least 2 arguments')
|
|
344
|
+
if self._step < 1:
|
|
345
|
+
raise ValueError('Step for islice() must be a positive integer or None')
|
|
346
|
+
self._consumed = 0
|
|
347
|
+
self._next_pos = self._start
|
|
348
|
+
|
|
349
|
+
def __iter__(self):
|
|
350
|
+
return self
|
|
351
|
+
|
|
352
|
+
def next(self):
|
|
353
|
+
if self._stop is not None and self._next_pos >= self._stop:
|
|
354
|
+
return {'value': undefined, 'done': True}
|
|
355
|
+
# Advance underlying iterator to _next_pos
|
|
356
|
+
while self._consumed < self._next_pos:
|
|
357
|
+
r = self._it.next()
|
|
358
|
+
if r.done:
|
|
359
|
+
return {'value': undefined, 'done': True}
|
|
360
|
+
self._consumed += 1
|
|
361
|
+
# Get element at _next_pos
|
|
362
|
+
r = self._it.next()
|
|
363
|
+
if r.done:
|
|
364
|
+
return {'value': undefined, 'done': True}
|
|
365
|
+
self._consumed += 1
|
|
366
|
+
self._next_pos += self._step
|
|
367
|
+
return {'value': r.value, 'done': False}
|
|
368
|
+
|
|
369
|
+
def __next__(self):
|
|
370
|
+
r = self.next()
|
|
371
|
+
if r.done:
|
|
372
|
+
raise StopIteration()
|
|
373
|
+
return r.value
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
class pairwise:
|
|
377
|
+
"""pairwise(iterable) -> (a,b), (b,c), (c,d), ..."""
|
|
378
|
+
|
|
379
|
+
def __init__(self, iterable):
|
|
380
|
+
self._it = iter(iterable)
|
|
381
|
+
self._prev = undefined
|
|
382
|
+
self._started = False
|
|
383
|
+
|
|
384
|
+
def __iter__(self):
|
|
385
|
+
return self
|
|
386
|
+
|
|
387
|
+
def next(self):
|
|
388
|
+
if not self._started:
|
|
389
|
+
r = self._it.next()
|
|
390
|
+
if r.done:
|
|
391
|
+
return {'value': undefined, 'done': True}
|
|
392
|
+
self._prev = r.value
|
|
393
|
+
self._started = True
|
|
394
|
+
r = self._it.next()
|
|
395
|
+
if r.done:
|
|
396
|
+
return {'value': undefined, 'done': True}
|
|
397
|
+
pair = [self._prev, r.value]
|
|
398
|
+
self._prev = r.value
|
|
399
|
+
return {'value': pair, 'done': False}
|
|
400
|
+
|
|
401
|
+
def __next__(self):
|
|
402
|
+
r = self.next()
|
|
403
|
+
if r.done:
|
|
404
|
+
raise StopIteration()
|
|
405
|
+
return r.value
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
class starmap:
|
|
409
|
+
"""starmap(func, iterable) -> func(*it[0]), func(*it[1]), ..."""
|
|
410
|
+
|
|
411
|
+
def __init__(self, func, iterable):
|
|
412
|
+
self._func = func
|
|
413
|
+
self._it = iter(iterable)
|
|
414
|
+
|
|
415
|
+
def __iter__(self):
|
|
416
|
+
return self
|
|
417
|
+
|
|
418
|
+
def next(self):
|
|
419
|
+
r = self._it.next()
|
|
420
|
+
if r.done:
|
|
421
|
+
return {'value': undefined, 'done': True}
|
|
422
|
+
args = _to_array(r.value)
|
|
423
|
+
v"var _result = this._func.apply(undefined, args)"
|
|
424
|
+
return {'value': _result, 'done': False}
|
|
425
|
+
|
|
426
|
+
def __next__(self):
|
|
427
|
+
r = self.next()
|
|
428
|
+
if r.done:
|
|
429
|
+
raise StopIteration()
|
|
430
|
+
return r.value
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
class takewhile:
|
|
434
|
+
"""takewhile(pred, seq) -> seq[0], seq[1], ... until pred fails."""
|
|
435
|
+
|
|
436
|
+
def __init__(self, predicate, iterable):
|
|
437
|
+
self._pred = predicate
|
|
438
|
+
self._it = iter(iterable)
|
|
439
|
+
self._done = False
|
|
440
|
+
|
|
441
|
+
def __iter__(self):
|
|
442
|
+
return self
|
|
443
|
+
|
|
444
|
+
def next(self):
|
|
445
|
+
if self._done:
|
|
446
|
+
return {'value': undefined, 'done': True}
|
|
447
|
+
r = self._it.next()
|
|
448
|
+
if r.done:
|
|
449
|
+
self._done = True
|
|
450
|
+
return {'value': undefined, 'done': True}
|
|
451
|
+
if self._pred(r.value):
|
|
452
|
+
return {'value': r.value, 'done': False}
|
|
453
|
+
self._done = True
|
|
454
|
+
return {'value': undefined, 'done': True}
|
|
455
|
+
|
|
456
|
+
def __next__(self):
|
|
457
|
+
r = self.next()
|
|
458
|
+
if r.done:
|
|
459
|
+
raise StopIteration()
|
|
460
|
+
return r.value
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
class zip_longest:
|
|
464
|
+
"""zip_longest(*iterables, fillvalue=None) -> zip with fill for shorter iterables."""
|
|
465
|
+
|
|
466
|
+
def __init__(self, *iterables, **kwargs):
|
|
467
|
+
self._iters = [iter(it) for it in iterables]
|
|
468
|
+
self._fill = kwargs['fillvalue'] if kwargs and 'fillvalue' in kwargs else None
|
|
469
|
+
self._active = self._iters.length
|
|
470
|
+
self._exhausted = [False for _ in range(self._iters.length)]
|
|
471
|
+
|
|
472
|
+
def __iter__(self):
|
|
473
|
+
return self
|
|
474
|
+
|
|
475
|
+
def next(self):
|
|
476
|
+
if self._active == 0:
|
|
477
|
+
return {'value': undefined, 'done': True}
|
|
478
|
+
values = []
|
|
479
|
+
all_done = True
|
|
480
|
+
for i in range(self._iters.length):
|
|
481
|
+
if self._exhausted[i]:
|
|
482
|
+
values.push(self._fill)
|
|
483
|
+
else:
|
|
484
|
+
r = self._iters[i].next()
|
|
485
|
+
if r.done:
|
|
486
|
+
self._exhausted[i] = True
|
|
487
|
+
self._active -= 1
|
|
488
|
+
values.push(self._fill)
|
|
489
|
+
else:
|
|
490
|
+
all_done = False
|
|
491
|
+
values.push(r.value)
|
|
492
|
+
if all_done:
|
|
493
|
+
return {'value': undefined, 'done': True}
|
|
494
|
+
return {'value': values, 'done': False}
|
|
495
|
+
|
|
496
|
+
def __next__(self):
|
|
497
|
+
r = self.next()
|
|
498
|
+
if r.done:
|
|
499
|
+
raise StopIteration()
|
|
500
|
+
return r.value
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
# ── Combinatoric generators ─────────────────────────────────────────────────
|
|
504
|
+
|
|
505
|
+
def product(*iterables, **kwargs):
|
|
506
|
+
"""product(*iterables, repeat=1) -> cartesian product of iterables."""
|
|
507
|
+
repeat_n = kwargs['repeat'] if kwargs and 'repeat' in kwargs else 1
|
|
508
|
+
pools = [_to_array(it) for it in iterables]
|
|
509
|
+
# Build a flat list of pools repeated repeat_n times
|
|
510
|
+
all_pools = []
|
|
511
|
+
for i in range(repeat_n):
|
|
512
|
+
for p in pools:
|
|
513
|
+
all_pools.push(p)
|
|
514
|
+
result = [[]]
|
|
515
|
+
for pool in all_pools:
|
|
516
|
+
new_result = []
|
|
517
|
+
for x in result:
|
|
518
|
+
for y in pool:
|
|
519
|
+
new_result.push(x.concat([y]))
|
|
520
|
+
result = new_result
|
|
521
|
+
return iter(result)
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
def permutations(iterable, r=None):
|
|
525
|
+
"""permutations(p, r=None) -> r-length permutations of elements in p."""
|
|
526
|
+
pool = _to_array(iterable)
|
|
527
|
+
n = pool.length
|
|
528
|
+
if r is None:
|
|
529
|
+
r = n
|
|
530
|
+
if r > n or (n == 0 and r > 0):
|
|
531
|
+
return iter([])
|
|
532
|
+
result = []
|
|
533
|
+
def _helper(current, remaining):
|
|
534
|
+
if current.length == r:
|
|
535
|
+
result.push(current.slice())
|
|
536
|
+
return
|
|
537
|
+
for i in range(remaining.length):
|
|
538
|
+
current.push(remaining[i])
|
|
539
|
+
_helper(current, remaining.slice(0, i).concat(remaining.slice(i + 1)))
|
|
540
|
+
current.pop()
|
|
541
|
+
_helper([], pool.slice())
|
|
542
|
+
return iter(result)
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
def combinations(iterable, r):
|
|
546
|
+
"""combinations(p, r) -> r-length subsequences of elements in p (no repeats)."""
|
|
547
|
+
pool = _to_array(iterable)
|
|
548
|
+
n = pool.length
|
|
549
|
+
if r > n:
|
|
550
|
+
return iter([])
|
|
551
|
+
result = []
|
|
552
|
+
def _helper(start, current):
|
|
553
|
+
if current.length == r:
|
|
554
|
+
result.push(current.slice())
|
|
555
|
+
return
|
|
556
|
+
for i in range(start, n):
|
|
557
|
+
current.push(pool[i])
|
|
558
|
+
_helper(i + 1, current)
|
|
559
|
+
current.pop()
|
|
560
|
+
_helper(0, [])
|
|
561
|
+
return iter(result)
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
def combinations_with_replacement(iterable, r):
|
|
565
|
+
"""combinations_with_replacement(p, r) -> r-length subsequences allowing repeats."""
|
|
566
|
+
pool = _to_array(iterable)
|
|
567
|
+
n = pool.length
|
|
568
|
+
if n == 0 and r > 0:
|
|
569
|
+
return iter([])
|
|
570
|
+
result = []
|
|
571
|
+
def _helper(start, current):
|
|
572
|
+
if current.length == r:
|
|
573
|
+
result.push(current.slice())
|
|
574
|
+
return
|
|
575
|
+
for i in range(start, n):
|
|
576
|
+
current.push(pool[i])
|
|
577
|
+
_helper(i, current)
|
|
578
|
+
current.pop()
|
|
579
|
+
_helper(0, [])
|
|
580
|
+
return iter(result)
|