firefly-compiler 0.4.18 → 0.4.20
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/compiler/Builder.ff +1 -1
- package/compiler/Compiler.ff +6 -5
- package/compiler/Inference.ff +31 -19
- package/compiler/JsEmitter.ff +98 -71
- package/compiler/JsImporter.ff +1 -1
- package/compiler/LspHook.ff +17 -5
- package/compiler/Main.ff +6 -6
- package/compiler/Parser.ff +50 -52
- package/compiler/Patterns.ff +2 -0
- package/compiler/Syntax.ff +1 -1
- package/compiler/Tokenizer.ff +2 -2
- package/compiler/Workspace.ff +2 -2
- package/core/Array.ff +135 -294
- package/core/Buffer.ff +3 -3
- package/core/BuildSystem.ff +1 -1
- package/core/Equal.ff +36 -52
- package/core/HttpClient.ff +1 -1
- package/core/IntMap.ff +14 -18
- package/core/JsSystem.ff +1 -1
- package/core/JsValue.ff +6 -12
- package/core/Json.ff +21 -30
- package/core/List.ff +281 -312
- package/core/Map.ff +4 -8
- package/core/NodeSystem.ff +2 -2
- package/core/Option.ff +0 -4
- package/core/Ordering.ff +10 -6
- package/core/Pair.ff +0 -4
- package/core/Random.ff +12 -26
- package/core/RbMap.ff +216 -216
- package/core/Serializable.ff +9 -18
- package/core/Set.ff +0 -1
- package/core/SourceLocation.ff +1 -1
- package/core/Stream.ff +10 -14
- package/core/String.ff +24 -6
- package/core/StringMap.ff +15 -19
- package/guide/Main.ff +20 -2
- package/lsp/CompletionHandler.ff +18 -18
- package/lsp/Handler.ff +45 -34
- package/lsp/HoverHandler.ff +2 -2
- package/lsp/LanguageServer.ff +2 -2
- package/lsp/SignatureHelpHandler.ff +1 -1
- package/lsp/SymbolHandler.ff +19 -5
- package/lux/Lux.ff +3 -3
- package/output/js/ff/compiler/Builder.mjs +19 -21
- package/output/js/ff/compiler/Compiler.mjs +18 -20
- package/output/js/ff/compiler/Dependencies.mjs +8 -10
- package/output/js/ff/compiler/Deriver.mjs +234 -236
- package/output/js/ff/compiler/Dictionaries.mjs +6 -8
- package/output/js/ff/compiler/Environment.mjs +42 -44
- package/output/js/ff/compiler/Inference.mjs +346 -304
- package/output/js/ff/compiler/JsEmitter.mjs +907 -833
- package/output/js/ff/compiler/JsImporter.mjs +0 -2
- package/output/js/ff/compiler/LspHook.mjs +872 -51
- package/output/js/ff/compiler/Main.mjs +109 -111
- package/output/js/ff/compiler/Parser.mjs +427 -441
- package/output/js/ff/compiler/Patterns.mjs +64 -50
- package/output/js/ff/compiler/Resolver.mjs +36 -38
- package/output/js/ff/compiler/Substitution.mjs +4 -6
- package/output/js/ff/compiler/Syntax.mjs +160 -162
- package/output/js/ff/compiler/Token.mjs +52 -54
- package/output/js/ff/compiler/Tokenizer.mjs +16 -18
- package/output/js/ff/compiler/Unification.mjs +24 -26
- package/output/js/ff/compiler/Wildcards.mjs +0 -2
- package/output/js/ff/compiler/Workspace.mjs +18 -20
- package/output/js/ff/core/Any.mjs +0 -2
- package/output/js/ff/core/Array.mjs +216 -613
- package/output/js/ff/core/AssetSystem.mjs +2 -4
- package/output/js/ff/core/Atomic.mjs +0 -2
- package/output/js/ff/core/Bool.mjs +0 -2
- package/output/js/ff/core/Box.mjs +0 -2
- package/output/js/ff/core/BrowserSystem.mjs +0 -2
- package/output/js/ff/core/Buffer.mjs +0 -2
- package/output/js/ff/core/BuildSystem.mjs +12 -14
- package/output/js/ff/core/Channel.mjs +0 -2
- package/output/js/ff/core/Char.mjs +0 -2
- package/output/js/ff/core/Core.mjs +0 -2
- package/output/js/ff/core/Duration.mjs +0 -2
- package/output/js/ff/core/Equal.mjs +0 -22
- package/output/js/ff/core/Error.mjs +0 -2
- package/output/js/ff/core/FileHandle.mjs +0 -2
- package/output/js/ff/core/Float.mjs +0 -2
- package/output/js/ff/core/HttpClient.mjs +2 -4
- package/output/js/ff/core/Instant.mjs +0 -2
- package/output/js/ff/core/Int.mjs +8 -10
- package/output/js/ff/core/IntMap.mjs +32 -42
- package/output/js/ff/core/JsSystem.mjs +1 -3
- package/output/js/ff/core/JsValue.mjs +5 -12
- package/output/js/ff/core/Json.mjs +25 -58
- package/output/js/ff/core/List.mjs +648 -1989
- package/output/js/ff/core/Lock.mjs +0 -2
- package/output/js/ff/core/Log.mjs +0 -2
- package/output/js/ff/core/Map.mjs +10 -20
- package/output/js/ff/core/NodeSystem.mjs +6 -8
- package/output/js/ff/core/Nothing.mjs +0 -2
- package/output/js/ff/core/Option.mjs +8 -18
- package/output/js/ff/core/Ordering.mjs +20 -98
- package/output/js/ff/core/Pair.mjs +6 -16
- package/output/js/ff/core/Path.mjs +12 -14
- package/output/js/ff/core/Random.mjs +24 -54
- package/output/js/ff/core/RbMap.mjs +54 -56
- package/output/js/ff/core/Serializable.mjs +19 -36
- package/output/js/ff/core/Set.mjs +0 -14
- package/output/js/ff/core/Show.mjs +0 -2
- package/output/js/ff/core/SourceLocation.mjs +0 -2
- package/output/js/ff/core/Stream.mjs +34 -44
- package/output/js/ff/core/String.mjs +31 -5
- package/output/js/ff/core/StringMap.mjs +32 -42
- package/output/js/ff/core/Task.mjs +0 -2
- package/output/js/ff/core/Try.mjs +0 -2
- package/output/js/ff/core/Unit.mjs +0 -2
- package/package.json +1 -1
- package/vscode/client/src/extension.ts +30 -2
- package/vscode/package.json +17 -1
- package/webserver/WebServer.ff +8 -8
- package/core/Stack.ff +0 -263
- package/output/js/ff/core/Stack.mjs +0 -603
package/core/List.ff
CHANGED
|
@@ -1,108 +1,77 @@
|
|
|
1
|
-
data List[T] {
|
|
2
|
-
Empty
|
|
3
|
-
Link(head: T, tail: List[T])
|
|
4
|
-
}
|
|
1
|
+
data List[T] {}
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
empty[T](): List[T]
|
|
7
4
|
target js sync """
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
return [];
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
fill[T](size: Int, value: T): List[T]
|
|
9
|
+
target js sync """
|
|
10
|
+
return new Array(size_).fill(value_);
|
|
13
11
|
"""
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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));
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
return array;
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
range(size: Int): List[Int]
|
|
26
|
+
target js sync """
|
|
27
|
+
return Array.from({length: size_}, (_, i) => i);
|
|
28
|
+
"""
|
|
24
29
|
|
|
25
30
|
extend self[T]: List[T] {
|
|
26
31
|
|
|
27
|
-
addAll(
|
|
28
|
-
|
|
29
|
-
|
|
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"
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
size(): Int
|
|
39
|
+
target js sync "return self_.length"
|
|
40
|
+
|
|
41
|
+
get(index: Int): Option[T]
|
|
32
42
|
target js sync """
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
result.push(current.head_);
|
|
37
|
-
current = current.tail_;
|
|
38
|
-
}
|
|
39
|
-
return {array: result};
|
|
43
|
+
return index_ >= 0 && index_ < self_.length
|
|
44
|
+
? ff_core_Option.Some(self_[index_])
|
|
45
|
+
: ff_core_Option.None()
|
|
40
46
|
"""
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
grab(index: Int): T {
|
|
47
|
-
function go(list: List[T], i: Int): T {
|
|
48
|
-
list.{
|
|
49
|
-
| [] => Try.internalThrowGrabException()
|
|
50
|
-
| [head, ...] {i == 0} => head
|
|
51
|
-
| [_, ...tail] => tailcall go(tail, i - 1)
|
|
48
|
+
grab(index: Int): T
|
|
49
|
+
target js sync """
|
|
50
|
+
if(index_ < 0 || index_ >= self_.length) {
|
|
51
|
+
ff_core_Try.internalThrowGrabException_()
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
53
|
+
return self_[index_]
|
|
54
|
+
"""
|
|
56
55
|
|
|
57
|
-
first(): Option[T] {
|
|
58
|
-
self.{
|
|
59
|
-
| [] => None
|
|
60
|
-
| [head, ...] => Some(head)
|
|
61
|
-
}
|
|
62
|
-
}
|
|
56
|
+
first(): Option[T] {self.get(0)}
|
|
63
57
|
|
|
64
|
-
last(): Option[T] {
|
|
65
|
-
self.{
|
|
66
|
-
| [] => None
|
|
67
|
-
| [head] => Some(head)
|
|
68
|
-
| [_, ...tail] => tailcall tail.last()
|
|
69
|
-
}
|
|
70
|
-
}
|
|
58
|
+
last(): Option[T] {self.get(self.size() - 1)}
|
|
71
59
|
|
|
72
|
-
grabFirst(): T {
|
|
73
|
-
self.first().else {Try.internalThrowGrabException()}
|
|
74
|
-
}
|
|
60
|
+
grabFirst(): T {self.grab(0)}
|
|
75
61
|
|
|
76
|
-
grabLast(): T {
|
|
77
|
-
self.last().else {Try.internalThrowGrabException()}
|
|
78
|
-
}
|
|
62
|
+
grabLast(): T {self.grab(self.size() - 1)}
|
|
79
63
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
| _ {count <= 0} => self
|
|
83
|
-
| [] => self
|
|
84
|
-
| [_, ...tail] => tailcall tail.dropFirst(count - 1)
|
|
85
|
-
}
|
|
86
|
-
}
|
|
64
|
+
takeFirst(count: Int = 1): List[T]
|
|
65
|
+
target js sync "return self_.slice(0, count_)"
|
|
87
66
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
67
|
+
takeLast(count: Int = 1): List[T]
|
|
68
|
+
target js sync "return self_.slice(-count_)"
|
|
91
69
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
list.{
|
|
95
|
-
| _ {count <= 0} => result.reverse()
|
|
96
|
-
| [] => result.reverse()
|
|
97
|
-
| [head, ...tail] => tailcall go(tail, count - 1, [head, ...result])
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
go(self, count, [])
|
|
101
|
-
}
|
|
70
|
+
dropFirst(count: Int = 1): List[T]
|
|
71
|
+
target js sync "return self_.slice(count_)"
|
|
102
72
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
73
|
+
dropLast(count: Int = 1): List[T]
|
|
74
|
+
target js sync "return self_.slice(0, self_.length - count_)"
|
|
106
75
|
|
|
107
76
|
pairs(): List[Pair[Int, T]] {
|
|
108
77
|
mutable i = 0
|
|
@@ -112,244 +81,220 @@ extend self[T]: List[T] {
|
|
|
112
81
|
r
|
|
113
82
|
}
|
|
114
83
|
}
|
|
115
|
-
|
|
84
|
+
|
|
116
85
|
slice(from: Int, until: Int): List[T] {
|
|
117
86
|
self.dropFirst(from).takeFirst(until - from)
|
|
118
87
|
}
|
|
88
|
+
|
|
89
|
+
foldLeft[R](initial: R, body: (R, T) => R): R {
|
|
90
|
+
mutable result = initial
|
|
91
|
+
self.each {x =>
|
|
92
|
+
result = body(result, x)
|
|
93
|
+
}
|
|
94
|
+
result
|
|
95
|
+
}
|
|
119
96
|
|
|
120
|
-
|
|
121
|
-
self.{
|
|
122
|
-
|
|
123
|
-
|
|
97
|
+
update(index: Int, value: T): List[T] {
|
|
98
|
+
self.modify(index) {_ => value}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
modify(index: Int, body: T => T): List[T]
|
|
102
|
+
target js sync """
|
|
103
|
+
if(index_ < 0 || index_ >= self_.length) {
|
|
104
|
+
ff_core_Try.internalThrowGrabException_()
|
|
105
|
+
}
|
|
106
|
+
let result = self_.slice();
|
|
107
|
+
result[index_] = body_(result[index_]);
|
|
108
|
+
return result;
|
|
109
|
+
"""
|
|
110
|
+
target js async """
|
|
111
|
+
if(index_ < 0 || index_ >= self_.length) {
|
|
112
|
+
ff_core_Try.internalThrowGrabException_()
|
|
113
|
+
}
|
|
114
|
+
let result = self_.slice();
|
|
115
|
+
result[index_] = await body_(result[index_], $task);
|
|
116
|
+
return result;
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
zip[S](that: List[S]): List[Pair[T, S]] {
|
|
120
|
+
if(self.size() <= that.size()) {
|
|
121
|
+
mutable i = -1
|
|
122
|
+
self.map {x =>
|
|
123
|
+
i += 1
|
|
124
|
+
Pair(x, that.grab(i))
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
mutable i = -1
|
|
128
|
+
that.map {y =>
|
|
129
|
+
i += 1
|
|
130
|
+
Pair(self.grab(i), y)
|
|
131
|
+
}
|
|
124
132
|
}
|
|
125
133
|
}
|
|
126
134
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
135
|
+
chunk(chunkSize: Int): List[List[T]] {
|
|
136
|
+
let results = Array.make()
|
|
137
|
+
let result = Array.make()
|
|
138
|
+
mutable added = 0
|
|
139
|
+
self.each {item =>
|
|
140
|
+
if(added < chunkSize) {
|
|
141
|
+
added += 1
|
|
142
|
+
} else {
|
|
143
|
+
results.push(result.drain())
|
|
144
|
+
added = 1
|
|
132
145
|
}
|
|
146
|
+
result.push(item)
|
|
147
|
+
}
|
|
148
|
+
if(added != 0) {
|
|
149
|
+
results.push(result.drain())
|
|
133
150
|
}
|
|
134
|
-
|
|
151
|
+
results.drain()
|
|
135
152
|
}
|
|
136
153
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
154
|
+
toStream(cycle: Bool = False): Stream[T] {
|
|
155
|
+
mutable index = 0
|
|
156
|
+
Stream.make {
|
|
157
|
+
if(index < self.size()) {
|
|
158
|
+
let result = self.grab(index)
|
|
159
|
+
index += 1
|
|
160
|
+
result
|
|
161
|
+
} elseIf {cycle && index != 0} {
|
|
162
|
+
let result = self.grab(0)
|
|
163
|
+
index = 1
|
|
164
|
+
result
|
|
165
|
+
}
|
|
143
166
|
}
|
|
144
167
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
168
|
+
|
|
169
|
+
toArray(): Array[T]
|
|
170
|
+
target js sync "return {array: self_.slice()}"
|
|
171
|
+
|
|
172
|
+
each(body: T => Unit): Unit
|
|
173
|
+
target js sync """
|
|
174
|
+
return self_.forEach(body_);
|
|
175
|
+
"""
|
|
176
|
+
target js async """
|
|
177
|
+
for(let i = 0; i < self_.length; i++) {
|
|
178
|
+
await body_(self_[i], $task)
|
|
179
|
+
}
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
eachWhile(body: T => Bool): Unit
|
|
183
|
+
target js sync "for(const value of self_) if(!body_(value)) break"
|
|
184
|
+
target js async "for(const value of self_) if(!await body_(value, $task)) break"
|
|
149
185
|
|
|
150
186
|
all(body: T => Bool): Bool {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
187
|
+
mutable result = True
|
|
188
|
+
self.eachWhile {x =>
|
|
189
|
+
result = result && body(x)
|
|
190
|
+
result
|
|
155
191
|
}
|
|
192
|
+
result
|
|
156
193
|
}
|
|
157
194
|
|
|
158
195
|
any(body: T => Bool): Bool {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
196
|
+
mutable result = False
|
|
197
|
+
self.eachWhile {x =>
|
|
198
|
+
result = result || body(x)
|
|
199
|
+
(!result)
|
|
163
200
|
}
|
|
201
|
+
result
|
|
164
202
|
}
|
|
165
|
-
|
|
203
|
+
|
|
166
204
|
find(body: T => Bool): Option[T] {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
205
|
+
mutable result = None
|
|
206
|
+
self.eachWhile {x =>
|
|
207
|
+
if(body(x)) {
|
|
208
|
+
result = Some(x)
|
|
209
|
+
False
|
|
210
|
+
} else {
|
|
211
|
+
True
|
|
212
|
+
}
|
|
171
213
|
}
|
|
214
|
+
result
|
|
172
215
|
}
|
|
173
216
|
|
|
174
217
|
filter(body: T => Bool): List[T] {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
| [head, ...tail] {body(head)} =>
|
|
180
|
-
tailcall go(tail, [head, ...result])
|
|
181
|
-
| [_, ...tail] =>
|
|
182
|
-
tailcall go(tail, result)
|
|
218
|
+
let result = Array.make()
|
|
219
|
+
self.each {x =>
|
|
220
|
+
if(body(x)) {
|
|
221
|
+
result.push(x)
|
|
183
222
|
}
|
|
184
223
|
}
|
|
185
|
-
|
|
224
|
+
result.drain()
|
|
186
225
|
}
|
|
187
|
-
|
|
226
|
+
|
|
188
227
|
partition(body: T => Bool): Pair[List[T], List[T]] {
|
|
189
228
|
Pair(self.filter(body), self.filter {!body(_)})
|
|
190
229
|
}
|
|
191
230
|
|
|
192
|
-
map[
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
go(self, [])
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
flatMap[R](body: T => List[R]): List[R] {
|
|
205
|
-
function go(list: List[T], result: List[List[R]]): List[R] {
|
|
206
|
-
list.{
|
|
207
|
-
| [] =>
|
|
208
|
-
result.reverse().flatten()
|
|
209
|
-
| [head, ...tail] =>
|
|
210
|
-
tailcall go(tail, [body(head), ...result])
|
|
231
|
+
map[S](body: T => S): List[S]
|
|
232
|
+
target js sync """
|
|
233
|
+
return self_.map(body_)
|
|
234
|
+
"""
|
|
235
|
+
target js async """
|
|
236
|
+
let result = [];
|
|
237
|
+
for(let i = 0; i < self_.length; i++) {
|
|
238
|
+
result.push(await body_(self_[i], $task));
|
|
211
239
|
}
|
|
240
|
+
return result;
|
|
241
|
+
"""
|
|
242
|
+
|
|
243
|
+
flatMap[S](body: T => List[S]): List[S] {
|
|
244
|
+
let results = Array.make()
|
|
245
|
+
self.each {x =>
|
|
246
|
+
results.pushList(body(x))
|
|
212
247
|
}
|
|
213
|
-
|
|
248
|
+
results.drain()
|
|
214
249
|
}
|
|
215
|
-
|
|
250
|
+
|
|
216
251
|
collect[R](body: T => Option[R]): List[R] {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
collectFirst[R](body: T => Option[R]): Option[R] {
|
|
221
|
-
self.{
|
|
222
|
-
| [] =>
|
|
223
|
-
None
|
|
224
|
-
| [head, ...tail] =>
|
|
225
|
-
body(head).{
|
|
226
|
-
| None => tailcall tail.collectFirst(body)
|
|
227
|
-
| Some(value) => Some(value)
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
foldLeft[R](initial: R, body: (R, T) => R): R {
|
|
233
|
-
function go(state: R, list: List[T]): R {
|
|
234
|
-
list.{
|
|
235
|
-
| [] =>
|
|
236
|
-
state
|
|
237
|
-
| [head, ...tail] =>
|
|
238
|
-
tailcall go(body(state, head), tail)
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
go(initial, self)
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
update(index: Int, value: T): List[T] {
|
|
245
|
-
function go(list: List[T], i: Int, result: List[T]): List[T] {
|
|
246
|
-
list.{
|
|
247
|
-
| [] =>
|
|
248
|
-
result.reverse()
|
|
249
|
-
| [head, ...tail] {i == 0} =>
|
|
250
|
-
tailcall go(tail, i - 1, [value, ...result])
|
|
251
|
-
| [head, ...tail] =>
|
|
252
|
-
tailcall go(tail, i - 1, [head, ...result])
|
|
253
|
-
}
|
|
252
|
+
mutable result = Array.make()
|
|
253
|
+
self.each {x =>
|
|
254
|
+
body(x).each {result.push(_)}
|
|
254
255
|
}
|
|
255
|
-
|
|
256
|
+
result.drain()
|
|
256
257
|
}
|
|
257
258
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
go(self, index, [])
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
zip[S](that: List[S]): List[Pair[T, S]] {
|
|
273
|
-
function go(list1: List[T], list2: List[S], result: List[Pair[T, S]]): List[Pair[T, S]] {
|
|
274
|
-
Pair(list1, list2).{
|
|
275
|
-
| Pair([x, ...xs], [y, ...ys]) =>
|
|
276
|
-
tailcall go(xs, ys, [Pair(x, y), ...result])
|
|
277
|
-
| _ =>
|
|
278
|
-
result.reverse()
|
|
259
|
+
collectFirst[R](body: T => Option[R]): Option[R] {
|
|
260
|
+
mutable result = None
|
|
261
|
+
self.eachWhile {x =>
|
|
262
|
+
body(x).{
|
|
263
|
+
| None =>
|
|
264
|
+
True
|
|
265
|
+
| o =>
|
|
266
|
+
result = o
|
|
267
|
+
False
|
|
279
268
|
}
|
|
280
269
|
}
|
|
281
|
-
|
|
270
|
+
result
|
|
282
271
|
}
|
|
283
272
|
|
|
284
|
-
sortBy[
|
|
285
|
-
|
|
286
|
-
let stack = self.toStack()
|
|
287
|
-
stack.sortBy(body)
|
|
288
|
-
stack.toList()
|
|
273
|
+
sortBy[S: Order](body: T => S): List[T] {
|
|
274
|
+
self.sortWith {Ordering.compare(body(_), body(_))}
|
|
289
275
|
}
|
|
290
276
|
|
|
291
|
-
sortWith(
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
stack.toList()
|
|
277
|
+
sortWith(ordering: (T, T) => Ordering): List[T] {
|
|
278
|
+
let array = self.toArray()
|
|
279
|
+
array.sortWith(ordering)
|
|
280
|
+
array.drain()
|
|
296
281
|
}
|
|
297
|
-
|
|
282
|
+
|
|
298
283
|
reverse(): List[T] {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
| [] =>
|
|
302
|
-
result
|
|
303
|
-
| [head, ...tail] =>
|
|
304
|
-
tailcall go(tail, [head, ...result])
|
|
305
|
-
}
|
|
284
|
+
1.to(self.size()).map {i =>
|
|
285
|
+
self.grab(self.size() - i)
|
|
306
286
|
}
|
|
307
|
-
go(self, [])
|
|
308
287
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if(added < chunkSize) {
|
|
316
|
-
result = [item, ...result]
|
|
317
|
-
added += 1
|
|
318
|
-
} else {
|
|
319
|
-
results = [result.reverse(), ...results]
|
|
320
|
-
result = [item]
|
|
321
|
-
added = 1
|
|
288
|
+
|
|
289
|
+
separate(separator: List[T]): List[T] {
|
|
290
|
+
let array = Array.make()
|
|
291
|
+
self.pairs().each {| Pair(i, x) =>
|
|
292
|
+
if(i != 0) {
|
|
293
|
+
array.pushList(separator)
|
|
322
294
|
}
|
|
295
|
+
array.push(x)
|
|
323
296
|
}
|
|
324
|
-
|
|
325
|
-
results = [result.reverse(), ...results]
|
|
326
|
-
}
|
|
327
|
-
results.reverse()
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
toStream(cycle: Bool = False): Stream[T] {
|
|
331
|
-
mutable remaining = self
|
|
332
|
-
Stream(
|
|
333
|
-
next = {
|
|
334
|
-
remaining.{
|
|
335
|
-
| [head, ...tail] =>
|
|
336
|
-
remaining = tail
|
|
337
|
-
Some(head)
|
|
338
|
-
| [] {self | [head, ...tail]} {cycle} =>
|
|
339
|
-
remaining = tail
|
|
340
|
-
Some(head)
|
|
341
|
-
| [] =>
|
|
342
|
-
None
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
close = {
|
|
346
|
-
remaining = []
|
|
347
|
-
}
|
|
348
|
-
)
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
separate(separator: List[T]): List[T] {
|
|
352
|
-
self.flatMap {e => [...separator, e]}.dropFirst(separator.size())
|
|
297
|
+
array.drain()
|
|
353
298
|
}
|
|
354
299
|
|
|
355
300
|
}
|
|
@@ -357,16 +302,13 @@ extend self[T]: List[T] {
|
|
|
357
302
|
extend self[T: Order]: List[T] {
|
|
358
303
|
|
|
359
304
|
sort(): List[T] {
|
|
360
|
-
|
|
361
|
-
let stack = self.toStack()
|
|
362
|
-
stack.sort()
|
|
363
|
-
stack.toList()
|
|
305
|
+
self.sortWith(Ordering.compare)
|
|
364
306
|
}
|
|
365
|
-
|
|
307
|
+
|
|
366
308
|
toSet(): Set[T] {
|
|
367
|
-
self.foldLeft(Set.empty
|
|
309
|
+
self.foldLeft(Set.empty()) {_.add(_)}
|
|
368
310
|
}
|
|
369
|
-
|
|
311
|
+
|
|
370
312
|
distinct(): List[T] {
|
|
371
313
|
mutable seen = [].toSet()
|
|
372
314
|
self.filter {
|
|
@@ -380,65 +322,92 @@ extend self[T: Order]: List[T] {
|
|
|
380
322
|
|
|
381
323
|
}
|
|
382
324
|
|
|
383
|
-
extend self[T: Show]: List[T] {
|
|
384
|
-
|
|
385
|
-
show(): String {
|
|
386
|
-
Show.show(self)
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
}
|
|
390
|
-
|
|
391
325
|
extend self[T]: List[List[T]] {
|
|
392
326
|
|
|
393
327
|
flatten(): List[T] {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
}
|
|
398
|
-
function go(lists: List[List[T]], result: List[T]): List[T] {
|
|
399
|
-
lists.{
|
|
400
|
-
| [] => []
|
|
401
|
-
| [as] => finish(as, result)
|
|
402
|
-
| [[], ...aas] => tailcall go(aas, result)
|
|
403
|
-
| [[a, ...as], ...aas] => tailcall go([as, ...aas], [a, ...result])
|
|
404
|
-
}
|
|
328
|
+
let result = Array.make()
|
|
329
|
+
self.each {xs =>
|
|
330
|
+
result.pushList(xs)
|
|
405
331
|
}
|
|
406
|
-
|
|
332
|
+
result.drain()
|
|
407
333
|
}
|
|
408
334
|
|
|
409
335
|
}
|
|
410
336
|
|
|
411
337
|
extend self[K: Order, V]: List[Pair[K, V]] {
|
|
412
|
-
|
|
338
|
+
|
|
413
339
|
toMap(): Map[K, V] {
|
|
414
|
-
self.foldLeft(Map.empty
|
|
340
|
+
self.foldLeft(Map.empty()) {| map, Pair(key, value) => map.add(key, value)}
|
|
415
341
|
}
|
|
416
|
-
|
|
342
|
+
|
|
417
343
|
group(): Map[K, List[V]] {
|
|
418
|
-
|
|
419
|
-
self.
|
|
344
|
+
mutable map = Map.empty[K, Array[V]]()
|
|
345
|
+
self.each {| Pair(k, v) => map = map.push(k, v)}
|
|
346
|
+
map.mapValues {_, v => v.drain()}
|
|
420
347
|
}
|
|
421
|
-
|
|
348
|
+
|
|
422
349
|
}
|
|
423
350
|
|
|
424
351
|
extend self[K, V]: List[Pair[K, V]] {
|
|
425
352
|
|
|
426
353
|
unzip(): Pair[List[K], List[V]] {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
tailcall go(tail, [k, ...ks], [v, ...vs])
|
|
433
|
-
}
|
|
354
|
+
let first = Array.make()
|
|
355
|
+
let second = Array.make()
|
|
356
|
+
self.each {| Pair(x, y) =>
|
|
357
|
+
first.push(x)
|
|
358
|
+
second.push(y)
|
|
434
359
|
}
|
|
435
|
-
|
|
360
|
+
Pair(first.drain(), second.drain())
|
|
436
361
|
}
|
|
437
362
|
|
|
438
363
|
}
|
|
439
364
|
|
|
440
365
|
extend self: List[String] {
|
|
441
366
|
|
|
442
|
-
join(separator: String = ""): String
|
|
367
|
+
join(separator: String = ""): String
|
|
368
|
+
target js sync "return self_.join(separator_)"
|
|
443
369
|
|
|
444
370
|
}
|
|
371
|
+
|
|
372
|
+
instance List[T: Show]: Show {
|
|
373
|
+
show(value: List[T]): String {
|
|
374
|
+
let array = Array.make()
|
|
375
|
+
array.push("[")
|
|
376
|
+
value.each {x =>
|
|
377
|
+
if(array.size() > 1) {array.push(", ")}
|
|
378
|
+
array.push(Show.show(x))
|
|
379
|
+
}
|
|
380
|
+
array.push("]")
|
|
381
|
+
array.join()
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
instance List[T: Equal]: Equal {
|
|
386
|
+
equals(x: List[T], y: List[T]): Bool {
|
|
387
|
+
if(internalSame(x, y)) {True} else:
|
|
388
|
+
if(x.size() != y.size()) {False} else:
|
|
389
|
+
mutable i = -1
|
|
390
|
+
x.all {l =>
|
|
391
|
+
i += 1
|
|
392
|
+
l == y.grab(i)
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
instance List[T: Order]: Order {
|
|
398
|
+
compare(x: List[T], y: List[T]): Ordering {
|
|
399
|
+
if(internalSame(x, y)) {OrderingSame} else:
|
|
400
|
+
let size = x.size().min(y.size())
|
|
401
|
+
mutable i = 0
|
|
402
|
+
mutable ordering = OrderingSame
|
|
403
|
+
while {ordering == OrderingSame && i < size} {
|
|
404
|
+
ordering = Ordering.compare(x.grab(i), y.grab(i))
|
|
405
|
+
i += 1
|
|
406
|
+
}
|
|
407
|
+
if(ordering != OrderingSame) {ordering} else:
|
|
408
|
+
Ordering.compare(x.size(), y.size())
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
internalSame[T](left: List[T], right: List[T]): Bool
|
|
413
|
+
target js sync "return left_ === right_"
|