firefly-compiler 0.4.4
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/.firefly-workspace +1 -0
- package/.vscode/settings.json +5 -0
- package/LICENSE.txt +21 -0
- package/README.md +96 -0
- package/bin/firefly.mjs +2 -0
- package/compiler/.firefly/package.ff +1 -0
- package/compiler/Builder.ff +218 -0
- package/compiler/Compiler.ff +241 -0
- package/compiler/Dependencies.ff +179 -0
- package/compiler/Deriver.ff +647 -0
- package/compiler/Dictionaries.ff +205 -0
- package/compiler/Environment.ff +166 -0
- package/compiler/Inference.ff +1117 -0
- package/compiler/JsEmitter.ff +861 -0
- package/compiler/JsImporter.ff +56 -0
- package/compiler/LspHook.ff +188 -0
- package/compiler/Main.ff +237 -0
- package/compiler/Parser.ff +1383 -0
- package/compiler/Patterns.ff +111 -0
- package/compiler/Resolver.ff +620 -0
- package/compiler/Substitution.ff +178 -0
- package/compiler/Syntax.ff +299 -0
- package/compiler/Token.ff +180 -0
- package/compiler/Tokenizer.ff +278 -0
- package/compiler/Unification.ff +220 -0
- package/compiler/Wildcards.ff +50 -0
- package/compiler/Workspace.ff +88 -0
- package/core/.firefly/package.ff +2 -0
- package/core/Any.ff +30 -0
- package/core/Array.ff +249 -0
- package/core/AssetSystem.ff +61 -0
- package/core/Atomic.ff +64 -0
- package/core/Bool.ff +13 -0
- package/core/BrowserSystem.ff +14 -0
- package/core/Buffer.ff +211 -0
- package/core/BuildSystem.ff +144 -0
- package/core/Channel.ff +131 -0
- package/core/Char.ff +18 -0
- package/core/Core.ff +58 -0
- package/core/Duration.ff +15 -0
- package/core/Equal.ff +52 -0
- package/core/Error.ff +20 -0
- package/core/FileHandle.ff +41 -0
- package/core/Float.ff +41 -0
- package/core/HttpClient.ff +84 -0
- package/core/Instant.ff +9 -0
- package/core/Int.ff +61 -0
- package/core/IntMap.ff +85 -0
- package/core/JsSystem.ff +66 -0
- package/core/JsValue.ff +240 -0
- package/core/List.ff +440 -0
- package/core/Lock.ff +144 -0
- package/core/Log.ff +24 -0
- package/core/Map.ff +126 -0
- package/core/NodeSystem.ff +88 -0
- package/core/Nothing.ff +1 -0
- package/core/Option.ff +133 -0
- package/core/Ordering.ff +157 -0
- package/core/Pair.ff +55 -0
- package/core/Path.ff +393 -0
- package/core/RbMap.ff +216 -0
- package/core/Serializable.ff +173 -0
- package/core/Set.ff +38 -0
- package/core/Show.ff +43 -0
- package/core/Stack.ff +263 -0
- package/core/Stream.ff +406 -0
- package/core/String.ff +175 -0
- package/core/StringMap.ff +85 -0
- package/core/Task.ff +138 -0
- package/core/Try.ff +81 -0
- package/core/Unit.ff +3 -0
- package/experimental/random/AltGeneric.ff +44 -0
- package/experimental/random/Async.ff +68 -0
- package/experimental/random/Buffer2.ff +77 -0
- package/experimental/random/Cat.ff +12 -0
- package/experimental/random/Dictionary.ff +52 -0
- package/experimental/random/Example.ff +46 -0
- package/experimental/random/Generic.ff +102 -0
- package/experimental/random/HappyEyeballs.ff +40 -0
- package/experimental/random/HashMap.ff +72 -0
- package/experimental/random/IfElseUnit.ff +9 -0
- package/experimental/random/InputOutput.ff +23 -0
- package/experimental/random/ListVsArray.ff +45 -0
- package/experimental/random/Main.ff +44 -0
- package/experimental/random/MapTest.ff +67 -0
- package/experimental/random/OldTaskSystem.ff +210 -0
- package/experimental/random/PatternTest.ff +39 -0
- package/experimental/random/Patterns.ff +226 -0
- package/experimental/random/ReadBytesTest.ff +10 -0
- package/experimental/random/RunLength.ff +65 -0
- package/experimental/random/Scrape.ff +51 -0
- package/experimental/random/Serialization.ff +217 -0
- package/experimental/random/SerializationTest.ff +46 -0
- package/experimental/random/Serializer.ff +36 -0
- package/experimental/random/StdInOutErr.ff +4 -0
- package/experimental/random/Symbols.ff +74 -0
- package/experimental/random/Tag.ff +49 -0
- package/experimental/random/Tensor.ff +52 -0
- package/experimental/random/Try.ff +56 -0
- package/experimental/random/Tsv.ff +9 -0
- package/experimental/random/TypesAreModules.ff +87 -0
- package/experimental/random/blueprints/Blueprint.ff +52 -0
- package/experimental/random/blueprints/Main.ff +11 -0
- package/experimental/random/blueprints/Pretty.ff +58 -0
- package/experimental/random/blueprints/User.ff +64 -0
- package/experimental/random/blueprintsystem/BlueprintSystem.ff +48 -0
- package/experimental/random/blueprintsystem/Deserialize.ff +53 -0
- package/experimental/random/blueprintsystem/ReadJs.ff +13 -0
- package/experimental/random/blueprintsystem/User.ff +2 -0
- package/experimental/random/kahrs/Kahrs.ff +112 -0
- package/experimental/random/kahrs/TestKahrs.ff +22 -0
- package/experimental/random/kahrs/TestMap.ff +18 -0
- package/experimental/random/streaming/Gzip.ff +3 -0
- package/experimental/random/streaming/Main.ff +34 -0
- package/experimental/random/streaming/S3Bucket.ff +11 -0
- package/experimental/random/streaming/Tar.ff +5 -0
- package/experimental/rhymeapp/Main.ff +81 -0
- package/experimental/rhymeapp/index.html +14 -0
- package/firefly.sh +5 -0
- package/fireflysite/Main.ff +13 -0
- package/httpserver/.firefly/package.ff +1 -0
- package/httpserver/HttpServer.ff +184 -0
- package/lsp/.firefly/package.ff +1 -0
- package/lsp/CompletionHandler.ff +814 -0
- package/lsp/Handler.ff +551 -0
- package/lsp/HoverHandler.ff +82 -0
- package/lsp/LanguageServer.ff +229 -0
- package/lsp/SignatureHelpHandler.ff +55 -0
- package/lsp/SymbolHandler.ff +167 -0
- package/output/js/ff/compiler/Builder.mjs +483 -0
- package/output/js/ff/compiler/Compiler.mjs +410 -0
- package/output/js/ff/compiler/Dependencies.mjs +388 -0
- package/output/js/ff/compiler/Deriver.mjs +1166 -0
- package/output/js/ff/compiler/Dictionaries.mjs +1305 -0
- package/output/js/ff/compiler/Environment.mjs +1005 -0
- package/output/js/ff/compiler/Inference.mjs +4264 -0
- package/output/js/ff/compiler/JsEmitter.mjs +5353 -0
- package/output/js/ff/compiler/JsImporter.mjs +262 -0
- package/output/js/ff/compiler/LspHook.mjs +789 -0
- package/output/js/ff/compiler/Main.mjs +1695 -0
- package/output/js/ff/compiler/Parser.mjs +4004 -0
- package/output/js/ff/compiler/Patterns.mjs +923 -0
- package/output/js/ff/compiler/Resolver.mjs +2303 -0
- package/output/js/ff/compiler/Substitution.mjs +1146 -0
- package/output/js/ff/compiler/Syntax.mjs +12430 -0
- package/output/js/ff/compiler/Token.mjs +3092 -0
- package/output/js/ff/compiler/Tokenizer.mjs +589 -0
- package/output/js/ff/compiler/Unification.mjs +1748 -0
- package/output/js/ff/compiler/Wildcards.mjs +604 -0
- package/output/js/ff/compiler/Workspace.mjs +683 -0
- package/output/js/ff/core/Any.mjs +139 -0
- package/output/js/ff/core/Array.mjs +594 -0
- package/output/js/ff/core/AssetSystem.mjs +270 -0
- package/output/js/ff/core/Atomic.mjs +186 -0
- package/output/js/ff/core/Bool.mjs +141 -0
- package/output/js/ff/core/BrowserSystem.mjs +122 -0
- package/output/js/ff/core/Buffer.mjs +467 -0
- package/output/js/ff/core/BuildSystem.mjs +320 -0
- package/output/js/ff/core/Channel.mjs +268 -0
- package/output/js/ff/core/Char.mjs +145 -0
- package/output/js/ff/core/Core.mjs +300 -0
- package/output/js/ff/core/Duration.mjs +112 -0
- package/output/js/ff/core/Equal.mjs +175 -0
- package/output/js/ff/core/Error.mjs +138 -0
- package/output/js/ff/core/FileHandle.mjs +164 -0
- package/output/js/ff/core/Float.mjs +214 -0
- package/output/js/ff/core/HttpClient.mjs +210 -0
- package/output/js/ff/core/Instant.mjs +105 -0
- package/output/js/ff/core/Int.mjs +254 -0
- package/output/js/ff/core/IntMap.mjs +282 -0
- package/output/js/ff/core/JsSystem.mjs +234 -0
- package/output/js/ff/core/JsValue.mjs +678 -0
- package/output/js/ff/core/List.mjs +2335 -0
- package/output/js/ff/core/Lock.mjs +322 -0
- package/output/js/ff/core/Log.mjs +159 -0
- package/output/js/ff/core/Map.mjs +358 -0
- package/output/js/ff/core/NodeSystem.mjs +288 -0
- package/output/js/ff/core/Nothing.mjs +100 -0
- package/output/js/ff/core/Option.mjs +1002 -0
- package/output/js/ff/core/Ordering.mjs +734 -0
- package/output/js/ff/core/Pair.mjs +318 -0
- package/output/js/ff/core/Path.mjs +768 -0
- package/output/js/ff/core/RbMap.mjs +1936 -0
- package/output/js/ff/core/Serializable.mjs +434 -0
- package/output/js/ff/core/Set.mjs +250 -0
- package/output/js/ff/core/Show.mjs +201 -0
- package/output/js/ff/core/Stack.mjs +595 -0
- package/output/js/ff/core/Stream.mjs +1300 -0
- package/output/js/ff/core/String.mjs +433 -0
- package/output/js/ff/core/StringMap.mjs +282 -0
- package/output/js/ff/core/Task.mjs +345 -0
- package/output/js/ff/core/Try.mjs +503 -0
- package/output/js/ff/core/Unit.mjs +103 -0
- package/package.json +29 -0
- package/postgresql/.firefly/include/package-lock.json +250 -0
- package/postgresql/.firefly/include/package.json +5 -0
- package/postgresql/.firefly/include/prepare.sh +2 -0
- package/postgresql/.firefly/package.ff +3 -0
- package/postgresql/Pg.ff +530 -0
- package/unsafejs/.firefly/package.ff +1 -0
- package/unsafejs/UnsafeJs.ff +19 -0
- package/vscode/.vscode/launch.json +18 -0
- package/vscode/.vscode/tasks.json +33 -0
- package/vscode/LICENSE.txt +21 -0
- package/vscode/Prepublish.ff +15 -0
- package/vscode/README.md +17 -0
- package/vscode/client/package-lock.json +544 -0
- package/vscode/client/package.json +22 -0
- package/vscode/client/src/extension.ts +64 -0
- package/vscode/client/tsconfig.json +12 -0
- package/vscode/icons/firefly-icon.png +0 -0
- package/vscode/icons/firefly-icon.svg +10 -0
- package/vscode/icons/firefly-logo-notext.png +0 -0
- package/vscode/icons/firefly-logo.png +0 -0
- package/vscode/language-configuration.json +39 -0
- package/vscode/package-lock.json +3623 -0
- package/vscode/package.json +144 -0
- package/vscode/snippets-none.json +1 -0
- package/vscode/snippets.json +241 -0
- package/vscode/syntaxes/firefly.tmLanguage.json +294 -0
- package/vscode/tsconfig.json +20 -0
package/core/Array.ff
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
data Array[T] {}
|
|
2
|
+
|
|
3
|
+
empty[T](): Array[T]
|
|
4
|
+
target js sync """
|
|
5
|
+
return [];
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
fill[T](size: Int, value: T): Array[T]
|
|
9
|
+
target js sync """
|
|
10
|
+
return new Array(size_).fill(value_);
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
fillBy[T](size: Int, body: Int => T): Array[T]
|
|
14
|
+
target js sync """
|
|
15
|
+
return Array.from({length: size_}, (_, i) => body_(i));
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
range(size: Int): Array[Int]
|
|
19
|
+
target js sync """
|
|
20
|
+
return Array.from({length: size_}, (_, i) => i);
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
extend self[T]: Array[T] {
|
|
24
|
+
|
|
25
|
+
addAll(that: Array[T]): Array[T]
|
|
26
|
+
target js sync "return self_.concat(that_)"
|
|
27
|
+
|
|
28
|
+
isEmpty(): Bool
|
|
29
|
+
target js sync "return self_.length === 0"
|
|
30
|
+
|
|
31
|
+
size(): Int
|
|
32
|
+
target js sync "return self_.length"
|
|
33
|
+
|
|
34
|
+
get(index: Int): Option[T]
|
|
35
|
+
target js sync """
|
|
36
|
+
return index_ >= 0 && index_ < self_.length
|
|
37
|
+
? ff_core_Option.Some(self_[index_])
|
|
38
|
+
: ff_core_Option.None()
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
grab(index: Int): T
|
|
42
|
+
target js sync """
|
|
43
|
+
if(index_ < 0 || index_ >= self_.length) {
|
|
44
|
+
ff_core_Try.internalThrowGrabException_()
|
|
45
|
+
}
|
|
46
|
+
return self_[index_]
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
first(): Option[T] { self.get(0) }
|
|
50
|
+
|
|
51
|
+
last(): Option[T] { self.get(self.size() - 1) }
|
|
52
|
+
|
|
53
|
+
grabFirst(): T { self.grab(0) }
|
|
54
|
+
|
|
55
|
+
grabLast(): T { self.grab(self.size() - 1) }
|
|
56
|
+
|
|
57
|
+
dropFirst(count: Int = 1): Array[T]
|
|
58
|
+
target js sync "return self_.slice(count_)"
|
|
59
|
+
|
|
60
|
+
dropLast(count: Int = 1): Array[T]
|
|
61
|
+
target js sync "return self_.slice(0, self_.length - count_)"
|
|
62
|
+
|
|
63
|
+
update(index: Int, body: T => T): Array[T]
|
|
64
|
+
target js sync """
|
|
65
|
+
if(index_ < 0 || index_ >= self_.length) {
|
|
66
|
+
ff_core_Try.internalThrowGrabException_()
|
|
67
|
+
}
|
|
68
|
+
let result = self_.slice();
|
|
69
|
+
result[index_] = body_(result[index_]);
|
|
70
|
+
return result;
|
|
71
|
+
"""
|
|
72
|
+
target js async """
|
|
73
|
+
if(index_ < 0 || index_ >= self_.length) {
|
|
74
|
+
ff_core_Try.internalThrowGrabException_()
|
|
75
|
+
}
|
|
76
|
+
let result = self_.slice();
|
|
77
|
+
result[index_] = await body_(result[index_], $task);
|
|
78
|
+
return result;
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
chunk(chunkSize: Int): Array[Array[T]] {
|
|
82
|
+
let results = Stack.make()
|
|
83
|
+
let result = Stack.make()
|
|
84
|
+
mutable added = 0
|
|
85
|
+
self.each { item =>
|
|
86
|
+
if(added < chunkSize) {
|
|
87
|
+
added += 1
|
|
88
|
+
} else {
|
|
89
|
+
results.push(result.drain())
|
|
90
|
+
added = 1
|
|
91
|
+
}
|
|
92
|
+
result.push(item)
|
|
93
|
+
}
|
|
94
|
+
if(added != 0) {
|
|
95
|
+
results.push(result.drain())
|
|
96
|
+
}
|
|
97
|
+
results.drain()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
toList(): List[T]
|
|
101
|
+
target js sync """
|
|
102
|
+
let result = ff_core_List.Empty();
|
|
103
|
+
for(let i = self_.length - 1; i >= 0; i--) {
|
|
104
|
+
result = ff_core_List.Link(self_[i], result);
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
toStream(cycle: Bool = False): Stream[T] {
|
|
110
|
+
mutable index = 0
|
|
111
|
+
Stream.make {
|
|
112
|
+
if(index < self.size()) {
|
|
113
|
+
let result = self.grab(index)
|
|
114
|
+
index += 1
|
|
115
|
+
result
|
|
116
|
+
} elseIf {cycle && index != 0} {
|
|
117
|
+
let result = self.grab(0)
|
|
118
|
+
index = 1
|
|
119
|
+
result
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
toStack(): Stack[T]
|
|
125
|
+
target js sync "return {array: self_.slice()}"
|
|
126
|
+
|
|
127
|
+
each(body: T => Unit): Unit
|
|
128
|
+
target js sync """
|
|
129
|
+
return self_.forEach(body_);
|
|
130
|
+
"""
|
|
131
|
+
target js async """
|
|
132
|
+
for(let i = 0; i < self_.length; i++) {
|
|
133
|
+
await body_(self_[i], $task)
|
|
134
|
+
}
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
eachWhile(body: T => Bool): Unit
|
|
138
|
+
target js sync "for(const value of self_) if(!body_(value)) break"
|
|
139
|
+
target js async "for(const value of self_) if(!await body_(value, $task)) break"
|
|
140
|
+
|
|
141
|
+
all(body: T => Bool): Bool {
|
|
142
|
+
mutable result = True
|
|
143
|
+
self.eachWhile {x =>
|
|
144
|
+
result = result && body(x)
|
|
145
|
+
result
|
|
146
|
+
}
|
|
147
|
+
result
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
any(body: T => Bool): Bool {
|
|
151
|
+
mutable result = False
|
|
152
|
+
self.eachWhile {x =>
|
|
153
|
+
result = result || body(x)
|
|
154
|
+
(!result)
|
|
155
|
+
}
|
|
156
|
+
result
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
map[S](body: T => S): Array[S]
|
|
160
|
+
target js sync """
|
|
161
|
+
return self_.map(body_)
|
|
162
|
+
"""
|
|
163
|
+
target js async """
|
|
164
|
+
let result = [];
|
|
165
|
+
for(let i = self_.length - 1; i >= 0; i--) {
|
|
166
|
+
result.push(await body_(self_[i], $task));
|
|
167
|
+
}
|
|
168
|
+
return result;
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
sortBy[S: Order](body: T => S): Array[T] {
|
|
172
|
+
self.sortWith {Ordering.compare(body(_), body(_))}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
sortWith(ordering: (T, T) => Ordering): Array[T] {
|
|
176
|
+
let stack = self.toStack()
|
|
177
|
+
stack.sortWith(ordering)
|
|
178
|
+
stack.drain()
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
extend self[T: Order]: Array[T] {
|
|
184
|
+
|
|
185
|
+
sort(): Array[T] {
|
|
186
|
+
self.sortWith(Ordering.compare)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
toSet(): Set[T] {
|
|
190
|
+
self.toList().toSet()
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
extend self[K: Order, V]: Array[Pair[K, V]] {
|
|
196
|
+
toMap(): Map[K, V] {
|
|
197
|
+
self.toList().toMap()
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
extend self: Array[String] {
|
|
202
|
+
|
|
203
|
+
join(separator: String = ""): String
|
|
204
|
+
target js sync "return self_.join(separator_)"
|
|
205
|
+
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
instance Array[T: Show]: Show {
|
|
209
|
+
show(value: Array[T]): String {
|
|
210
|
+
let stack = Stack.make()
|
|
211
|
+
stack.push("[")
|
|
212
|
+
value.each {x =>
|
|
213
|
+
if(stack.size() > 1) {stack.push(", ")}
|
|
214
|
+
stack.push(Show.show(x))
|
|
215
|
+
}
|
|
216
|
+
stack.push("].toArray()")
|
|
217
|
+
stack.join()
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
instance Array[T: Equal]: Equal {
|
|
222
|
+
equals(x: Array[T], y: Array[T]): Bool {
|
|
223
|
+
if(internalSame(x, y)) {True} else:
|
|
224
|
+
if(x.size() != y.size()) {False} else:
|
|
225
|
+
mutable i = -1
|
|
226
|
+
x.all {l =>
|
|
227
|
+
i += 1
|
|
228
|
+
l == y.grab(i)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
instance Array[T: Order]: Order {
|
|
234
|
+
compare(x: Array[T], y: Array[T]): Ordering {
|
|
235
|
+
if(internalSame(x, y)) {OrderingSame} else:
|
|
236
|
+
let size = x.size().min(y.size())
|
|
237
|
+
mutable i = 0
|
|
238
|
+
mutable ordering = OrderingSame
|
|
239
|
+
while {ordering == OrderingSame && i < size} {
|
|
240
|
+
ordering = Ordering.compare(x.grab(i), y.grab(i))
|
|
241
|
+
i += 1
|
|
242
|
+
}
|
|
243
|
+
if(ordering != OrderingSame) {ordering} else:
|
|
244
|
+
Ordering.compare(x.size(), y.size())
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
internalSame[T](left: Array[T], right: Array[T]): Bool
|
|
249
|
+
target js sync "return left_ === right_"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
capability AssetSystem(
|
|
2
|
+
files: Map[String, () => Stream[Buffer]]
|
|
3
|
+
)
|
|
4
|
+
|
|
5
|
+
create(): AssetSystem {
|
|
6
|
+
AssetSystem([].toMap())
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
extend self: AssetSystem {
|
|
10
|
+
|
|
11
|
+
addAssets(path: String, assets: AssetSystem): AssetSystem {
|
|
12
|
+
let prefix = if(path.endsWith("/")) {path.dropLast(1)} else {path}
|
|
13
|
+
AssetSystem(
|
|
14
|
+
self.files.addAll(
|
|
15
|
+
assets.files.map {p, stream =>
|
|
16
|
+
Pair(prefix + p, stream)
|
|
17
|
+
}
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
assets(path: String): AssetSystem {
|
|
23
|
+
let prefix = if(path.endsWith("/")) {path} else {path + "/"}
|
|
24
|
+
let streams = self.files.pairs().collect {
|
|
25
|
+
| Pair(p, s) {p.startsWith(prefix)} => Some(Pair(p.dropFirst(prefix.size()), s))
|
|
26
|
+
| _ => None
|
|
27
|
+
}
|
|
28
|
+
AssetSystem(streams.toMap())
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
asset(path: String): AssetSystem {
|
|
32
|
+
let name = path.reverse().takeWhile {_ != '/'}.reverse()
|
|
33
|
+
let streams = self.files.get(path).toList().map {s => Pair("/" + name, s)}
|
|
34
|
+
AssetSystem(streams.toMap())
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
list(path: String): List[String] {
|
|
38
|
+
let prefix = if(path.endsWith("/")) {path} else {path + "/"}
|
|
39
|
+
self.files.pairs().collect {
|
|
40
|
+
| Pair(p, _) {p.startsWith(prefix)} => Some(p.dropFirst(prefix.size()).takeWhile {_ != '/'})
|
|
41
|
+
| _ => None
|
|
42
|
+
}.distinct()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
exists(path: String): Bool {
|
|
46
|
+
let prefix = if(path.endsWith("/")) {path} else {path + "/"}
|
|
47
|
+
self.files.contains(path) || self.files.pairs().any {_.first.startsWith(prefix)}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
readStream(file: String): Stream[Buffer] {
|
|
51
|
+
let makeStream = self.files.get(file).else {
|
|
52
|
+
panic("Asset not found for readStream: " + file)
|
|
53
|
+
}
|
|
54
|
+
makeStream()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
readText(file: String): String {
|
|
58
|
+
self.readStream(file).toString()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
}
|
package/core/Atomic.ff
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
class Atomic[T] {}
|
|
2
|
+
|
|
3
|
+
make[T](value: T): Atomic[T]
|
|
4
|
+
target js sync """
|
|
5
|
+
return {value: value_}
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
extend self[T]: Atomic[T] {
|
|
9
|
+
|
|
10
|
+
modify(body: T => T): T
|
|
11
|
+
target js sync """
|
|
12
|
+
return self_.value = body_(self_.value)
|
|
13
|
+
"""
|
|
14
|
+
target js async """
|
|
15
|
+
let currentValue, newValue
|
|
16
|
+
do {
|
|
17
|
+
currentValue = self_.value
|
|
18
|
+
newValue = await body_(currentValue)
|
|
19
|
+
} while(currentValue !== self_.value)
|
|
20
|
+
self_.value = newValue
|
|
21
|
+
return newValue
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
getAndModify(body: T => T): T
|
|
25
|
+
target js sync """
|
|
26
|
+
const currentValue = self_.value
|
|
27
|
+
self_.value = body_(currentValue)
|
|
28
|
+
return currentValue
|
|
29
|
+
"""
|
|
30
|
+
target js async """
|
|
31
|
+
let currentValue, newValue
|
|
32
|
+
do {
|
|
33
|
+
currentValue = self_.value
|
|
34
|
+
newValue = await body_(currentValue)
|
|
35
|
+
} while(currentValue !== self_.value)
|
|
36
|
+
self_.value = newValue
|
|
37
|
+
return currentValue
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
get(): T
|
|
41
|
+
target js sync """
|
|
42
|
+
return self_.value
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
set(value: T): Unit
|
|
46
|
+
target js sync """
|
|
47
|
+
self_.value = value
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
getAndSet(newValue: T): T
|
|
51
|
+
target js sync """
|
|
52
|
+
const currentValue = self_.value
|
|
53
|
+
self_.value = newValue
|
|
54
|
+
return currentValue
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
compareAndSet(currentValue: T, newValue: T): Bool
|
|
58
|
+
target js sync """
|
|
59
|
+
if(self_.value !== currentValue) return false
|
|
60
|
+
self_.value = newValue
|
|
61
|
+
return true
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
}
|
package/core/Bool.ff
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
capability BrowserSystem {}
|
|
2
|
+
|
|
3
|
+
extend self: BrowserSystem {
|
|
4
|
+
|
|
5
|
+
httpClient(): HttpClient
|
|
6
|
+
target js async "return null"
|
|
7
|
+
|
|
8
|
+
mainTask(): Task
|
|
9
|
+
target js async "return self_.task_"
|
|
10
|
+
|
|
11
|
+
js(): JsSystem
|
|
12
|
+
target js async "return typeof globalThis !== 'undefined' ? globalThis : window"
|
|
13
|
+
|
|
14
|
+
}
|
package/core/Buffer.ff
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
class Buffer {}
|
|
2
|
+
|
|
3
|
+
make(size: Int, shared: Bool = False): Buffer
|
|
4
|
+
target js sync "return new DataView(shared_ ? new SharedArrayBuffer(size_) : new ArrayBuffer(size_))"
|
|
5
|
+
|
|
6
|
+
extend self: Buffer {
|
|
7
|
+
|
|
8
|
+
/*grabBigInt64(byteOffset: Int, littleEndian: Bool = True): BigInt
|
|
9
|
+
target js sync "return self_.getBigInt64(byteOffset_, littleEndian_)"*/
|
|
10
|
+
|
|
11
|
+
/*grabBigUint64(byteOffset: Int, littleEndian: Bool = True): BigInt
|
|
12
|
+
target js sync "return self_.getBigUint64(byteOffset_, littleEndian_)"*/
|
|
13
|
+
|
|
14
|
+
grabUint64(byteOffset: Int, littleEndian: Bool = True): Int
|
|
15
|
+
target js sync """
|
|
16
|
+
const high = self_.getUint32(byteOffset_ + (littleEndian_ ? 4 : 0), littleEndian_)
|
|
17
|
+
const low = self_.getUint32(byteOffset_ + (littleEndian_ ? 0 : 4), littleEndian_)
|
|
18
|
+
const result = (high * 0x100000000) + low
|
|
19
|
+
if(!Number.isSafeInteger(result)) throw 'grabUint64 out of range (consider grabBigUint64)'
|
|
20
|
+
return result
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
grabInt64(byteOffset: Int, littleEndian: Bool = True): Int
|
|
24
|
+
target js sync """
|
|
25
|
+
const high = self_.getInt32(byteOffset_ + (littleEndian_ ? 4 : 0), littleEndian_)
|
|
26
|
+
const low = self_.getUint32(byteOffset_ + (littleEndian_ ? 0 : 4), littleEndian_)
|
|
27
|
+
const result = (high * 0x100000000) + low
|
|
28
|
+
if(!Number.isSafeInteger(result)) throw 'grabInt64 out of range (consider grabBigInt64)'
|
|
29
|
+
return result
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
grabFloat32(byteOffset: Int, littleEndian: Bool = True): Float
|
|
33
|
+
target js sync "return self_.getFloat32(byteOffset_, littleEndian_)"
|
|
34
|
+
|
|
35
|
+
grabFloat64(byteOffset: Int, littleEndian: Bool = True): Float
|
|
36
|
+
target js sync "return self_.getFloat64(byteOffset_, littleEndian_)"
|
|
37
|
+
|
|
38
|
+
grabInt16(byteOffset: Int, littleEndian: Bool = True): Int
|
|
39
|
+
target js sync "return self_.getInt16(byteOffset_, littleEndian_)"
|
|
40
|
+
|
|
41
|
+
grabInt32(byteOffset: Int, littleEndian: Bool = True): Int
|
|
42
|
+
target js sync "return self_.getInt32(byteOffset_, littleEndian_)"
|
|
43
|
+
|
|
44
|
+
grabInt8(byteOffset: Int): Int
|
|
45
|
+
target js sync "return self_.getInt8(byteOffset_)"
|
|
46
|
+
|
|
47
|
+
grabUint16(byteOffset: Int, littleEndian: Bool = True): Int
|
|
48
|
+
target js sync "return self_.getUint16(byteOffset_, littleEndian_)"
|
|
49
|
+
|
|
50
|
+
grabUint32(byteOffset: Int, littleEndian: Bool = True): Int
|
|
51
|
+
target js sync "return self_.getUint32(byteOffset_, littleEndian_)"
|
|
52
|
+
|
|
53
|
+
grabUint8(byteOffset: Int): Int
|
|
54
|
+
target js sync "return self_.getUint8(byteOffset_)"
|
|
55
|
+
|
|
56
|
+
/*setBigInt64(byteOffset: Int, value: BigInt, littleEndian: Bool = False): Unit
|
|
57
|
+
target js sync "self_.setBigInt64(byteOffset_, value_, littleEndian_)"*/
|
|
58
|
+
|
|
59
|
+
/*setBigUint64(byteOffset: Int, value: BigInt, littleEndian: Bool = False): Unit
|
|
60
|
+
target js sync "self_.setBigUint64(byteOffset_, value_, littleEndian_)"*/
|
|
61
|
+
|
|
62
|
+
setUint64(byteOffset: Int, value: Int, littleEndian: Bool = True): Int
|
|
63
|
+
target js sync """
|
|
64
|
+
self_.setUint32(byteOffset_ + (littleEndian_ ? 4 : 0), (value_ >>> 16) >>> 16, littleEndian_)
|
|
65
|
+
self_.setUint32(byteOffset_ + (littleEndian_ ? 0 : 4), value_ & 0xffffffff, littleEndian_)
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
setInt64(byteOffset: Int, value: Int, littleEndian: Bool = True): Int
|
|
69
|
+
target js sync """
|
|
70
|
+
self_.setUint32(byteOffset_ + (littleEndian_ ? 4 : 0), (value_ >> 16) >> 16, littleEndian_)
|
|
71
|
+
self_.setUint32(byteOffset_ + (littleEndian_ ? 0 : 4), value_ & 0xffffffff, littleEndian_)
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
setFloat32(byteOffset: Int, value: Float, littleEndian: Bool = True): Unit
|
|
75
|
+
target js sync "self_.setFloat32(byteOffset_, value_, littleEndian_)"
|
|
76
|
+
|
|
77
|
+
setFloat64(byteOffset: Int, value: Float, littleEndian: Bool = True): Unit
|
|
78
|
+
target js sync "self_.setFloat64(byteOffset_, value_, littleEndian_)"
|
|
79
|
+
|
|
80
|
+
setInt16(byteOffset: Int, value: Int, littleEndian: Bool = True): Unit
|
|
81
|
+
target js sync "self_.setInt16(byteOffset_, value_, littleEndian_)"
|
|
82
|
+
|
|
83
|
+
setInt32(byteOffset: Int, value: Int, littleEndian: Bool = True): Unit
|
|
84
|
+
target js sync "self_.setInt32(byteOffset_, value_, littleEndian_)"
|
|
85
|
+
|
|
86
|
+
setInt8(byteOffset: Int, value: Int): Unit
|
|
87
|
+
target js sync "self_.setInt8(byteOffset_, value_)"
|
|
88
|
+
|
|
89
|
+
setUint16(byteOffset: Int, value: Int, littleEndian: Bool = True): Unit
|
|
90
|
+
target js sync "self_.setUint16(byteOffset_, value_, littleEndian_)"
|
|
91
|
+
|
|
92
|
+
setUint32(byteOffset: Int, value: Int, littleEndian: Bool = True): Unit
|
|
93
|
+
target js sync "self_.setUint32(byteOffset_, value_, littleEndian_)"
|
|
94
|
+
|
|
95
|
+
setUint8(byteOffset: Int, value: Int): Unit
|
|
96
|
+
target js sync "self_.setUint8(byteOffset_, value_)"
|
|
97
|
+
|
|
98
|
+
setAll(byteOffset: Int, buffer: Buffer): Unit
|
|
99
|
+
target js sync """
|
|
100
|
+
const sourceBuffer = new Uint8Array(buffer_.buffer, buffer_.byteOffset, buffer_.byteLength)
|
|
101
|
+
const targetBuffer = new Uint8Array(self_.buffer, self_.byteOffset, self_.byteLength)
|
|
102
|
+
targetBuffer.set(sourceBuffer, byteOffset_)
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
size(): Int
|
|
106
|
+
target js sync "return self_.byteLength"
|
|
107
|
+
|
|
108
|
+
shared(): Bool
|
|
109
|
+
target js sync "return typeof SharedArrayBuffer !== 'undefined' && self_.buffer instanceof SharedArrayBuffer"
|
|
110
|
+
|
|
111
|
+
view(begin: Int, end: Int): Buffer
|
|
112
|
+
target js sync "return new DataView(self_.buffer, self_.byteOffset + begin_, end_ - begin_)"
|
|
113
|
+
|
|
114
|
+
copy(): Buffer
|
|
115
|
+
target js sync "return new DataView(self_.buffer.slice(self_.byteOffset, self_.byteOffset + self_.byteLength))"
|
|
116
|
+
|
|
117
|
+
toString(encoding: String = "utf8"): String
|
|
118
|
+
target js sync """
|
|
119
|
+
if(encoding_ === "utf8") {
|
|
120
|
+
if(typeof TextDecoder.ffSingleton === 'undefined') TextDecoder.ffSingleton = new TextDecoder()
|
|
121
|
+
return TextDecoder.ffSingleton.decode(self_)
|
|
122
|
+
}
|
|
123
|
+
return new TextDecoder().decode(self_)
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
toByteArray(): Array[Int]
|
|
127
|
+
target js sync "return [...new Uint8Array(self_.buffer, self_.byteOffset, self_.byteLength)]"
|
|
128
|
+
|
|
129
|
+
toHex(): String
|
|
130
|
+
target js sync """
|
|
131
|
+
let hex = ''
|
|
132
|
+
for (let i = 0; i < self_.byteLength; i++) {
|
|
133
|
+
hex += self_.getUint8(i).toString(16).padStart(2, '0')
|
|
134
|
+
}
|
|
135
|
+
return hex
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
toBase64(): String
|
|
139
|
+
target js sync """
|
|
140
|
+
const view = new Uint8Array(self_.buffer, self_.byteOffset, self_.byteLength);
|
|
141
|
+
return btoa(String.fromCharCode(...view));
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
fromByteArray(array: Array[Int]): Buffer
|
|
147
|
+
target js sync "return new DataView(new Uint8Array(array_).buffer)"
|
|
148
|
+
|
|
149
|
+
fromBufferArray(array: Array[Buffer]): Buffer
|
|
150
|
+
target js sync """
|
|
151
|
+
let length = 0
|
|
152
|
+
for(let b of array_) length += b.byteLength
|
|
153
|
+
const arrayBuffer = new ArrayBuffer(length);
|
|
154
|
+
const result = new Uint8Array(arrayBuffer)
|
|
155
|
+
let offset = 0
|
|
156
|
+
for(let b of array_) {
|
|
157
|
+
result.set(new Uint8Array(b.buffer, b.byteOffset, b.byteLength), offset)
|
|
158
|
+
offset += b.byteLength
|
|
159
|
+
}
|
|
160
|
+
return new DataView(arrayBuffer)
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
fromHex(hex: String): Buffer
|
|
164
|
+
target js sync """
|
|
165
|
+
const hexValues = hexString.match(/.{1,2}/g) || []
|
|
166
|
+
const numbers = hexValues.map(value => parseInt(value, 16))
|
|
167
|
+
return new DataView(new Uint8Array(numbers).buffer)
|
|
168
|
+
"""
|
|
169
|
+
|
|
170
|
+
fromBase64(base64: String): Buffer
|
|
171
|
+
target js sync """
|
|
172
|
+
const binaryString = atob(base64_)
|
|
173
|
+
const dataView = new DataView(new ArrayBuffer(binaryString.length))
|
|
174
|
+
dataView.setUint8(binaryString.split('').map(char => char.charCodeAt(0)))
|
|
175
|
+
return dataView
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
instance Buffer: Show {
|
|
179
|
+
show(value: Buffer): String {
|
|
180
|
+
"""Buffer.fromHex("""" + value.toHex() + """")"""
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
instance Buffer: Equal {
|
|
185
|
+
equals(x: Buffer, y: Buffer): Bool
|
|
186
|
+
target js sync """
|
|
187
|
+
if(x_.buffer.byteLength !== y_.buffer.byteLength) return false
|
|
188
|
+
if(x_.buffer === y_.buffer) return true
|
|
189
|
+
for(let i = 0; i + 4 <= x_.buffer.byteLength; i += 4) {
|
|
190
|
+
if(x_.getInt32(i) !== y_.getInt32(i)) return false
|
|
191
|
+
}
|
|
192
|
+
for(; i < x_.buffer.byteLength; i++) {
|
|
193
|
+
if(x_.getUint8(i) !== y_.getUint8(i)) return false
|
|
194
|
+
}
|
|
195
|
+
return true
|
|
196
|
+
"""
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
instance Buffer: Order {
|
|
200
|
+
compare(x: Buffer, y: Buffer): Ordering
|
|
201
|
+
target js sync """
|
|
202
|
+
if(x_.buffer === y_.buffer) return ff_core_Ordering.OrderingSame()
|
|
203
|
+
const minLength = Math.min(x_.buffer.byteLength, y_.buffer.byteLength)
|
|
204
|
+
for(let i = 0; i < minLength; i++) {
|
|
205
|
+
if(x_.getUint8(i) !== y_.getUint8(i)) {
|
|
206
|
+
return ff_core_Ordering.fromInt_(x_.getUint8(i) - y_.getUint8(i))
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return ff_core_Ordering.fromInt_(x_.buffer.byteLength - y_.buffer.byteLength)
|
|
210
|
+
"""
|
|
211
|
+
}
|