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/Task.ff ADDED
@@ -0,0 +1,138 @@
1
+ capability Task {}
2
+
3
+ extend self: Task {
4
+ // Spawns a task running body. The return value as well as the argument to body is the task handle.
5
+ // Automatically aborts and then joins subtasks when body returns or throws an unhandled exception.
6
+ // If body throws, the parent task is also aborted with the dueToSubtask flag set to true.
7
+ spawn(body: Task => Unit): Task
8
+ target js async """
9
+ return ff_core_Task.Task_spawn(self_, body_)
10
+ """
11
+ target js sync """
12
+ ff_core_Task.Task_throwIfAborted(self_)
13
+ const task = {controller: new AbortController(), subtasks: new Set(), started: performance.now() * 0.001}
14
+ self_.subtasks.add(task)
15
+ task.promise = Promise.resolve(task).then(async () => {
16
+ try {
17
+ await body_(task, task)
18
+ } catch(e) {
19
+ await ff_core_Task.Task_abort$(self_)
20
+ throw e
21
+ } finally {
22
+ for(const subtask of task.subtasks) subtask.controller.abort()
23
+ await Promise.allSettled([...task.subtasks].map(subtask => subtask.promise))
24
+ self_.subtasks.delete(task)
25
+ }
26
+ })
27
+ return task
28
+ """
29
+
30
+ // If the aborted flag is set for the current task, clears it and throws TaskAbortedException.
31
+ // You don't normally need to call this, but you might want to before doing an expensive computation.
32
+ throwIfAborted(): Unit
33
+ target js async """
34
+ ff_core_Task.Task_throwIfAborted(self_)
35
+ """
36
+ target js sync """
37
+ if(self_.controller.signal.aborted) {
38
+ const signal = self_.controller.signal
39
+ self_.controller = new AbortController()
40
+ signal.throwIfAborted()
41
+ }
42
+ """
43
+
44
+ // Sets the tasks aborted flag, which causes the ongoing/next async call to throw TaskAbortedException.
45
+ abort(): Unit
46
+ target js async """
47
+ self_.controller.abort()
48
+ """
49
+
50
+ // Create a blocking channel with the specified capacity. The channel is not tied to the task.
51
+ channel[T](capacity: Int = 0): Channel[T]
52
+ target js async """return ff_core_Task.Task_channel(capacity_)"""
53
+ target js sync """return {capacity: capacity_, buffer: [], readers: new Set(), writers: new Set()}"""
54
+
55
+ // Create a mutex. The mutex is not tied to the task.
56
+ lock(): Lock
57
+ target js async """return {owner: null, level: 0, stack: [], queue: []}"""
58
+
59
+ now(): Instant
60
+ target js sync "return Date.now() * 0.001"
61
+ target js async "return Date.now() * 0.001" // TODO: Mark now() as sync and remove async version
62
+
63
+ elapsed(): Duration
64
+ target js sync "return performance.now() * 0.001 - self_.started"
65
+ target js async "return performance.now() * 0.001 - self_.started" // TODO: Mark sync and remove async version
66
+
67
+ time[R](body: () => R): Pair[R, Duration] {
68
+ let start = self.elapsed()
69
+ let result = body()
70
+ let stop = self.elapsed()
71
+ let duration = Duration(stop.seconds - start.seconds)
72
+ Pair(result, duration)
73
+ }
74
+
75
+ }
76
+
77
+ // Convenience methods
78
+ extend self: Task {
79
+
80
+ sleep(duration: Duration): Unit {
81
+ Channel.
82
+ readOr(self.channel()) {_ => }.
83
+ timeout(duration) {}
84
+ }
85
+
86
+ all[T](tasks: List[() => T]): List[T] {
87
+ let successChannel = self.channel()
88
+ let failureChannel = self.channel()
89
+ self.spawn {t =>
90
+ let channel = t.channel()
91
+ try {
92
+ tasks.pairs().each {| Pair(i, task) =>
93
+ t.spawn {_ =>
94
+ channel.write(Pair(i, task()))
95
+ }
96
+ }
97
+ let result = tasks.map {_ =>
98
+ channel.read()
99
+ }.sortBy {_.first}.map {_.second}
100
+ successChannel.write(result)
101
+ } catchAny {error =>
102
+ failureChannel.write(error)
103
+ t.abort()
104
+ } grab()
105
+ }
106
+ Channel.
107
+ readOr(successChannel, {_}).
108
+ readOr(failureChannel, {_.rethrow()}).
109
+ wait()
110
+ }
111
+
112
+ race[T](tasks: List[() => T]): T {
113
+ let successChannel = self.channel()
114
+ let failureChannel = self.channel()
115
+ mutable live = tasks.size()
116
+ let started = tasks.map {task =>
117
+ self.spawn {_ =>
118
+ try {
119
+ successChannel.write(task())
120
+ } catchAny {e =>
121
+ live -= 1 // Not thread safe (but OK in JS)
122
+ if(live == 0) {
123
+ failureChannel.write(e)
124
+ }
125
+ } grab()
126
+ }
127
+ }
128
+ try {
129
+ Channel.
130
+ readOr(successChannel, {_}).
131
+ readOr(failureChannel, {_.rethrow()}).
132
+ wait()
133
+ } finally {
134
+ started.each {_.abort()}
135
+ } grab()
136
+ }
137
+
138
+ }
package/core/Try.ff ADDED
@@ -0,0 +1,81 @@
1
+ data Try[T] {
2
+ Success(value: T)
3
+ Failure(error: Error)
4
+ }
5
+
6
+ extend self[T]: Try[T] {
7
+
8
+ map[S](body: T => S): Try[S] {
9
+ self.{
10
+ | Success(value) => try {body(value)}
11
+ | Failure(error) => Failure(error)
12
+ }
13
+ }
14
+
15
+ flatMap[S](body: T => Try[S]): Try[S] {
16
+ self.map(body).flatten()
17
+ }
18
+
19
+ catch[E: HasAnyTag](body: (E, Error) => T): Try[T] {
20
+ self.{
21
+ | Failure(error) {error.exception().flatMap(Any.fromAny) | Some(e)} => try {body(e, error)}
22
+ | _ => self
23
+ }
24
+ }
25
+
26
+ catchAny(body: Error => T): Try[T] {
27
+ self.{
28
+ | Failure(error) => try {body(error)}
29
+ | _ => self
30
+ }
31
+ }
32
+
33
+ finally(body: () => Unit): Try[T] {
34
+ self.{
35
+ | Success(value) => try {body(); value}
36
+ | Failure(_) =>
37
+ try {body()}.{
38
+ | Success(_) => self
39
+ | Failure(error) => Failure(error)
40
+ }
41
+ }
42
+ }
43
+
44
+ else(body: () => T): T {
45
+ self.{
46
+ | Success(value) => value
47
+ | Failure(_) => body()
48
+ }
49
+ }
50
+
51
+ grab(): T {
52
+ self.{
53
+ | Success(value) => value
54
+ | Failure(error) => error.rethrow()
55
+ }
56
+ }
57
+
58
+ toOption(): Option[T] {
59
+ self.{
60
+ | Success(value) => Some(value)
61
+ | Failure(_) => None
62
+ }
63
+ }
64
+
65
+ }
66
+
67
+ extend self[T]: Try[Try[T]] {
68
+
69
+ flatten(): Try[T] {
70
+ self.{
71
+ | Success(Success(_)@t) => t
72
+ | Success(Failure(_)@t) => t
73
+ | Failure(error) => Failure(error)
74
+ }
75
+ }
76
+
77
+ }
78
+
79
+ internalThrowGrabException[T](): T {
80
+ throw(GrabException())
81
+ }
package/core/Unit.ff ADDED
@@ -0,0 +1,3 @@
1
+ data Unit {
2
+ Unit
3
+ }
@@ -0,0 +1,44 @@
1
+ // Two fields, zero fields and a particular field
2
+
3
+ data GFields[A, B](
4
+ first: A
5
+ second: B
6
+ )
7
+
8
+ data GNoFields()
9
+
10
+ data GField[S, V](value: V)
11
+
12
+
13
+ // Two constructors, zero constructors and a particular constructor
14
+
15
+ data GConstructors[L, R] {
16
+ GLeft(value: L)
17
+ GRight(value: R)
18
+ }
19
+
20
+ data GNoConstructors {}
21
+
22
+ data GConstructor[S, V](value: V)
23
+
24
+ trait T: Generic[R] {
25
+ toGeneric(value: T): R
26
+ fromGeneric(generic: R): T
27
+ }
28
+
29
+ data Person(name : String, age : Int)
30
+
31
+ // Mål: Show på Person
32
+ // Vej: Person -> R -> String
33
+
34
+ // instance Person: Generic[GType[_, GConstructor[_, GFields[GField[_, String], GField[_, Int]]]]]
35
+
36
+ trait T: Show {
37
+ show(value: T): String
38
+ }
39
+
40
+ instance GFields[A: Show, B: Show]: Show {
41
+ show(v) { show(v.first) + ", " + show(v.second) }
42
+ }
43
+
44
+ person_show_GFields[A: Show, B: Show](a : A, b : B) = show(a) + ", " + show(b)
@@ -0,0 +1,68 @@
1
+ import Syntax
2
+
3
+ data Async()
4
+
5
+ make(): Async {
6
+ Async()
7
+ }
8
+
9
+ extend self: Async {
10
+
11
+ groupRecursive(functions: List[DFunction]) : List[List[DFunction]] {
12
+
13
+ }
14
+
15
+ checkRecursive(functions: List[List[DFunction]]) : List[DFunction] {
16
+ // function f(x) {}
17
+ f : $1 -> $2
18
+ --
19
+ f : forall a. a -> Unit
20
+
21
+ // function g() { f(42); h(False) }
22
+ // function h(y) { if(y) g() }
23
+ g : () -> $3
24
+ h : $4 -> $5
25
+ --
26
+ g : () -> Unit
27
+ h : Bool -> Unit
28
+ }
29
+
30
+ type Quux[A, B, s](f: A =s> B)
31
+ type Baz[s1, s2](quux: Quux[String, Int =s1> Bool, s2])
32
+
33
+ type Foo[s](f: Int =s> String)
34
+ type Bar[s](foo: Foo[s])
35
+
36
+ process(term: Term): Term {
37
+ | ELet e => e.ELet(value = self.fixWildcards(e.value), body = self.fixWildcards(e.body))
38
+ | ESequential e => e.ESequential(before = self.fixWildcards(e.before), after = self.fixWildcards(e.after))
39
+ | EAssign e => e.EAssign(value = self.fixWildcards(e.value))
40
+ | EAssignField e => e.EAssignField(record = self.fixWildcards(e.record), value = self.fixWildcards(e.value))
41
+ | EPipe e => e.EPipe(value = self.fixWildcards(e.value), function = self.fixWildcards(e.function))
42
+ | ECall e =>
43
+ e.ECall(
44
+ function = self.fixWildcards(e.function),
45
+ arguments = e.arguments.map { a => a.Argument(value = self.fixWildcards(a.value)) }
46
+ )
47
+ | EList e =>
48
+ e.EList(items = e.items.map { | Pair(item, spread) =>
49
+ Pair(self.fixWildcards(item), spread)
50
+ })
51
+ | ECopy e =>
52
+ e.ECopy(
53
+ record = self.fixWildcards(e.record),
54
+ arguments = e.arguments.map { a => a.Field(value = self.fixWildcards(a.value)) }
55
+ )
56
+ | EVariant e =>
57
+ e.EVariant(arguments = e.arguments.map { _.map { a =>
58
+ a.Argument(value = self.fixWildcards(a.value))
59
+ }})
60
+ | ERecord e => e.ERecord(fields = e.fields.map { a => a.Field(value = self.fixWildcards(a.value)) })
61
+ | EField e => e.EField(record = self.fixWildcards(e.record))
62
+ | EWildcard e =>
63
+ self.seenWildcards += 1
64
+ e.EWildcard(index = self.seenWildcards)
65
+ | _ => term
66
+ }
67
+
68
+ }
@@ -0,0 +1,77 @@
1
+ data DataView {}
2
+
3
+ make(size: Int, shared: Bool = False): Buffer2
4
+ target js sync "return new DataView(shared_ ? new SharedArrayBuffer(size_) : new ArrayBuffer(size_))"
5
+
6
+ extend self: Buffer2 {
7
+
8
+ size(): Int
9
+ target js sync "return self_.byteLength"
10
+
11
+ shared(): Bool
12
+ target js sync "return typeof SharedArrayBuffer !== 'undefined' && self_.buffer instanceof SharedArrayBuffer"
13
+
14
+ grabBigInt64(byteOffset: Int, littleEndian: Bool = False): BigInt
15
+ target js sync "return self_.getBigInt64(byteOffset_, littleEndian_)"
16
+
17
+ grabBigUint64(byteOffset: Int, littleEndian: Bool = False): BigInt
18
+ target js sync "return self_.getBigUint64(byteOffset_, littleEndian_)"
19
+
20
+ grabFloat32(byteOffset: Int, littleEndian: Bool = False): Float
21
+ target js sync "return self_.getFloat32(byteOffset_, littleEndian_)"
22
+
23
+ grabFloat64(byteOffset: Int, littleEndian: Bool = False): Float
24
+ target js sync "return self_.getFloat64(byteOffset_, littleEndian_)"
25
+
26
+ grabInt16(byteOffset: Int, littleEndian: Bool = False): Int
27
+ target js sync "return self_.getInt16(byteOffset_, littleEndian_)"
28
+
29
+ grabInt32(byteOffset: Int, littleEndian: Bool = False): Int
30
+ target js sync "return self_.getInt32(byteOffset_, littleEndian_)"
31
+
32
+ grabInt8(byteOffset: Int, littleEndian: Bool = False): Int
33
+ target js sync "return self_.getInt8(byteOffset_, littleEndian_)"
34
+
35
+ grabUint16(byteOffset: Int, littleEndian: Bool = False): Int
36
+ target js sync "return self_.getUint16(byteOffset_, littleEndian_)"
37
+
38
+ grabUint32(byteOffset: Int, littleEndian: Bool = False): Int
39
+ target js sync "return self_.getUint32(byteOffset_, littleEndian_)"
40
+
41
+ grabUint8(byteOffset: Int, littleEndian: Bool = False): Int
42
+ target js sync "return self_.getUint8(byteOffset_, littleEndian_)"
43
+
44
+ setBigInt64(byteOffset: Int, value: BigInt, littleEndian: Bool = False): Unit
45
+ target js sync "self_.setBigInt64(byteOffset_, littleEndian_)"
46
+
47
+ setBigUint64(byteOffset: Int, value: BigInt, littleEndian: Bool = False): Unit
48
+ target js sync "self_.setBigUint64(byteOffset_, littleEndian_)"
49
+
50
+ setFloat32(byteOffset: Int, value: Float, littleEndian: Bool = False): Unit
51
+ target js sync "self_.setFloat32(byteOffset_, littleEndian_)"
52
+
53
+ setFloat64(byteOffset: Int, value: Float, littleEndian: Bool = False): Unit
54
+ target js sync "self_.setFloat64(byteOffset_, littleEndian_)"
55
+
56
+ setInt16(byteOffset: Int, value: Int, littleEndian: Bool = False): Unit
57
+ target js sync "self_.setInt16(byteOffset_, littleEndian_)"
58
+
59
+ setInt32(byteOffset: Int, value: Int, littleEndian: Bool = False): Unit
60
+ target js sync "self_.setInt32(byteOffset_, littleEndian_)"
61
+
62
+ setInt8(byteOffset: Int, value: Int, littleEndian: Bool = False): Unit
63
+ target js sync "self_.setInt8(byteOffset_, littleEndian_)"
64
+
65
+ setUint16(byteOffset: Int, value: Int, littleEndian: Bool = False): Unit
66
+ target js sync "self_.setUint16(byteOffset_, littleEndian_)"
67
+
68
+ setUint32(byteOffset: Int, value: Int, littleEndian: Bool = False): Unit
69
+ target js sync "self_.setUint32(byteOffset_, littleEndian_)"
70
+
71
+ setUint8(byteOffset: Int, value: Int, littleEndian: Bool = False): Unit
72
+ target js sync "self_.setUint8(byteOffset_, littleEndian_)"
73
+
74
+ slice(begin: Int, end: Int): Buffer2
75
+ target js sync "return new DataView(self_.buffer.slice(begin, end))"
76
+
77
+ }
@@ -0,0 +1,12 @@
1
+ main(system: NodeSystem) {
2
+ let outputFileName = system.arguments().grabFirst()
3
+ let fileNames = system.arguments().dropFirst()
4
+ let result = cat(system.files(), fileNames)
5
+ system.files().writeStream(outputFileName, result)
6
+ }
7
+
8
+ cat(fs: FileSystem, fileNames: Array[String]): Stream[Buffer] {
9
+ fileNames.toStream().flatMap {fileName =>
10
+ fs.readStream(fileName)
11
+ }
12
+ }
@@ -0,0 +1,52 @@
1
+ data JsValue {}
2
+
3
+ data Dictionary[K, V] {}
4
+
5
+ trait K: DictionaryKey {
6
+ add[V](js: JsValue, key: K, value: V): Unit
7
+ has(js: JsValue, key: K): Bool
8
+ grab[V](js: JsValue, key: K): V
9
+ }
10
+
11
+ instance Int: DictionaryKey {
12
+ add[V](js: JsValue, key: Int, value: V): Unit
13
+ target js sync "js_.set(key_, value_)"
14
+ has(js: JsValue, key: Int): Bool
15
+ target js sync "return js_.has(key_)"
16
+ get[V](js: JsValue, key: Int): Option[V]
17
+ target js sync "return js_.has(key_) ? ff_core_Option.Some(js_.get(key_)) : ff_core_Option.None()"
18
+ }
19
+
20
+ instance String: DictionaryKey {
21
+ add[V](js: JsValue, key: String, value: V): Unit
22
+ target js sync "js_.set(key_, value_)"
23
+ has(js: JsValue, key: String): Bool
24
+ target js sync "return js_.has(key_)"
25
+ get[V](js: JsValue, key: String): Option[V]
26
+ target js sync "return js_.has(key_) ? ff_core_Option.Some(js_.get(key_)) : ff_core_Option.None()"
27
+ }
28
+
29
+ instance Pair[A: DictionaryKey, B: DictionaryKey]: DictionaryKey {
30
+ add[V](basic: JsDictionary, key: Pair[A, B], value: V): Unit
31
+ javascript """
32
+ let inner = basic_.get(key_.first_)
33
+ if(inner === undefined) {
34
+ inner = new Map()
35
+ }
36
+ basic_.set(key_.first_, )
37
+ """
38
+ has(basic: JsDictionary, key: Pair[A, B]): Bool
39
+ javascript """
40
+ return basic_.has(key_)
41
+ """
42
+ get[V](basic: JsDictionary, key: Pair[A, B]): Option[V]
43
+ javascript """
44
+ return basic_.has(key_) ? ff_core_Option.Some(basic_.get(key_)) : ff_core_Option.None()
45
+ """
46
+ }
47
+
48
+ extend self[K: DictionaryKey, V]: Dictionary[K, V] {
49
+ add(key: K, value: V): Unit {
50
+
51
+ }
52
+ }
@@ -0,0 +1,46 @@
1
+ trait Show[T] {
2
+ show(value: T): String
3
+ }
4
+
5
+ instance Show[List[T: Show]] {
6
+ show(value: List[T]) {
7
+ value.map { show(_) }.join(", ")
8
+ }
9
+ }
10
+
11
+ map[A, B](list: List[A], body: A => B): List[B] {
12
+ | Empty, _ => Empty
13
+ | Link(head, tail), _ => Link(body(head), map(tail, body))
14
+ }
15
+
16
+ data Stack {
17
+ EmptyStack
18
+ PushStack(value: Int, stack: Stack)
19
+ }
20
+
21
+ extend stack: Stack {
22
+ map(body: Int => Int): Stack {
23
+ switch(stack) {
24
+ | EmptyStack => EmptyStack
25
+ | PushStack s => PushStack(body(s.value), s.stack.map(body))
26
+ }
27
+ }
28
+ }
29
+
30
+ user: (name: String, email: String) = (name = "Joe", email = "jj@example.com")
31
+
32
+ load(files: FileSystem, file1: String, file2: String): String {
33
+ try {
34
+ files.readText(file1) ++
35
+ files.readText(file2)
36
+ } catch(FileNotFound?) { e =>
37
+ ""
38
+ } grab
39
+ }
40
+
41
+ data FileException(file: String) {
42
+ FileNotFound
43
+ AccessDenied
44
+ }
45
+
46
+ instance Exceptional[FileException]
@@ -0,0 +1,102 @@
1
+ // Haskell-like Generic programming. Thanks to nathanf for instructions.
2
+
3
+ // Two fields, zero fields and a particular field
4
+
5
+ data GFields[A, B](
6
+ first: A
7
+ second: B
8
+ )
9
+
10
+ data GNoFields()
11
+
12
+ data GField[S, V](value: V)
13
+
14
+
15
+ // Two constructors, zero constructors and a particular constructor
16
+
17
+ data GConstructors[L, R] {
18
+ GLeft(value: L)
19
+ GRight(value: R)
20
+ }
21
+
22
+ data GNoConstructors {}
23
+
24
+ data GConstructor[S, V](value: V)
25
+
26
+
27
+ // Type declarations
28
+
29
+ data GType[S, C](constructors: C)
30
+
31
+
32
+ // Names and such
33
+
34
+ trait S: GFieldSymbol {
35
+ fieldName(): String
36
+ }
37
+
38
+ trait S: GConstructorSymbol {
39
+ constructorName(): String
40
+ }
41
+
42
+ trait S: GTypeSymbol {
43
+ typeName(): String
44
+ packageName(): String
45
+ moduleName(): String
46
+ }
47
+
48
+
49
+ // The type class that converts from/to the generic representation
50
+
51
+ trait T: Generic[R] {
52
+ toGeneric(value: T): R
53
+ fromGeneric(generic: R): T
54
+ }
55
+
56
+
57
+ // Example of implementing a generic instance of Show
58
+
59
+ instance GFields[A: Show, B: Show]: Show {
60
+ show(v) { show(v.first) + ", " + show(v.second) }
61
+ }
62
+
63
+ instance GNoFields: Show {
64
+ show(v) { "" }
65
+ }
66
+
67
+ instance GField[S: GFieldSymbol, V: Show]: Show {
68
+ show(v) { fieldName[S]() + " = " + show(v.value) }
69
+ }
70
+
71
+ instance GConstructors[A: Show, B: Show]: Show {
72
+ show(v) {
73
+ | GLeft(v) => show(v)
74
+ | GRight(v) => show(v)
75
+ }
76
+ }
77
+
78
+ instance GConstructor[S: GConstructorSymbol, V: Show]: Show {
79
+ show(v) { constructorName[S]() + "(" + show(v.value) + ")" }
80
+ }
81
+
82
+ instance GType[S, C: Show]: Show {
83
+ show(v) {
84
+ show(v.constructors)
85
+ }
86
+ }
87
+
88
+
89
+ // Example of using the generic instance of Show above
90
+
91
+ trait T: Show {
92
+ show(value: T): String {
93
+ show(toGeneric(value)) // Type checked at each instance, not in the trait (to allow T: Generic[R])
94
+ }
95
+ }
96
+
97
+ data User(id: Int, email: String)
98
+
99
+ instance User: Show
100
+
101
+
102
+ // Perhaps Generic is automatic, and the instance is only in scope where the constructors of the type are accessible.
@@ -0,0 +1,40 @@
1
+ // https://datatracker.ietf.org/doc/html/rfc8305#section-5
2
+
3
+ data Ip(ipAddress: String, seconds: Duration, succeed: Bool)
4
+
5
+ main(system: NodeSystem): Unit {
6
+ let ips = [
7
+ Ip("1.1.1.1", Duration(1.7), False)
8
+ Ip("2.2.2.2", Duration(0.4), False)
9
+ Ip("3.3.3.3", Duration(1.5), True)
10
+ Ip("4.4.4.4", Duration(0.6), True)
11
+ ]
12
+ let channel = system.tasks().channel(capacity = 2)
13
+ channel.write(Unit)
14
+ channel.write(Unit)
15
+ let winner = happyEyeballs(system.tasks(), channel, ips)
16
+ Log.debug(winner)
17
+ }
18
+
19
+ happyEyeballs(taskSystem: TaskSystem, channel: Channel[Unit], ips: List[Ip]): String {
20
+ let ip = ips.grabFirst()
21
+ let nextChannel = taskSystem.channel(capacity = 2)
22
+ taskSystem.race([
23
+ {
24
+ channel.read()
25
+ Channel.readOr(channel, {_}).timeout(Duration(0.5), {})
26
+ nextChannel.write(Unit)
27
+ try {
28
+ taskSystem.sleep(ip.seconds)
29
+ if(!ip.succeed) { panic("Network error") }
30
+ ip.ipAddress
31
+ } catchAny { error =>
32
+ nextChannel.write(Unit)
33
+ error.rethrow()
34
+ } grab()
35
+ }
36
+ {
37
+ happyEyeballs(taskSystem, nextChannel, ips.dropFirst())
38
+ }
39
+ ])
40
+ }