firefly-compiler 0.5.39 → 0.5.40

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.
Files changed (129) hide show
  1. package/.hintrc +4 -4
  2. package/.vscode/settings.json +4 -4
  3. package/bin/Release.ff +157 -157
  4. package/bin/firefly.mjs +1 -1
  5. package/compiler/Builder.ff +275 -275
  6. package/compiler/Compiler.ff +234 -234
  7. package/compiler/Dependencies.ff +186 -186
  8. package/compiler/DependencyLock.ff +17 -17
  9. package/compiler/JsEmitter.ff +1437 -1437
  10. package/compiler/LspHook.ff +202 -202
  11. package/compiler/ModuleCache.ff +178 -178
  12. package/compiler/Workspace.ff +88 -88
  13. package/core/.firefly/include/package.json +5 -5
  14. package/core/.firefly/package.ff +2 -2
  15. package/core/Any.ff +25 -25
  16. package/core/Array.ff +298 -298
  17. package/core/Atomic.ff +63 -63
  18. package/core/Box.ff +7 -7
  19. package/core/BrowserSystem.ff +40 -40
  20. package/core/BuildSystem.ff +156 -156
  21. package/core/Crypto.ff +94 -94
  22. package/core/Equal.ff +41 -41
  23. package/core/Error.ff +25 -25
  24. package/core/HttpClient.ff +142 -142
  25. package/core/Instant.ff +24 -24
  26. package/core/Js.ff +305 -305
  27. package/core/JsSystem.ff +135 -135
  28. package/core/Json.ff +423 -423
  29. package/core/List.ff +482 -482
  30. package/core/Lock.ff +108 -108
  31. package/core/NodeSystem.ff +198 -198
  32. package/core/Ordering.ff +160 -160
  33. package/core/Path.ff +377 -378
  34. package/core/Queue.ff +90 -90
  35. package/core/Random.ff +140 -140
  36. package/core/RbMap.ff +216 -216
  37. package/core/Show.ff +44 -44
  38. package/core/SourceLocation.ff +68 -68
  39. package/core/Task.ff +165 -165
  40. package/experimental/benchmarks/ListGrab.ff +23 -23
  41. package/experimental/benchmarks/ListGrab.java +55 -55
  42. package/experimental/benchmarks/Pyrotek45.ff +30 -30
  43. package/experimental/benchmarks/Pyrotek45.java +64 -64
  44. package/experimental/bidirectional/Bidi.ff +88 -88
  45. package/experimental/lines/Main.ff +40 -40
  46. package/experimental/random/Index.ff +53 -53
  47. package/experimental/random/Process.ff +120 -120
  48. package/experimental/random/RunLength.ff +65 -65
  49. package/experimental/random/Scrape.ff +51 -51
  50. package/experimental/random/Symbols.ff +73 -73
  51. package/experimental/random/Tensor.ff +52 -52
  52. package/experimental/random/Units.ff +36 -36
  53. package/experimental/s3/S3TestAuthorizationHeader.ff +39 -39
  54. package/experimental/s3/S3TestPut.ff +16 -16
  55. package/experimental/tests/TestJson.ff +26 -26
  56. package/firefly.sh +0 -0
  57. package/fireflysite/.firefly/package.ff +4 -4
  58. package/fireflysite/CommunityOverview.ff +20 -20
  59. package/fireflysite/CountingButtonDemo.ff +58 -58
  60. package/fireflysite/DocumentParser.ff +325 -325
  61. package/fireflysite/ExamplesOverview.ff +40 -40
  62. package/fireflysite/FrontPage.ff +344 -344
  63. package/fireflysite/GettingStarted.ff +45 -45
  64. package/fireflysite/Guide.ff +456 -456
  65. package/fireflysite/Main.ff +163 -163
  66. package/fireflysite/MatchingPasswordsDemo.ff +82 -82
  67. package/fireflysite/PackagesOverview.ff +49 -49
  68. package/fireflysite/PostgresqlDemo.ff +34 -34
  69. package/fireflysite/ReferenceAll.ff +18 -18
  70. package/fireflysite/ReferenceIntroduction.ff +11 -11
  71. package/fireflysite/Styles.ff +567 -567
  72. package/fireflysite/Test.ff +121 -121
  73. package/fireflysite/assets/markdown/reference/BaseTypes.md +209 -209
  74. package/fireflysite/assets/markdown/reference/EmittedJavascript.md +65 -65
  75. package/fireflysite/assets/markdown/reference/Exceptions.md +101 -101
  76. package/fireflysite/assets/markdown/reference/FunctionsAndMethods.md +364 -364
  77. package/fireflysite/assets/markdown/reference/JavascriptInterop.md +235 -235
  78. package/fireflysite/assets/markdown/reference/ModulesAndPackages.md +162 -162
  79. package/fireflysite/assets/markdown/reference/OldStructuredConcurrency.md +48 -48
  80. package/fireflysite/assets/markdown/reference/PatternMatching.md +224 -224
  81. package/fireflysite/assets/markdown/reference/StatementsAndExpressions.md +86 -86
  82. package/fireflysite/assets/markdown/reference/StructuredConcurrency.md +99 -99
  83. package/fireflysite/assets/markdown/reference/TraitsAndInstances.md +100 -100
  84. package/fireflysite/assets/markdown/reference/UserDefinedTypes.md +184 -184
  85. package/fireflysite/assets/markdown/scratch/ControlFlow.md +136 -136
  86. package/fireflysite/assets/markdown/scratch/Toc.md +40 -40
  87. package/lsp/.firefly/package.ff +1 -1
  88. package/lsp/CompletionHandler.ff +827 -827
  89. package/lsp/Handler.ff +714 -714
  90. package/lsp/HoverHandler.ff +79 -79
  91. package/lsp/LanguageServer.ff +272 -272
  92. package/lsp/SignatureHelpHandler.ff +55 -55
  93. package/lsp/SymbolHandler.ff +181 -181
  94. package/lsp/TestReferences.ff +17 -17
  95. package/lsp/TestReferencesCase.ff +7 -7
  96. package/lsp/stderr.txt +1 -1
  97. package/lsp/stdout.txt +34 -34
  98. package/lux/.firefly/package.ff +1 -1
  99. package/lux/Css.ff +648 -648
  100. package/lux/CssTest.ff +48 -48
  101. package/lux/Lux.ff +608 -608
  102. package/lux/LuxEvent.ff +79 -79
  103. package/lux/Main.ff +123 -123
  104. package/lux/Main2.ff +143 -143
  105. package/lux/TestDry.ff +28 -28
  106. package/output/js/ff/compiler/Builder.mjs +36 -36
  107. package/output/js/ff/core/Path.mjs +0 -2
  108. package/package.json +1 -1
  109. package/rpc/.firefly/package.ff +1 -1
  110. package/rpc/Rpc.ff +70 -70
  111. package/s3/.firefly/package.ff +1 -1
  112. package/s3/S3.ff +92 -92
  113. package/vscode/LICENSE.txt +21 -21
  114. package/vscode/Prepublish.ff +15 -15
  115. package/vscode/README.md +16 -16
  116. package/vscode/client/package-lock.json +544 -544
  117. package/vscode/client/package.json +22 -22
  118. package/vscode/client/src/extension.ts +104 -104
  119. package/vscode/icons/firefly-icon.svg +10 -10
  120. package/vscode/language-configuration.json +61 -61
  121. package/vscode/package-lock.json +3623 -3623
  122. package/vscode/package.json +1 -1
  123. package/vscode/snippets.json +241 -241
  124. package/vscode/syntaxes/firefly-markdown-injection.json +45 -45
  125. package/webserver/.firefly/include/package.json +5 -5
  126. package/webserver/.firefly/package.ff +2 -2
  127. package/webserver/WebServer.ff +647 -647
  128. package/websocket/.firefly/package.ff +1 -1
  129. package/websocket/WebSocket.ff +100 -100
