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.
Files changed (221) hide show
  1. package/.firefly-workspace +1 -0
  2. package/.vscode/settings.json +5 -0
  3. package/LICENSE.txt +21 -0
  4. package/README.md +96 -0
  5. package/bin/firefly.mjs +2 -0
  6. package/compiler/.firefly/package.ff +1 -0
  7. package/compiler/Builder.ff +218 -0
  8. package/compiler/Compiler.ff +241 -0
  9. package/compiler/Dependencies.ff +179 -0
  10. package/compiler/Deriver.ff +647 -0
  11. package/compiler/Dictionaries.ff +205 -0
  12. package/compiler/Environment.ff +166 -0
  13. package/compiler/Inference.ff +1117 -0
  14. package/compiler/JsEmitter.ff +861 -0
  15. package/compiler/JsImporter.ff +56 -0
  16. package/compiler/LspHook.ff +188 -0
  17. package/compiler/Main.ff +237 -0
  18. package/compiler/Parser.ff +1383 -0
  19. package/compiler/Patterns.ff +111 -0
  20. package/compiler/Resolver.ff +620 -0
  21. package/compiler/Substitution.ff +178 -0
  22. package/compiler/Syntax.ff +299 -0
  23. package/compiler/Token.ff +180 -0
  24. package/compiler/Tokenizer.ff +278 -0
  25. package/compiler/Unification.ff +220 -0
  26. package/compiler/Wildcards.ff +50 -0
  27. package/compiler/Workspace.ff +88 -0
  28. package/core/.firefly/package.ff +2 -0
  29. package/core/Any.ff +30 -0
  30. package/core/Array.ff +249 -0
  31. package/core/AssetSystem.ff +61 -0
  32. package/core/Atomic.ff +64 -0
  33. package/core/Bool.ff +13 -0
  34. package/core/BrowserSystem.ff +14 -0
  35. package/core/Buffer.ff +211 -0
  36. package/core/BuildSystem.ff +144 -0
  37. package/core/Channel.ff +131 -0
  38. package/core/Char.ff +18 -0
  39. package/core/Core.ff +58 -0
  40. package/core/Duration.ff +15 -0
  41. package/core/Equal.ff +52 -0
  42. package/core/Error.ff +20 -0
  43. package/core/FileHandle.ff +41 -0
  44. package/core/Float.ff +41 -0
  45. package/core/HttpClient.ff +84 -0
  46. package/core/Instant.ff +9 -0
  47. package/core/Int.ff +61 -0
  48. package/core/IntMap.ff +85 -0
  49. package/core/JsSystem.ff +66 -0
  50. package/core/JsValue.ff +240 -0
  51. package/core/List.ff +440 -0
  52. package/core/Lock.ff +144 -0
  53. package/core/Log.ff +24 -0
  54. package/core/Map.ff +126 -0
  55. package/core/NodeSystem.ff +88 -0
  56. package/core/Nothing.ff +1 -0
  57. package/core/Option.ff +133 -0
  58. package/core/Ordering.ff +157 -0
  59. package/core/Pair.ff +55 -0
  60. package/core/Path.ff +393 -0
  61. package/core/RbMap.ff +216 -0
  62. package/core/Serializable.ff +173 -0
  63. package/core/Set.ff +38 -0
  64. package/core/Show.ff +43 -0
  65. package/core/Stack.ff +263 -0
  66. package/core/Stream.ff +406 -0
  67. package/core/String.ff +175 -0
  68. package/core/StringMap.ff +85 -0
  69. package/core/Task.ff +138 -0
  70. package/core/Try.ff +81 -0
  71. package/core/Unit.ff +3 -0
  72. package/experimental/random/AltGeneric.ff +44 -0
  73. package/experimental/random/Async.ff +68 -0
  74. package/experimental/random/Buffer2.ff +77 -0
  75. package/experimental/random/Cat.ff +12 -0
  76. package/experimental/random/Dictionary.ff +52 -0
  77. package/experimental/random/Example.ff +46 -0
  78. package/experimental/random/Generic.ff +102 -0
  79. package/experimental/random/HappyEyeballs.ff +40 -0
  80. package/experimental/random/HashMap.ff +72 -0
  81. package/experimental/random/IfElseUnit.ff +9 -0
  82. package/experimental/random/InputOutput.ff +23 -0
  83. package/experimental/random/ListVsArray.ff +45 -0
  84. package/experimental/random/Main.ff +44 -0
  85. package/experimental/random/MapTest.ff +67 -0
  86. package/experimental/random/OldTaskSystem.ff +210 -0
  87. package/experimental/random/PatternTest.ff +39 -0
  88. package/experimental/random/Patterns.ff +226 -0
  89. package/experimental/random/ReadBytesTest.ff +10 -0
  90. package/experimental/random/RunLength.ff +65 -0
  91. package/experimental/random/Scrape.ff +51 -0
  92. package/experimental/random/Serialization.ff +217 -0
  93. package/experimental/random/SerializationTest.ff +46 -0
  94. package/experimental/random/Serializer.ff +36 -0
  95. package/experimental/random/StdInOutErr.ff +4 -0
  96. package/experimental/random/Symbols.ff +74 -0
  97. package/experimental/random/Tag.ff +49 -0
  98. package/experimental/random/Tensor.ff +52 -0
  99. package/experimental/random/Try.ff +56 -0
  100. package/experimental/random/Tsv.ff +9 -0
  101. package/experimental/random/TypesAreModules.ff +87 -0
  102. package/experimental/random/blueprints/Blueprint.ff +52 -0
  103. package/experimental/random/blueprints/Main.ff +11 -0
  104. package/experimental/random/blueprints/Pretty.ff +58 -0
  105. package/experimental/random/blueprints/User.ff +64 -0
  106. package/experimental/random/blueprintsystem/BlueprintSystem.ff +48 -0
  107. package/experimental/random/blueprintsystem/Deserialize.ff +53 -0
  108. package/experimental/random/blueprintsystem/ReadJs.ff +13 -0
  109. package/experimental/random/blueprintsystem/User.ff +2 -0
  110. package/experimental/random/kahrs/Kahrs.ff +112 -0
  111. package/experimental/random/kahrs/TestKahrs.ff +22 -0
  112. package/experimental/random/kahrs/TestMap.ff +18 -0
  113. package/experimental/random/streaming/Gzip.ff +3 -0
  114. package/experimental/random/streaming/Main.ff +34 -0
  115. package/experimental/random/streaming/S3Bucket.ff +11 -0
  116. package/experimental/random/streaming/Tar.ff +5 -0
  117. package/experimental/rhymeapp/Main.ff +81 -0
  118. package/experimental/rhymeapp/index.html +14 -0
  119. package/firefly.sh +5 -0
  120. package/fireflysite/Main.ff +13 -0
  121. package/httpserver/.firefly/package.ff +1 -0
  122. package/httpserver/HttpServer.ff +184 -0
  123. package/lsp/.firefly/package.ff +1 -0
  124. package/lsp/CompletionHandler.ff +814 -0
  125. package/lsp/Handler.ff +551 -0
  126. package/lsp/HoverHandler.ff +82 -0
  127. package/lsp/LanguageServer.ff +229 -0
  128. package/lsp/SignatureHelpHandler.ff +55 -0
  129. package/lsp/SymbolHandler.ff +167 -0
  130. package/output/js/ff/compiler/Builder.mjs +483 -0
  131. package/output/js/ff/compiler/Compiler.mjs +410 -0
  132. package/output/js/ff/compiler/Dependencies.mjs +388 -0
  133. package/output/js/ff/compiler/Deriver.mjs +1166 -0
  134. package/output/js/ff/compiler/Dictionaries.mjs +1305 -0
  135. package/output/js/ff/compiler/Environment.mjs +1005 -0
  136. package/output/js/ff/compiler/Inference.mjs +4264 -0
  137. package/output/js/ff/compiler/JsEmitter.mjs +5353 -0
  138. package/output/js/ff/compiler/JsImporter.mjs +262 -0
  139. package/output/js/ff/compiler/LspHook.mjs +789 -0
  140. package/output/js/ff/compiler/Main.mjs +1695 -0
  141. package/output/js/ff/compiler/Parser.mjs +4004 -0
  142. package/output/js/ff/compiler/Patterns.mjs +923 -0
  143. package/output/js/ff/compiler/Resolver.mjs +2303 -0
  144. package/output/js/ff/compiler/Substitution.mjs +1146 -0
  145. package/output/js/ff/compiler/Syntax.mjs +12430 -0
  146. package/output/js/ff/compiler/Token.mjs +3092 -0
  147. package/output/js/ff/compiler/Tokenizer.mjs +589 -0
  148. package/output/js/ff/compiler/Unification.mjs +1748 -0
  149. package/output/js/ff/compiler/Wildcards.mjs +604 -0
  150. package/output/js/ff/compiler/Workspace.mjs +683 -0
  151. package/output/js/ff/core/Any.mjs +139 -0
  152. package/output/js/ff/core/Array.mjs +594 -0
  153. package/output/js/ff/core/AssetSystem.mjs +270 -0
  154. package/output/js/ff/core/Atomic.mjs +186 -0
  155. package/output/js/ff/core/Bool.mjs +141 -0
  156. package/output/js/ff/core/BrowserSystem.mjs +122 -0
  157. package/output/js/ff/core/Buffer.mjs +467 -0
  158. package/output/js/ff/core/BuildSystem.mjs +320 -0
  159. package/output/js/ff/core/Channel.mjs +268 -0
  160. package/output/js/ff/core/Char.mjs +145 -0
  161. package/output/js/ff/core/Core.mjs +300 -0
  162. package/output/js/ff/core/Duration.mjs +112 -0
  163. package/output/js/ff/core/Equal.mjs +175 -0
  164. package/output/js/ff/core/Error.mjs +138 -0
  165. package/output/js/ff/core/FileHandle.mjs +164 -0
  166. package/output/js/ff/core/Float.mjs +214 -0
  167. package/output/js/ff/core/HttpClient.mjs +210 -0
  168. package/output/js/ff/core/Instant.mjs +105 -0
  169. package/output/js/ff/core/Int.mjs +254 -0
  170. package/output/js/ff/core/IntMap.mjs +282 -0
  171. package/output/js/ff/core/JsSystem.mjs +234 -0
  172. package/output/js/ff/core/JsValue.mjs +678 -0
  173. package/output/js/ff/core/List.mjs +2335 -0
  174. package/output/js/ff/core/Lock.mjs +322 -0
  175. package/output/js/ff/core/Log.mjs +159 -0
  176. package/output/js/ff/core/Map.mjs +358 -0
  177. package/output/js/ff/core/NodeSystem.mjs +288 -0
  178. package/output/js/ff/core/Nothing.mjs +100 -0
  179. package/output/js/ff/core/Option.mjs +1002 -0
  180. package/output/js/ff/core/Ordering.mjs +734 -0
  181. package/output/js/ff/core/Pair.mjs +318 -0
  182. package/output/js/ff/core/Path.mjs +768 -0
  183. package/output/js/ff/core/RbMap.mjs +1936 -0
  184. package/output/js/ff/core/Serializable.mjs +434 -0
  185. package/output/js/ff/core/Set.mjs +250 -0
  186. package/output/js/ff/core/Show.mjs +201 -0
  187. package/output/js/ff/core/Stack.mjs +595 -0
  188. package/output/js/ff/core/Stream.mjs +1300 -0
  189. package/output/js/ff/core/String.mjs +433 -0
  190. package/output/js/ff/core/StringMap.mjs +282 -0
  191. package/output/js/ff/core/Task.mjs +345 -0
  192. package/output/js/ff/core/Try.mjs +503 -0
  193. package/output/js/ff/core/Unit.mjs +103 -0
  194. package/package.json +29 -0
  195. package/postgresql/.firefly/include/package-lock.json +250 -0
  196. package/postgresql/.firefly/include/package.json +5 -0
  197. package/postgresql/.firefly/include/prepare.sh +2 -0
  198. package/postgresql/.firefly/package.ff +3 -0
  199. package/postgresql/Pg.ff +530 -0
  200. package/unsafejs/.firefly/package.ff +1 -0
  201. package/unsafejs/UnsafeJs.ff +19 -0
  202. package/vscode/.vscode/launch.json +18 -0
  203. package/vscode/.vscode/tasks.json +33 -0
  204. package/vscode/LICENSE.txt +21 -0
  205. package/vscode/Prepublish.ff +15 -0
  206. package/vscode/README.md +17 -0
  207. package/vscode/client/package-lock.json +544 -0
  208. package/vscode/client/package.json +22 -0
  209. package/vscode/client/src/extension.ts +64 -0
  210. package/vscode/client/tsconfig.json +12 -0
  211. package/vscode/icons/firefly-icon.png +0 -0
  212. package/vscode/icons/firefly-icon.svg +10 -0
  213. package/vscode/icons/firefly-logo-notext.png +0 -0
  214. package/vscode/icons/firefly-logo.png +0 -0
  215. package/vscode/language-configuration.json +39 -0
  216. package/vscode/package-lock.json +3623 -0
  217. package/vscode/package.json +144 -0
  218. package/vscode/snippets-none.json +1 -0
  219. package/vscode/snippets.json +241 -0
  220. package/vscode/syntaxes/firefly.tmLanguage.json +294 -0
  221. package/vscode/tsconfig.json +20 -0
