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/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,13 @@
1
+ data Bool {
2
+ False
3
+ True
4
+ }
5
+
6
+ extend self: Bool {
7
+ toInt(): Int {
8
+ self.{
9
+ | False => 0
10
+ | True => 1
11
+ }
12
+ }
13
+ }
@@ -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
+ }