firefly-compiler 0.5.35 → 0.5.37

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