package/core/Path.ff ADDED
@@ -0,0 +1,393 @@
1
+ capability Path {}
2
+ capability PathEntry {}
3
+
4
+ extend self: Path {
5
+
6
+ exists(checkReadable: Bool = False, checkWritable: Bool = False, checkExecutable: Bool = False): Bool
7
+ target node async """
8
+ import * as fs from 'fs'
9
+ import * as fsPromises from 'fs/promises'
10
+ const flags =
11
+ (fs.constants.R_OK * checkReadable_) |
12
+ (fs.constants.W_OK * checkWritable_) |
13
+ (fs.constants.X_OK * checkExecutable_)
14
+ try {
15
+ await fsPromises.access(self_, flags === 0 ? fs.constants.F_OK : flags)
16
+ return true
17
+ } catch(e) {
18
+ return false
19
+ }
20
+ """
21
+
22
+ isReadable(): Bool {
23
+ self.exists(checkReadable = True)
24
+ }
25
+
26
+ isWritable(): Bool {
27
+ self.exists(checkWritable = True)
28
+ }
29
+
30
+ isExecutable(): Bool {
31
+ self.exists(checkExecutable = True)
32
+ }
33
+
34
+ isDirectory(): Bool
35
+ target node async """
36
+ import * as fsPromises from 'fs/promises'
37
+ try {
38
+ return (await fsPromises.lstat(self_)).isDirectory();
39
+ } catch(e) {
40
+ return false;
41
+ }
42
+ """
43
+
44
+ isFile(): Bool
45
+ target node async """
46
+ import * as fsPromises from 'fs/promises'
47
+ try {
48
+ return (await fsPromises.lstat(self_)).isFile();
49
+ } catch(e) {
50
+ return false;
51
+ }
52
+ """
53
+
54
+ isSymbolicLink(): Bool
55
+ target node async """
56
+ import * as fsPromises from 'fs/promises'
57
+ try {
58
+ return (await fsPromises.lstat(self_)).isSymbolicLink();
59
+ } catch(e) {
60
+ return false;
61
+ }
62
+ """
63
+
64
+ isInsideOf(path: Path): Bool
65
+ target node async """
66
+ import * as path from 'path'
67
+ if(path_ === '/') return true
68
+ const childPath = path.resolve(self_)
69
+ const parentPath = path.resolve(path_)
70
+ return childPath.startsWith(parentPath + path.sep) || childPath === parentPath
71
+ """
72
+
73
+ size(): Int
74
+ target node async """
75
+ return (await fs.promises.stat(file)).size
76
+ """
77
+
78
+ modified(): Instant
79
+ target node async """
80
+ return (await fs.promises.stat(file)).mtimeMs * 0.001
81
+ """
82
+
83
+ entries(): Stream[PathEntry]
84
+ target node async """
85
+ import * as fsPromises from 'fs/promises'
86
+ let dir = null
87
+ return ff_core_Stream.Stream(
88
+ async () => {
89
+ if(dir === null) dir = await fsPromises.opendir(self_, {bufferSize: 128})
90
+ const entry = await dir.read()
91
+ if(entry === null) return ff_core_Option.None()
92
+ entry.ffPath = self_
93
+ return ff_core_Option.Some(entry)
94
+ },
95
+ async () => {
96
+ await dir.close()
97
+ }
98
+ )
99
+ """
100
+
101
+ absolute(): String
102
+ target node async """
103
+ import * as path from 'path'
104
+ return path.resolve(self_)
105
+ """
106
+
107
+ relativeTo(path: Path): String
108
+ target node async """
109
+ import * as path from 'path';
110
+ return path.relative(path_, self_);
111
+ """
112
+
113
+ endsWith(parts: List[String]): Bool {
114
+ function go(pathOption: Option[Path], reversed: List[String]): Bool {
115
+ | _, [] => True
116
+ | Some(path), [p, ...ps] => path.base() == p && go(path.parent(), ps)
117
+ | None, _ => False
118
+ }
119
+ go(Some(self), parts.reverse())
120
+ }
121
+
122
+ base(): String
123
+ target node async """
124
+ import * as path from 'path'
125
+ return path.basename(self_)
126
+ """
127
+
128
+ extension(): String
129
+ target node async """
130
+ import * as path from 'path'
131
+ return path.extname(self_)
132
+ """
133
+
134
+ url(): String
135
+ target node async """
136
+ import * as url from 'url';
137
+ return '' + url.pathToFileURL(self_);
138
+ """
139
+
140
+ delimiter(): String
141
+ target node async """
142
+ import * as path from 'path';
143
+ return path.delimiter(self_);
144
+ """
145
+
146
+ separator(): String
147
+ target node async """
148
+ import * as path from 'path';
149
+ return path.separator();
150
+ """
151
+
152
+ parent(): Option[Path]
153
+ target node async """
154
+ import * as path from 'path'
155
+ const result = path.dirname(self_)
156
+ return result !== "" && result !== self_
157
+ ? ff_core_Option.Some(result)
158
+ : ff_core_Option.None()
159
+ """
160
+
161
+ slash(relativePath: String): Path
162
+ target node async """
163
+ import * as path from 'path'
164
+ return path.join(self_, relativePath_)
165
+ """
166
+
167
+ path(absoluteOrRelativePath: String): Path
168
+ target node async """
169
+ import * as path from 'path'
170
+ return path.resolve(self_, absoluteOrRelativePath_)
171
+ """
172
+
173
+ copyTo(path: Path, retries: Int = 0, retryDelay: Int = 100) {
174
+ if(self.isDirectory()) {
175
+ if(path.exists()) {path.delete(retries, retryDelay)}
176
+ path.createDirectory()
177
+ self.entries().each {file =>
178
+ file.path().copyTo(path.slash(file.path().relativeTo(self)), retries, retryDelay)
179
+ }
180
+ } else {
181
+ path.writeStream(self.readStream())
182
+ }
183
+ }
184
+
185
+ createDirectory(createParentDirectories: Bool = False)
186
+ target node async """
187
+ import * as fsPromises from 'fs/promises'
188
+ await fsPromises.mkdir(self_, {recursive: createParentDirectories_})
189
+ """
190
+
191
+ createSymlinkTo(path: Path)
192
+ target node async """
193
+ import * as fsPromises from 'fs/promises'
194
+ await fsPromises.symlink(path_, self_)
195
+ """
196
+
197
+ delete(retries: Int = 0, retryDelay: Int = 100)
198
+ target node async """
199
+ import * as fsPromises from 'fs/promises'
200
+ await fsPromises.rm(self_, {recursive: true, retries: retries_, retryDelay: retryDelay_})
201
+ """
202
+
203
+ truncate(length: Int = 0)
204
+ target node async """
205
+ import * as fsPromises from 'fs/promises'
206
+ await fsPromises.truncate(self_, length_)
207
+ """
208
+
209
+ renameTo(path: Path)
210
+ target node async """
211
+ import * as fsPromises from 'fs/promises'
212
+ await fsPromises.rename(self_, path_)
213
+ """
214
+
215
+ readText(): String
216
+ target node async """
217
+ import * as fsPromises from 'fs/promises'
218
+ try {
219
+ return await fsPromises.readFile(self_, {encoding: 'UTF-8', signal: $task.controller.signal})
220
+ } finally {
221
+ if($task.controller.signal.aborted) $task.controller = new AbortController()
222
+ }
223
+ """
224
+
225
+ writeText(text: String)
226
+ target node async """
227
+ import * as fsPromises from 'fs/promises'
228
+ try {
229
+ await fsPromises.writeFile(self_, text_, {encoding: 'UTF-8', signal: $task.controller.signal})
230
+ } finally {
231
+ if($task.controller.signal.aborted) $task.controller = new AbortController()
232
+ }
233
+ """
234
+
235
+ appendText(text: String)
236
+ target node async """
237
+ import * as fsPromises from 'fs/promises'
238
+ try {
239
+ await fsPromises.appendFile(self_, text_, {encoding: 'UTF-8', signal: $task.controller.signal})
240
+ } finally {
241
+ if($task.controller.signal.aborted) $task.controller = new AbortController()
242
+ }
243
+ """
244
+
245
+ readBuffer(): Buffer {
246
+ self.readStream().toBuffer()
247
+ }
248
+
249
+ writeBuffer(buffer: Buffer) {
250
+ self.writeStream([buffer].toStream())
251
+ }
252
+
253
+ appendBuffer(buffer: Buffer) {
254
+ self.appendStream([buffer].toStream())
255
+ }
256
+
257
+ readStream(): Stream[Buffer]
258
+ target node async """
259
+ import * as fs from 'fs'
260
+ return ff_core_Path.internalReadStream_$(() => fs.createReadStream(self_))
261
+ """
262
+
263
+ writeStream(stream: Stream[Buffer], createOnly: Bool = False)
264
+ target node async """
265
+ import * as fs from 'fs'
266
+ let writeable = fs.createWriteStream(self_, {flags: createOnly_ ? 'wx' : 'w'})
267
+ try {
268
+ await ff_core_Stream.Stream_each$(stream_, async buffer => {
269
+ if(!writeable.write(new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength))) {
270
+ await new Promise((resolve, reject) => {
271
+ $task.controller.signal.addEventListener('abort', reject)
272
+ writeable.once('drain', () => {
273
+ $task.controller.signal.removeEventListener('abort', reject)
274
+ resolve()
275
+ })
276
+ })
277
+ }
278
+ }, $task)
279
+ } finally {
280
+ writeable.close()
281
+ }
282
+ """
283
+
284
+ appendStream(stream: Stream[Buffer])
285
+ target node async """
286
+ import * as fs from 'fs'
287
+ let writeable = fs.createWriteStream(self_, {flags: 'a'})
288
+ try {
289
+ await ff_core_Stream.Stream_each$(stream_, async buffer => {
290
+ if(!writeable.write(new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength))) {
291
+ await new Promise((resolve, reject) => {
292
+ $task.controller.signal.addEventListener('abort', reject)
293
+ writeable.once('drain', () => {
294
+ $task.controller.signal.removeEventListener('abort', reject)
295
+ resolve()
296
+ })
297
+ })
298
+ }
299
+ }, $task)
300
+ } finally {
301
+ writeable.close()
302
+ }
303
+ """
304
+
305
+ readHandle(alsoWrite: Bool = False): FileHandle
306
+ target node async """
307
+ import * as fsPromises from 'fs/promises'
308
+ return await fsPromises.open(self_, alsoWrite_ ? 'r+' : 'r')
309
+ """
310
+
311
+ writeHandle(alsoRead: Bool = False, mustCreate: Bool = False): FileHandle
312
+ target node async """
313
+ import * as fsPromises from 'fs/promises'
314
+ return await fsPromises.open(self_, (mustCreate_ ? 'wx' : 'w') + (alsoRead_ ? '+' : ''))
315
+ """
316
+
317
+ appendHandle(alsoRead: Bool = False, mustCreate: Bool = False): FileHandle
318
+ target node async """
319
+ import * as fsPromises from 'fs/promises'
320
+ return await fsPromises.open(self_, (mustCreate_ ? 'wx' : 'w') + (alsoRead_ ? '+' : ''))
321
+ """
322
+
323
+ }
324
+
325
+ extend self: PathEntry {
326
+
327
+ path(): Path
328
+ target node async """
329
+ import * as path from 'path'
330
+ return path.join(self_.ffPath, self_.name)
331
+ """
332
+
333
+ isDirectory(): Bool
334
+ target node async """
335
+ return self_.isDirectory()
336
+ """
337
+
338
+ isFile(): Bool
339
+ target node async """
340
+ return self_.isFile()
341
+ """
342
+
343
+ isSymbolicLink(): Bool
344
+ target node async """
345
+ return self_.isSymbolicLink()
346
+ """
347
+
348
+ }
349
+
350
+ internalReadStream(createReadStream: () => JsValue): Stream[Buffer]
351
+ target node async """
352
+ let task = null
353
+ let readable = null
354
+ let doResolve = null
355
+ let doReject = null
356
+ let seenError = null
357
+ const abort = () => {
358
+ if(task != null) {
359
+ task.controller.signal.removeEventListener('abort', abort)
360
+ readable.destroy()
361
+ }
362
+ }
363
+ function open($task) {
364
+ ff_core_Task.Task_throwIfAborted($task)
365
+ task = $task
366
+ readable = createReadStream_()
367
+ readable.on('readable', () => {
368
+ if(doResolve != null) doResolve()
369
+ })
370
+ readable.on('error', error => {
371
+ task.controller.signal.removeEventListener('abort', abort)
372
+ seenError = error
373
+ if(doReject != null) doReject(error)
374
+ })
375
+ readable.on('close', () => {
376
+ task.controller.signal.removeEventListener('abort', abort)
377
+ if(doResolve != null) doResolve()
378
+ })
379
+ $task.controller.signal.addEventListener('abort', abort)
380
+ }
381
+ return ff_core_Stream.Stream(async function go($task) {
382
+ if(task == null) open($task)
383
+ let buffer = readable.read()
384
+ if(buffer != null) return ff_core_Option.Some(new DataView(buffer.buffer, buffer.byteOffset, buffer.length))
385
+ if(seenError != null) throw seenError
386
+ if(readable.destroyed) return ff_core_Option.None()
387
+ let promise = new Promise((resolve, reject) => {
388
+ doResolve = () => {doResolve = null; doReject = null; resolve()}
389
+ doReject = error => {doResolve = null; doReject = null; reject(error)}
390
+ }).then(() => go($task))
391
+ return await promise
392
+ }, abort)
393
+ """
package/core/RbMap.ff ADDED
@@ -0,0 +1,216 @@
1
+ // Based on https://www.cs.kent.ac.uk/people/staff/smk/redblack/Untyped.hs
2
+
3
+ data Color {
4
+ R
5
+ B
6
+ }
7
+
8
+ data RB[K, V] {
9
+ E
10
+ T(color: Color, left: RB[K, V], key: K, value: V, right: RB[K, V])
11
+ }
12
+
13
+ insert[K: Order, V](x: K, xv: V, s: RB[K, V]): RB[K, V] {
14
+ function ins(s: RB[K, V]): RB[K, V] {
15
+ | E => T(R, E, x, xv, E)
16
+ | T(B, a, y, yv, b) => Ordering.compare(x, y).{
17
+ | OrderingBefore => balance(ins(a), y, yv, b)
18
+ | OrderingAfter => balance(a, y, yv, ins(b))
19
+ | OrderingSame => T(B, a, x, xv, b)
20
+ }
21
+ | T(R, a, y, yv, b) => Ordering.compare(x, y).{
22
+ | OrderingBefore => T(R, ins(a), y, yv, b)
23
+ | OrderingAfter => T(R, a, y, yv, ins(b))
24
+ | OrderingSame => T(R, a, x, xv, b)
25
+ }
26
+ }
27
+
28
+ ins(s).{
29
+ | E => panic("Unexpected empty tree")
30
+ | T(_, a, z, zv, b) => T(B, a, z, zv, b)
31
+ }
32
+ }
33
+
34
+ member[K: Order, V](key: K, tree: RB[K, V]): Bool {
35
+ | x, E => False
36
+ | x, T(_, a, y, _, b,) => Ordering.compare(x, y).{
37
+ | OrderingBefore => member(x, a)
38
+ | OrderingAfter => member(x, b)
39
+ | OrderingSame => True
40
+ }
41
+ }
42
+
43
+ balance[K: Order, V](tree1: RB[K, V], key: K, value: V, tree2: RB[K, V]): RB[K, V] {
44
+ | T(R, a, x, xv, b), y, yv, T(R, c, z, zv, d) => T(R, T(B, a, x, xv, b), y, yv, T(B, c, z, zv, d))
45
+ | T(R, T(R, a, x, xv, b), y, yv, c), z, zv, d => T(R, T(B, a, x, xv, b), y, yv, T(B, c, z, zv, d))
46
+ | T(R, a, x, xv, T(R, b, y, yv, c)), z, zv, d => T(R, T(B, a, x, xv, b), y, yv, T(B, c, z, zv, d))
47
+ | a, x, xv, T(R, b, y, yv, T(R, c, z, zv, d)) => T(R, T(B, a, x, xv, b), y, yv, T(B, c, z, zv, d))
48
+ | a, x, xv, T(R, T(R, b, y, yv, c), z, zv, d) => T(R, T(B, a, x, xv, b), y, yv, T(B, c, z, zv, d))
49
+ | a, x, xv, b => T(B, a, x, xv, b)
50
+ }
51
+
52
+ delete[K: Order, V](x: K, t: RB[K, V]): RB[K, V] {
53
+ function del(ss: RB[K, V]): RB[K, V] {
54
+ | E => E
55
+ | T(_, a, y, yv, b) => Ordering.compare(x, y).{
56
+ | OrderingBefore => delformLeft(a, y, yv, b)
57
+ | OrderingAfter => delformRight(a, y, yv, b)
58
+ | OrderingSame => app(a, b)
59
+ }
60
+ }
61
+
62
+ function delformLeft(left: RB[K, V], key: K, value: V, right: RB[K, V]): RB[K, V] {
63
+ | T(B, _, _, _, _), y, yv, b => balleft(del(left), y, yv, b)
64
+ | a, y, yv, b => T(R, del(a), y, yv, b)
65
+ }
66
+
67
+ function delformRight(left: RB[K, V], key: K, value: V, right: RB[K, V]): RB[K, V] {
68
+ | a, y, yv, T(B, _, _, _, _) => balright(a, y, yv, del(right))
69
+ | a, y, yv, b => T(R, a, y, yv, del(b))
70
+ }
71
+
72
+ del(t).{
73
+ | T(_, a, y, yv, b) => T(B, a, y, yv, b)
74
+ | _ => E
75
+ }
76
+ }
77
+
78
+ balleft[K: Order, V](tree1: RB[K, V], key: K, value: V, tree2: RB[K, V]): RB[K, V] {
79
+ | T(R, a, x, xv, b), y, yv, c => T(R, T(B, a, x, xv, b), y, yv, c)
80
+ | bl, x, xv, T(B, a, y, yv, b) => balance(bl, x, xv, T(R, a, y, yv, b))
81
+ | bl, x, xv, T(R, T(B, a, y, yv, b), z, zv, c) => T(R, T(B, bl, x, xv, a), y, yv, (balance(b, z, zv, sub1(c))))
82
+ | _, _, _, _ => panic("Unexhaustive match in balleft")
83
+ }
84
+
85
+ balright[K: Order, V](tree1: RB[K, V], key: K, value: V, tree2: RB[K, V]): RB[K, V] {
86
+ | a, x, xv, T(R, b, y, yv, c) => T(R, a, x, xv, T(B, b, y, yv, c))
87
+ | T(B, a, x, xv, b), y, yv, bl => balance(T(R, a, x, xv, b), y, yv, bl)
88
+ | T(R, a, x, xv, T(B, b, y, yv, c)), z, zv, bl => T(R, balance(sub1(a), x, xv, b), y, yv, T(B, c, z, zv, bl))
89
+ | _, _, _, _ => panic("Unexhaustive match in balright")
90
+ }
91
+
92
+ sub1[K: Order, V](tree: RB[K, V]): RB[K, V] {
93
+ | T(B, a, x, xv, b) => T(R, a, x, xv, b)
94
+ | _ => panic("invariance violation")
95
+ }
96
+
97
+ app[K: Order, V](tree1: RB[K, V], tree2: RB[K, V]): RB[K, V] {
98
+ | E, b => b
99
+ | a, E => a
100
+ | T(R, a, x, xv, b), T(R, c, y, yv, d) =>
101
+ app(b, c).{
102
+ | T(R, b2, z, zv, c2) => T(R, T(R, a, x, xv, b2), z, zv, T(R, c2, y, yv, d))
103
+ | bc => T(R, a, x, xv, T(R, bc, y, yv, d))
104
+ }
105
+ | T(B, a, x, xv, b), T(B, c, y, yv, d) =>
106
+ app(b, c).{
107
+ | T(R, b2, z, zv, c2) => T(R, T(B, a, x, xv, b2), z, zv, T(B, c2, y, yv, d))
108
+ | bc => balleft(a, x, xv, T(B, bc, y, yv, d))
109
+ }
110
+ | a, T(R, b, x, xv, c) => T(R, app(a, b), x, xv, c)
111
+ | T(R, a, x, xv, b), c => T(R, a, x, xv, app(b, c))
112
+ }
113
+
114
+ extend self[K: Order, V]: RB[K, V] {
115
+
116
+ get(key: K): Option[V] {
117
+ self.{
118
+ | E_ => None
119
+ | T(_, a, y, yv, b) => Ordering.compare(key, y).{
120
+ | OrderingBefore => a.get(key)
121
+ | OrderingAfter => b.get(key)
122
+ | OrderingSame => Some(yv)
123
+ }
124
+ }
125
+ }
126
+
127
+ size(): Int {
128
+ self.{
129
+ | E => 0
130
+ | T(_, l, _, _, r) => l.size() + 1 + r.size()
131
+ }
132
+ }
133
+
134
+ pairs(): List[Pair[K, V]] {
135
+ mutable result = []
136
+ self.each {k, v =>
137
+ result = [Pair(k, v), ...result]
138
+ }
139
+ result.reverse()
140
+ }
141
+
142
+ toStream(cycle: Bool): Stream[Pair[K, V]] {
143
+ mutable stack = [self]
144
+ function next(): Option[Pair[K, V]] {
145
+ stack.{
146
+ | [] =>
147
+ if(cycle && self.{| E => False | _ => True}) {
148
+ stack = [self]
149
+ tailcall next()
150
+ } else {
151
+ None
152
+ }
153
+ | [E, ...tail] =>
154
+ stack = tail
155
+ tailcall next()
156
+ | [T(_, E, k, v, E), ...tail] =>
157
+ stack = tail
158
+ Some(Pair(k, v))
159
+ | [T(_, l, k, v, r), ...tail] =>
160
+ stack = [l, T(B, E, k, v, E), r, ...tail]
161
+ tailcall next()
162
+ }
163
+ }
164
+ Stream.make(next)
165
+ }
166
+
167
+ each(body: (K, V) => Unit): Unit {
168
+ self.{
169
+ | E =>
170
+ | T(_, l, k, v, r) =>
171
+ l.each(body)
172
+ body(k, v)
173
+ r.each(body)
174
+ }
175
+ }
176
+
177
+ eachWhile(body: (K, V) => Bool): Bool {
178
+ self.{
179
+ | E =>
180
+ True
181
+ | T(_, l, k, v, r) =>
182
+ l.eachWhile(body) &&
183
+ body(k, v) &&
184
+ r.eachWhile(body)
185
+ }
186
+ }
187
+
188
+ map[K2: Order, V2](body: (K, V) => Pair[K2, V2]): RB[K2, V2] {
189
+ mutable result = E
190
+ self.each {k, v =>
191
+ let pair = body(k, v)
192
+ result = insert(pair.first, pair.second, result)
193
+ }
194
+ result
195
+ }
196
+
197
+ mapValues[V2](body: (K, V) => V2): RB[K, V2] {
198
+ self.{
199
+ | E => E
200
+ | T(c, l, k, v, r) =>
201
+ T(c, l.mapValues(body), k, body(k, v), r.mapValues(body))
202
+ }
203
+ }
204
+
205
+ find(body: (K, V) => Bool): Option[Pair[K, V]] {
206
+ mutable result = None
207
+ self.eachWhile {k, v =>
208
+ if(body(k, v)) {
209
+ result = Some(Pair(k, v))
210
+ False
211
+ } else {True}
212
+ }
213
+ result
214
+ }
215
+
216
+ }