package/core/List.ff CHANGED
@@ -1,482 +1,482 @@
1
- data List[T] {}
2
-
3
- new[T](): List[T] {
4
- []
5
- }
6
-
7
- fill[T](size: Int, value: T): List[T] {
8
- Js->Array->(size)->fill(value!)?
9
- }
10
-
11
- fillBy[T](size: Int, body: Int => T): List[T] {
12
- if(Js.inAsync()) {
13
- let array = Js->Array->(size)
14
- 1.until(size).each {i =>
15
- array.set(i, body(i)!)
16
- }
17
- array?
18
- } else {
19
- Js->Array->from(Js->(length = size), Js->{_, i => body(i?)})?
20
- }
21
- }
22
-
23
-
24
- range(size: Int): List[Int] {
25
- Js->Array->from(Js->(length = size), Js->{_, i => i})?
26
- }
27
-
28
- extend self[T]: List[T] {
29
-
30
- addAll(that: List[T]): List[T] {
31
- self!->concat(that!)?
32
- }
33
-
34
- isEmpty(): Bool {
35
- self.size() == 0
36
- }
37
-
38
- size(): Int {
39
- self!->length?
40
- }
41
-
42
- get(index: Int): Option[T] {
43
- if(index >= 0 && index < self.size()) {
44
- Some(self!.get(index)?)
45
- } else {
46
- None
47
- }
48
- }
49
-
50
- grab(index: Int): T {
51
- if(index < 0 || index >= self.size()) {
52
- throw(GrabException())
53
- }
54
- self!.get(index)?
55
- }
56
-
57
- first(): Option[T] {self.get(0)}
58
-
59
- last(): Option[T] {self.get(self.size() - 1)}
60
-
61
- grabFirst(): T {self.grab(0)}
62
-
63
- grabLast(): T {self.grab(self.size() - 1)}
64
-
65
- takeFirst(count: Int = 1): List[T] {
66
- self!->slice(0, count)?
67
- }
68
-
69
- takeLast(count: Int = 1): List[T] {
70
- self!->slice(-count)?
71
- }
72
-
73
- dropFirst(count: Int = 1): List[T] {
74
- self!->slice(count)?
75
- }
76
-
77
- dropLast(count: Int = 1): List[T] {
78
- self!->slice(0, self.size() - count)?
79
- }
80
-
81
- count(body: T => Bool): Int {
82
- mutable result = 0
83
- mutable i = 0
84
- while {i < self.size()} {
85
- if(body(self.grab(i))) {result += 1}
86
- i += 1
87
- }
88
- result
89
- }
90
-
91
- countWhile(body: T => Bool): Int {
92
- mutable i = 0
93
- while {i < self.size() && body(self.grab(i))} {
94
- i += 1
95
- }
96
- i
97
- }
98
-
99
- takeWhile(body: T => Bool): List[T] {
100
- let result = Array.new()
101
- mutable i = 0
102
- while {i < self.size() && body(self.grab(i))} {
103
- result.push(self.grab(i))
104
- i += 1
105
- }
106
- result.drain()
107
- }
108
-
109
- dropWhile(body: T => Bool): List[T] {
110
- let result = Array.new()
111
- mutable i = 0
112
- while {i < self.size() && body(self.grab(i))} {
113
- i += 1
114
- }
115
- while {i < self.size()} {
116
- result.push(self.grab(i))
117
- i += 1
118
- }
119
- result.drain()
120
- }
121
-
122
- partitionWhile(body: T => Bool): Pair[List[T], List[T]] {
123
- let first = Array.new()
124
- let second = Array.new()
125
- mutable i = 0
126
- while {i < self.size() && body(self.grab(i))} {
127
- first.push(self.grab(i))
128
- i += 1
129
- }
130
- while {i < self.size()} {
131
- second.push(self.grab(i))
132
- i += 1
133
- }
134
- Pair(first.drain(), second.drain())
135
- }
136
-
137
- pairs(): List[Pair[Int, T]] {
138
- mutable i = 0
139
- self.map {x =>
140
- let r = Pair(i, x)
141
- i += 1
142
- r
143
- }
144
- }
145
-
146
- slice(from: Int, until: Int): List[T] {
147
- self.dropFirst(from).takeFirst(until - from)
148
- }
149
-
150
- foldLeft[R](initial: R, body: (R, T) => R): R {
151
- mutable result = initial
152
- self.each {x =>
153
- result = body(result, x)
154
- }
155
- result
156
- }
157
-
158
- update(index: Int, value: T): List[T] {
159
- self.modify(index) {_ => value}
160
- }
161
-
162
- modify(index: Int, body: T => T): List[T] {
163
- if(index < 0 || index >= self.size()) {
164
- throw(GrabException())
165
- }
166
- let result = self!->slice()
167
- result.set(index, body(result.get(index)?)!)
168
- result?
169
- }
170
-
171
- zip[S](that: List[S]): List[Pair[T, S]] {
172
- if(self.size() <= that.size()) {
173
- mutable i = -1
174
- self.map {x =>
175
- i += 1
176
- Pair(x, that.grab(i))
177
- }
178
- } else {
179
- mutable i = -1
180
- that.map {y =>
181
- i += 1
182
- Pair(self.grab(i), y)
183
- }
184
- }
185
- }
186
-
187
- chunk(chunkSize: Int): List[List[T]] {
188
- let results = Array.new()
189
- let result = Array.new()
190
- mutable added = 0
191
- self.each {item =>
192
- if(added < chunkSize) {
193
- added += 1
194
- } else {
195
- results.push(result.drain())
196
- added = 1
197
- }
198
- result.push(item)
199
- }
200
- if(added != 0) {
201
- results.push(result.drain())
202
- }
203
- results.drain()
204
- }
205
-
206
- toStream(cycle: Bool = False): Stream[T] {
207
- mutable index = 0
208
- Stream.new {
209
- if(index < self.size()) {
210
- let result = self.grab(index)
211
- index += 1
212
- result
213
- } elseIf {cycle && index != 0} {
214
- let result = self.grab(0)
215
- index = 1
216
- result
217
- }
218
- }
219
- }
220
-
221
- toArray(): Array[T] {
222
- Js->(array = self!->slice())?
223
- }
224
-
225
- toQueue(): Queue[T] {
226
- let queue = Queue.new()
227
- self.each {v => queue.push(v)}
228
- queue
229
- }
230
-
231
- each(body: T => Unit): Unit {
232
- mutable i = 0
233
- while {i < self.size()} {
234
- body(self!.get(i)?)
235
- i += 1
236
- }
237
- }
238
-
239
- eachWhile(body: T => Bool): Unit {
240
- mutable i = 0
241
- while {i < self.size()} {
242
- if(body(self!.get(i)?)) {
243
- i += 1
244
- } else {
245
- i = self.size()
246
- }
247
- }
248
- }
249
-
250
- all(body: T => Bool): Bool {
251
- mutable result = True
252
- self.eachWhile {x =>
253
- result = body(x)
254
- result
255
- }
256
- result
257
- }
258
-
259
- any(body: T => Bool): Bool {
260
- mutable result = False
261
- self.eachWhile {x =>
262
- result = body(x)
263
- (!result)
264
- }
265
- result
266
- }
267
-
268
- find(body: T => Bool): Option[T] {
269
- mutable result = None
270
- self.eachWhile {x =>
271
- if(body(x)) {
272
- result = Some(x)
273
- False
274
- } else {
275
- True
276
- }
277
- }
278
- result
279
- }
280
-
281
- indexWhere(body: T => Bool): Option[Int] {
282
- mutable i = -1
283
- mutable result = False
284
- self.eachWhile {x =>
285
- i += 1
286
- result = body(x)
287
- (!result)
288
- }
289
- if(result) {i}
290
- }
291
-
292
- filter(body: T => Bool): List[T] {
293
- let result = Array.new()
294
- self.each {x =>
295
- if(body(x)) {
296
- result.push(x)
297
- }
298
- }
299
- result.drain()
300
- }
301
-
302
- partition(body: T => Bool): Pair[List[T], List[T]] {
303
- Pair(self.filter(body), self.filter {!body(_)})
304
- }
305
-
306
- map[S](body: T => S): List[S] {
307
- let array = Array.new()
308
- self.each {e =>
309
- array.push(body(e))
310
- }
311
- array.drain()
312
- }
313
-
314
- flatMap[S](body: T => List[S]): List[S] {
315
- let results = Array.new()
316
- self.each {x =>
317
- results.pushList(body(x))
318
- }
319
- results.drain()
320
- }
321
-
322
- collect[R](body: T => Option[R]): List[R] {
323
- mutable result = Array.new()
324
- self.each {x =>
325
- body(x).each {result.push(_)}
326
- }
327
- result.drain()
328
- }
329
-
330
- collectFirst[R](body: T => Option[R]): Option[R] {
331
- mutable result = None
332
- self.eachWhile {x =>
333
- body(x).{
334
- | None =>
335
- True
336
- | o =>
337
- result = o
338
- False
339
- }
340
- }
341
- result
342
- }
343
-
344
- sortBy[S: Order](body: T => S): List[T] {
345
- self.sortWith {Ordering.compare(body(_), body(_))}
346
- }
347
-
348
- sortWith(ordering: (T, T) => Ordering): List[T] {
349
- let array = self.toArray()
350
- array.sortWith(ordering)
351
- array.drain()
352
- }
353
-
354
- reverse(): List[T] {
355
- 1.to(self.size()).map {i =>
356
- self.grab(self.size() - i)
357
- }
358
- }
359
-
360
- separate(separator: List[T]): List[T] {
361
- let array = Array.new()
362
- self.pairs().each {| Pair(i, x) =>
363
- if(i != 0) {
364
- array.pushList(separator)
365
- }
366
- array.push(x)
367
- }
368
- array.drain()
369
- }
370
-
371
- }
372
-
373
- extend self[T: Order]: List[T] {
374
-
375
- sort(): List[T] {
376
- self.sortWith(Ordering.compare)
377
- }
378
-
379
- toSet(): Set[T] {
380
- self.foldLeft(Set.new()) {_.add(_)}
381
- }
382
-
383
- distinct(): List[T] {
384
- mutable seen = [].toSet()
385
- self.filter {
386
- | item {!seen.contains(item)} =>
387
- seen = seen.add(item)
388
- True
389
- | _ =>
390
- False
391
- }
392
- }
393
-
394
- }
395
-
396
- extend self[T]: List[List[T]] {
397
-
398
- flatten(): List[T] {
399
- let result = Array.new()
400
- self.each {xs =>
401
- result.pushList(xs)
402
- }
403
- result.drain()
404
- }
405
-
406
- }
407
-
408
- extend self[K: Order, V]: List[Pair[K, V]] {
409
-
410
- toMap(): Map[K, V] {
411
- self.foldLeft(Map.new()) {| map, Pair(key, value) => map.add(key, value)}
412
- }
413
-
414
- group(): Map[K, List[V]] {
415
- mutable map = Map.new[K, Array[V]]()
416
- self.each {| Pair(k, v) => map = map.push(k, v)}
417
- map.mapValues {_, v => v.drain()}
418
- }
419
-
420
- }
421
-
422
- extend self[K, V]: List[Pair[K, V]] {
423
-
424
- unzip(): Pair[List[K], List[V]] {
425
- let first = Array.new()
426
- let second = Array.new()
427
- self.each {| Pair(x, y) =>
428
- first.push(x)
429
- second.push(y)
430
- }
431
- Pair(first.drain(), second.drain())
432
- }
433
-
434
- }
435
-
436
- extend self: List[String] {
437
-
438
- join(separator: String = ""): String {
439
- self!->join(separator)?
440
- }
441
-
442
- }
443
-
444
- instance List[T: Show]: Show {
445
- show(value: List[T]): String {
446
- let array = Array.new()
447
- array.push("[")
448
- value.each {x =>
449
- if(array.size() > 1) {array.push(", ")}
450
- array.push(Show.show(x))
451
- }
452
- array.push("]")
453
- array.join()
454
- }
455
- }
456
-
457
- instance List[T: Equal]: Equal {
458
- equals(x: List[T], y: List[T]): Bool {
459
- if(x!.equals(y!)) {True} else:
460
- if(x.size() != y.size()) {False} else:
461
- mutable i = -1
462
- x.all {l =>
463
- i += 1
464
- l == y.grab(i)
465
- }
466
- }
467
- }
468
-
469
- instance List[T: Order]: Order {
470
- compare(x: List[T], y: List[T]): Ordering {
471
- if(x!.equals(y!)) {OrderingSame} else:
472
- let size = x.size().min(y.size())
473
- mutable i = 0
474
- mutable ordering = OrderingSame
475
- while {ordering == OrderingSame && i < size} {
476
- ordering = Ordering.compare(x.grab(i), y.grab(i))
477
- i += 1
478
- }
479
- if(ordering != OrderingSame) {ordering} else:
480
- Ordering.compare(x.size(), y.size())
481
- }
482
- }
1
+ data List[T] {}
2
+
3
+ new[T](): List[T] {
4
+ []
5
+ }
6
+
7
+ fill[T](size: Int, value: T): List[T] {
8
+ Js->Array->(size)->fill(value!)?
9
+ }
10
+
11
+ fillBy[T](size: Int, body: Int => T): List[T] {
12
+ if(Js.inAsync()) {
13
+ let array = Js->Array->(size)
14
+ 1.until(size).each {i =>
15
+ array.set(i, body(i)!)
16
+ }
17
+ array?
18
+ } else {
19
+ Js->Array->from(Js->(length = size), Js->{_, i => body(i?)})?
20
+ }
21
+ }
22
+
23
+
24
+ range(size: Int): List[Int] {
25
+ Js->Array->from(Js->(length = size), Js->{_, i => i})?
26
+ }
27
+
28
+ extend self[T]: List[T] {
29
+
30
+ addAll(that: List[T]): List[T] {
31
+ self!->concat(that!)?
32
+ }
33
+
34
+ isEmpty(): Bool {
35
+ self.size() == 0
36
+ }
37
+
38
+ size(): Int {
39
+ self!->length?
40
+ }
41
+
42
+ get(index: Int): Option[T] {
43
+ if(index >= 0 && index < self.size()) {
44
+ Some(self!.get(index)?)
45
+ } else {
46
+ None
47
+ }
48
+ }
49
+
50
+ grab(index: Int): T {
51
+ if(index < 0 || index >= self.size()) {
52
+ throw(GrabException())
53
+ }
54
+ self!.get(index)?
55
+ }
56
+
57
+ first(): Option[T] {self.get(0)}
58
+
59
+ last(): Option[T] {self.get(self.size() - 1)}
60
+
61
+ grabFirst(): T {self.grab(0)}
62
+
63
+ grabLast(): T {self.grab(self.size() - 1)}
64
+
65
+ takeFirst(count: Int = 1): List[T] {
66
+ self!->slice(0, count)?
67
+ }
68
+
69
+ takeLast(count: Int = 1): List[T] {
70
+ self!->slice(-count)?
71
+ }
72
+
73
+ dropFirst(count: Int = 1): List[T] {
74
+ self!->slice(count)?
75
+ }
76
+
77
+ dropLast(count: Int = 1): List[T] {
78
+ self!->slice(0, self.size() - count)?
79
+ }
80
+
81
+ count(body: T => Bool): Int {
82
+ mutable result = 0
83
+ mutable i = 0
84
+ while {i < self.size()} {
85
+ if(body(self.grab(i))) {result += 1}
86
+ i += 1
87
+ }
88
+ result
89
+ }
90
+
91
+ countWhile(body: T => Bool): Int {
92
+ mutable i = 0
93
+ while {i < self.size() && body(self.grab(i))} {
94
+ i += 1
95
+ }
96
+ i
97
+ }
98
+
99
+ takeWhile(body: T => Bool): List[T] {
100
+ let result = Array.new()
101
+ mutable i = 0
102
+ while {i < self.size() && body(self.grab(i))} {
103
+ result.push(self.grab(i))
104
+ i += 1
105
+ }
106
+ result.drain()
107
+ }
108
+
109
+ dropWhile(body: T => Bool): List[T] {
110
+ let result = Array.new()
111
+ mutable i = 0
112
+ while {i < self.size() && body(self.grab(i))} {
113
+ i += 1
114
+ }
115
+ while {i < self.size()} {
116
+ result.push(self.grab(i))
117
+ i += 1
118
+ }
119
+ result.drain()
120
+ }
121
+
122
+ partitionWhile(body: T => Bool): Pair[List[T], List[T]] {
123
+ let first = Array.new()
124
+ let second = Array.new()
125
+ mutable i = 0
126
+ while {i < self.size() && body(self.grab(i))} {
127
+ first.push(self.grab(i))
128
+ i += 1
129
+ }
130
+ while {i < self.size()} {
131
+ second.push(self.grab(i))
132
+ i += 1
133
+ }
134
+ Pair(first.drain(), second.drain())
135
+ }
136
+
137
+ pairs(): List[Pair[Int, T]] {
138
+ mutable i = 0
139
+ self.map {x =>
140
+ let r = Pair(i, x)
141
+ i += 1
142
+ r
143
+ }
144
+ }
145
+
146
+ slice(from: Int, until: Int): List[T] {
147
+ self.dropFirst(from).takeFirst(until - from)
148
+ }
149
+
150
+ foldLeft[R](initial: R, body: (R, T) => R): R {
151
+ mutable result = initial
152
+ self.each {x =>
153
+ result = body(result, x)
154
+ }
155
+ result
156
+ }
157
+
158
+ update(index: Int, value: T): List[T] {
159
+ self.modify(index) {_ => value}
160
+ }
161
+
162
+ modify(index: Int, body: T => T): List[T] {
163
+ if(index < 0 || index >= self.size()) {
164
+ throw(GrabException())
165
+ }
166
+ let result = self!->slice()
167
+ result.set(index, body(result.get(index)?)!)
168
+ result?
169
+ }
170
+
171
+ zip[S](that: List[S]): List[Pair[T, S]] {
172
+ if(self.size() <= that.size()) {
173
+ mutable i = -1
174
+ self.map {x =>
175
+ i += 1
176
+ Pair(x, that.grab(i))
177
+ }
178
+ } else {
179
+ mutable i = -1
180
+ that.map {y =>
181
+ i += 1
182
+ Pair(self.grab(i), y)
183
+ }
184
+ }
185
+ }
186
+
187
+ chunk(chunkSize: Int): List[List[T]] {
188
+ let results = Array.new()
189
+ let result = Array.new()
190
+ mutable added = 0
191
+ self.each {item =>
192
+ if(added < chunkSize) {
193
+ added += 1
194
+ } else {
195
+ results.push(result.drain())
196
+ added = 1
197
+ }
198
+ result.push(item)
199
+ }
200
+ if(added != 0) {
201
+ results.push(result.drain())
202
+ }
203
+ results.drain()
204
+ }
205
+
206
+ toStream(cycle: Bool = False): Stream[T] {
207
+ mutable index = 0
208
+ Stream.new {
209
+ if(index < self.size()) {
210
+ let result = self.grab(index)
211
+ index += 1
212
+ result
213
+ } elseIf {cycle && index != 0} {
214
+ let result = self.grab(0)
215
+ index = 1
216
+ result
217
+ }
218
+ }
219
+ }
220
+
221
+ toArray(): Array[T] {
222
+ Js->(array = self!->slice())?
223
+ }
224
+
225
+ toQueue(): Queue[T] {
226
+ let queue = Queue.new()
227
+ self.each {v => queue.push(v)}
228
+ queue
229
+ }
230
+
231
+ each(body: T => Unit): Unit {
232
+ mutable i = 0
233
+ while {i < self.size()} {
234
+ body(self!.get(i)?)
235
+ i += 1
236
+ }
237
+ }
238
+
239
+ eachWhile(body: T => Bool): Unit {
240
+ mutable i = 0
241
+ while {i < self.size()} {
242
+ if(body(self!.get(i)?)) {
243
+ i += 1
244
+ } else {
245
+ i = self.size()
246
+ }
247
+ }
248
+ }
249
+
250
+ all(body: T => Bool): Bool {
251
+ mutable result = True
252
+ self.eachWhile {x =>
253
+ result = body(x)
254
+ result
255
+ }
256
+ result
257
+ }
258
+
259
+ any(body: T => Bool): Bool {
260
+ mutable result = False
261
+ self.eachWhile {x =>
262
+ result = body(x)
263
+ (!result)
264
+ }
265
+ result
266
+ }
267
+
268
+ find(body: T => Bool): Option[T] {
269
+ mutable result = None
270
+ self.eachWhile {x =>
271
+ if(body(x)) {
272
+ result = Some(x)
273
+ False
274
+ } else {
275
+ True
276
+ }
277
+ }
278
+ result
279
+ }
280
+
281
+ indexWhere(body: T => Bool): Option[Int] {
282
+ mutable i = -1
283
+ mutable result = False
284
+ self.eachWhile {x =>
285
+ i += 1
286
+ result = body(x)
287
+ (!result)
288
+ }
289
+ if(result) {i}
290
+ }
291
+
292
+ filter(body: T => Bool): List[T] {
293
+ let result = Array.new()
294
+ self.each {x =>
295
+ if(body(x)) {
296
+ result.push(x)
297
+ }
298
+ }
299
+ result.drain()
300
+ }
301
+
302
+ partition(body: T => Bool): Pair[List[T], List[T]] {
303
+ Pair(self.filter(body), self.filter {!body(_)})
304
+ }
305
+
306
+ map[S](body: T => S): List[S] {
307
+ let array = Array.new()
308
+ self.each {e =>
309
+ array.push(body(e))
310
+ }
311
+ array.drain()
312
+ }
313
+
314
+ flatMap[S](body: T => List[S]): List[S] {
315
+ let results = Array.new()
316
+ self.each {x =>
317
+ results.pushList(body(x))
318
+ }
319
+ results.drain()
320
+ }
321
+
322
+ collect[R](body: T => Option[R]): List[R] {
323
+ mutable result = Array.new()
324
+ self.each {x =>
325
+ body(x).each {result.push(_)}
326
+ }
327
+ result.drain()
328
+ }
329
+
330
+ collectFirst[R](body: T => Option[R]): Option[R] {
331
+ mutable result = None
332
+ self.eachWhile {x =>
333
+ body(x).{
334
+ | None =>
335
+ True
336
+ | o =>
337
+ result = o
338
+ False
339
+ }
340
+ }
341
+ result
342
+ }
343
+
344
+ sortBy[S: Order](body: T => S): List[T] {
345
+ self.sortWith {Ordering.compare(body(_), body(_))}
346
+ }
347
+
348
+ sortWith(ordering: (T, T) => Ordering): List[T] {
349
+ let array = self.toArray()
350
+ array.sortWith(ordering)
351
+ array.drain()
352
+ }
353
+
354
+ reverse(): List[T] {
355
+ 1.to(self.size()).map {i =>
356
+ self.grab(self.size() - i)
357
+ }
358
+ }
359
+
360
+ separate(separator: List[T]): List[T] {
361
+ let array = Array.new()
362
+ self.pairs().each {| Pair(i, x) =>
363
+ if(i != 0) {
364
+ array.pushList(separator)
365
+ }
366
+ array.push(x)
367
+ }
368
+ array.drain()
369
+ }
370
+
371
+ }
372
+
373
+ extend self[T: Order]: List[T] {
374
+
375
+ sort(): List[T] {
376
+ self.sortWith(Ordering.compare)
377
+ }
378
+
379
+ toSet(): Set[T] {
380
+ self.foldLeft(Set.new()) {_.add(_)}
381
+ }
382
+
383
+ distinct(): List[T] {
384
+ mutable seen = [].toSet()
385
+ self.filter {
386
+ | item {!seen.contains(item)} =>
387
+ seen = seen.add(item)
388
+ True
389
+ | _ =>
390
+ False
391
+ }
392
+ }
393
+
394
+ }
395
+
396
+ extend self[T]: List[List[T]] {
397
+
398
+ flatten(): List[T] {
399
+ let result = Array.new()
400
+ self.each {xs =>
401
+ result.pushList(xs)
402
+ }
403
+ result.drain()
404
+ }
405
+
406
+ }
407
+
408
+ extend self[K: Order, V]: List[Pair[K, V]] {
409
+
410
+ toMap(): Map[K, V] {
411
+ self.foldLeft(Map.new()) {| map, Pair(key, value) => map.add(key, value)}
412
+ }
413
+
414
+ group(): Map[K, List[V]] {
415
+ mutable map = Map.new[K, Array[V]]()
416
+ self.each {| Pair(k, v) => map = map.push(k, v)}
417
+ map.mapValues {_, v => v.drain()}
418
+ }
419
+
420
+ }
421
+
422
+ extend self[K, V]: List[Pair[K, V]] {
423
+
424
+ unzip(): Pair[List[K], List[V]] {
425
+ let first = Array.new()
426
+ let second = Array.new()
427
+ self.each {| Pair(x, y) =>
428
+ first.push(x)
429
+ second.push(y)
430
+ }
431
+ Pair(first.drain(), second.drain())
432
+ }
433
+
434
+ }
435
+
436
+ extend self: List[String] {
437
+
438
+ join(separator: String = ""): String {
439
+ self!->join(separator)?
440
+ }
441
+
442
+ }
443
+
444
+ instance List[T: Show]: Show {
445
+ show(value: List[T]): String {
446
+ let array = Array.new()
447
+ array.push("[")
448
+ value.each {x =>
449
+ if(array.size() > 1) {array.push(", ")}
450
+ array.push(Show.show(x))
451
+ }
452
+ array.push("]")
453
+ array.join()
454
+ }
455
+ }
456
+
457
+ instance List[T: Equal]: Equal {
458
+ equals(x: List[T], y: List[T]): Bool {
459
+ if(x!.equals(y!)) {True} else:
460
+ if(x.size() != y.size()) {False} else:
461
+ mutable i = -1
462
+ x.all {l =>
463
+ i += 1
464
+ l == y.grab(i)
465
+ }
466
+ }
467
+ }
468
+
469
+ instance List[T: Order]: Order {
470
+ compare(x: List[T], y: List[T]): Ordering {
471
+ if(x!.equals(y!)) {OrderingSame} else:
472
+ let size = x.size().min(y.size())
473
+ mutable i = 0
474
+ mutable ordering = OrderingSame
475
+ while {ordering == OrderingSame && i < size} {
476
+ ordering = Ordering.compare(x.grab(i), y.grab(i))
477
+ i += 1
478
+ }
479
+ if(ordering != OrderingSame) {ordering} else:
480
+ Ordering.compare(x.size(), y.size())
481
+ }
482
+ }