firefly-compiler 0.5.39 → 0.5.40

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 (129) hide show
  1. package/.hintrc +4 -4
  2. package/.vscode/settings.json +4 -4
  3. package/bin/Release.ff +157 -157
  4. package/bin/firefly.mjs +1 -1
  5. package/compiler/Builder.ff +275 -275
  6. package/compiler/Compiler.ff +234 -234
  7. package/compiler/Dependencies.ff +186 -186
  8. package/compiler/DependencyLock.ff +17 -17
  9. package/compiler/JsEmitter.ff +1437 -1437
  10. package/compiler/LspHook.ff +202 -202
  11. package/compiler/ModuleCache.ff +178 -178
  12. package/compiler/Workspace.ff +88 -88
  13. package/core/.firefly/include/package.json +5 -5
  14. package/core/.firefly/package.ff +2 -2
  15. package/core/Any.ff +25 -25
  16. package/core/Array.ff +298 -298
  17. package/core/Atomic.ff +63 -63
  18. package/core/Box.ff +7 -7
  19. package/core/BrowserSystem.ff +40 -40
  20. package/core/BuildSystem.ff +156 -156
  21. package/core/Crypto.ff +94 -94
  22. package/core/Equal.ff +41 -41
  23. package/core/Error.ff +25 -25
  24. package/core/HttpClient.ff +142 -142
  25. package/core/Instant.ff +24 -24
  26. package/core/Js.ff +305 -305
  27. package/core/JsSystem.ff +135 -135
  28. package/core/Json.ff +423 -423
  29. package/core/List.ff +482 -482
  30. package/core/Lock.ff +108 -108
  31. package/core/NodeSystem.ff +198 -198
  32. package/core/Ordering.ff +160 -160
  33. package/core/Path.ff +377 -378
  34. package/core/Queue.ff +90 -90
  35. package/core/Random.ff +140 -140
  36. package/core/RbMap.ff +216 -216
  37. package/core/Show.ff +44 -44
  38. package/core/SourceLocation.ff +68 -68
  39. package/core/Task.ff +165 -165
  40. package/experimental/benchmarks/ListGrab.ff +23 -23
  41. package/experimental/benchmarks/ListGrab.java +55 -55
  42. package/experimental/benchmarks/Pyrotek45.ff +30 -30
  43. package/experimental/benchmarks/Pyrotek45.java +64 -64
  44. package/experimental/bidirectional/Bidi.ff +88 -88
  45. package/experimental/lines/Main.ff +40 -40
  46. package/experimental/random/Index.ff +53 -53
  47. package/experimental/random/Process.ff +120 -120
  48. package/experimental/random/RunLength.ff +65 -65
  49. package/experimental/random/Scrape.ff +51 -51
  50. package/experimental/random/Symbols.ff +73 -73
  51. package/experimental/random/Tensor.ff +52 -52
  52. package/experimental/random/Units.ff +36 -36
  53. package/experimental/s3/S3TestAuthorizationHeader.ff +39 -39
  54. package/experimental/s3/S3TestPut.ff +16 -16
  55. package/experimental/tests/TestJson.ff +26 -26
  56. package/firefly.sh +0 -0
  57. package/fireflysite/.firefly/package.ff +4 -4
  58. package/fireflysite/CommunityOverview.ff +20 -20
  59. package/fireflysite/CountingButtonDemo.ff +58 -58
  60. package/fireflysite/DocumentParser.ff +325 -325
  61. package/fireflysite/ExamplesOverview.ff +40 -40
  62. package/fireflysite/FrontPage.ff +344 -344
  63. package/fireflysite/GettingStarted.ff +45 -45
  64. package/fireflysite/Guide.ff +456 -456
  65. package/fireflysite/Main.ff +163 -163
  66. package/fireflysite/MatchingPasswordsDemo.ff +82 -82
  67. package/fireflysite/PackagesOverview.ff +49 -49
  68. package/fireflysite/PostgresqlDemo.ff +34 -34
  69. package/fireflysite/ReferenceAll.ff +18 -18
  70. package/fireflysite/ReferenceIntroduction.ff +11 -11
  71. package/fireflysite/Styles.ff +567 -567
  72. package/fireflysite/Test.ff +121 -121
  73. package/fireflysite/assets/markdown/reference/BaseTypes.md +209 -209
  74. package/fireflysite/assets/markdown/reference/EmittedJavascript.md +65 -65
  75. package/fireflysite/assets/markdown/reference/Exceptions.md +101 -101
  76. package/fireflysite/assets/markdown/reference/FunctionsAndMethods.md +364 -364
  77. package/fireflysite/assets/markdown/reference/JavascriptInterop.md +235 -235
  78. package/fireflysite/assets/markdown/reference/ModulesAndPackages.md +162 -162
  79. package/fireflysite/assets/markdown/reference/OldStructuredConcurrency.md +48 -48
  80. package/fireflysite/assets/markdown/reference/PatternMatching.md +224 -224
  81. package/fireflysite/assets/markdown/reference/StatementsAndExpressions.md +86 -86
  82. package/fireflysite/assets/markdown/reference/StructuredConcurrency.md +99 -99
  83. package/fireflysite/assets/markdown/reference/TraitsAndInstances.md +100 -100
  84. package/fireflysite/assets/markdown/reference/UserDefinedTypes.md +184 -184
  85. package/fireflysite/assets/markdown/scratch/ControlFlow.md +136 -136
  86. package/fireflysite/assets/markdown/scratch/Toc.md +40 -40
  87. package/lsp/.firefly/package.ff +1 -1
  88. package/lsp/CompletionHandler.ff +827 -827
  89. package/lsp/Handler.ff +714 -714
  90. package/lsp/HoverHandler.ff +79 -79
  91. package/lsp/LanguageServer.ff +272 -272
  92. package/lsp/SignatureHelpHandler.ff +55 -55
  93. package/lsp/SymbolHandler.ff +181 -181
  94. package/lsp/TestReferences.ff +17 -17
  95. package/lsp/TestReferencesCase.ff +7 -7
  96. package/lsp/stderr.txt +1 -1
  97. package/lsp/stdout.txt +34 -34
  98. package/lux/.firefly/package.ff +1 -1
  99. package/lux/Css.ff +648 -648
  100. package/lux/CssTest.ff +48 -48
  101. package/lux/Lux.ff +608 -608
  102. package/lux/LuxEvent.ff +79 -79
  103. package/lux/Main.ff +123 -123
  104. package/lux/Main2.ff +143 -143
  105. package/lux/TestDry.ff +28 -28
  106. package/output/js/ff/compiler/Builder.mjs +36 -36
  107. package/output/js/ff/core/Path.mjs +0 -2
  108. package/package.json +1 -1
  109. package/rpc/.firefly/package.ff +1 -1
  110. package/rpc/Rpc.ff +70 -70
  111. package/s3/.firefly/package.ff +1 -1
  112. package/s3/S3.ff +92 -92
  113. package/vscode/LICENSE.txt +21 -21
  114. package/vscode/Prepublish.ff +15 -15
  115. package/vscode/README.md +16 -16
  116. package/vscode/client/package-lock.json +544 -544
  117. package/vscode/client/package.json +22 -22
  118. package/vscode/client/src/extension.ts +104 -104
  119. package/vscode/icons/firefly-icon.svg +10 -10
  120. package/vscode/language-configuration.json +61 -61
  121. package/vscode/package-lock.json +3623 -3623
  122. package/vscode/package.json +1 -1
  123. package/vscode/snippets.json +241 -241
  124. package/vscode/syntaxes/firefly-markdown-injection.json +45 -45
  125. package/webserver/.firefly/include/package.json +5 -5
  126. package/webserver/.firefly/package.ff +2 -2
  127. package/webserver/WebServer.ff +647 -647
  128. package/websocket/.firefly/package.ff +1 -1
  129. package/websocket/WebSocket.ff +100 -100
@@ -1,99 +1,99 @@
1
- # Structured concurrency
2
-
3
- Firefly has a lightweight task system that supports structured concurrency and cancellation.
4
-
5
- Tasks are structured in a parent-child relationship, where the parent scope waits for all its child tasks to complete before proceeding.
6
-
7
- If the parent task or a sibling subtask fails with an uncaught exception, the other subtasks are cancelled.
8
-
9
-
10
- # Waiting for results
11
-
12
- A simple use case is to concurrently run some tasks and waiting for their results.
13
- This can be done without explicitly spawning tasks, as there's a utility method `task.mapList()` for this:
14
-
15
- ```firefly
16
- let results = system.mainTask().mapList(urls) {url =>
17
- system.httpClient().get(url) {_.readText()}
18
- }
19
- ```
20
-
21
- This fetches all of the URLs concurrently.
22
- If any fetch throws an exception, the other fetches are cancelled and `task.mapList()` rethrows an exception.
23
- Otherwise, the list of results is returned.
24
-
25
- Similarly, `task.raceList()` can be used to run some tasks concurrently, wait for the first one to complete, and cancel the others.
26
-
27
-
28
- # Spawning tasks
29
-
30
- A slightly more advanced use case is handling requests concurrently. It might look like this:
31
-
32
- ```firefly
33
- while {True} {
34
- let request = waitForRequest()
35
- system.mainTask().spawn {subtask =>
36
- handleRequest(subtask, request)
37
- }
38
- }
39
- ```
40
-
41
- The infinite loop here calls some function to wait for the next request.
42
- Then it spawns a subtask to handle the request, and loops back to waiting for the next request.
43
- The subtask executes concurrently, and thus doesn't block the loop while the request is being handled.
44
-
45
-
46
- # Channels
47
-
48
- Concurrently running tasks may need to communicate while executing.
49
- One mechanism for inter-task communication is the `Channel[T]` type, which represents an unbuffered multi-producer multi-consumer channel for messages of type `T`.
50
-
51
- A function to read URLs from a channel, fetch JSON from those URLs, and write the results to another channel could look like this:
52
-
53
- ```firefly
54
- fetchTask(in: Channel[String], out: Channel[Json]) {
55
- while {True} {
56
- let url = in.read()
57
- let result = system.httpClient().get(url) {_.readJson()}
58
- out.write(result)
59
- }
60
- }
61
- ```
62
-
63
- The `in.read()` call waits until there's a task ready to write to the `in` channel.
64
- Similarly, the `out.write()` call waits until there's a task ready to read from the `out` channel.
65
-
66
- To do multiple requests concurrently, spawn multiple instances of the task:
67
-
68
- ```firefly
69
- let in = system.mainTask().channel()
70
- let out = system.mainTask().channel()
71
- 1.to(3).each {_ =>
72
- system.mainTask().spawn {_ =>
73
- fetchTask(in, out)
74
- }
75
- }
76
- ```
77
-
78
- Consider calling an API that either returns `{value: ...}` where `...` is some number, or `{add: ...}` where `...` is a list of API URLs to add up to a total.
79
- A first attempt could be adding the following code:
80
-
81
- ```firefly
82
- mutable total = 0
83
- in.write("https://example.com/my-api")
84
- while {True} {
85
- let json = out.read()
86
- json.field("value").map {total += _.grabInt()}.else {
87
- let urls = json.field("add").map {_.grabArray().map {_.grabString()}}
88
- urls.each {url =>
89
- in.write(url)
90
- }
91
- }
92
- }
93
- ```
94
-
95
- However, there are two problems here:
96
-
97
- * If all the fetch tasks are waiting to write to the `out` channel, `in.write(url)` will block forever.
98
- * There's no logic to discover that there are no API calls left to do, so the `total` will never be reported.
99
-
1
+ # Structured concurrency
2
+
3
+ Firefly has a lightweight task system that supports structured concurrency and cancellation.
4
+
5
+ Tasks are structured in a parent-child relationship, where the parent scope waits for all its child tasks to complete before proceeding.
6
+
7
+ If the parent task or a sibling subtask fails with an uncaught exception, the other subtasks are cancelled.
8
+
9
+
10
+ # Waiting for results
11
+
12
+ A simple use case is to concurrently run some tasks and waiting for their results.
13
+ This can be done without explicitly spawning tasks, as there's a utility method `task.mapList()` for this:
14
+
15
+ ```firefly
16
+ let results = system.mainTask().mapList(urls) {url =>
17
+ system.httpClient().get(url) {_.readText()}
18
+ }
19
+ ```
20
+
21
+ This fetches all of the URLs concurrently.
22
+ If any fetch throws an exception, the other fetches are cancelled and `task.mapList()` rethrows an exception.
23
+ Otherwise, the list of results is returned.
24
+
25
+ Similarly, `task.raceList()` can be used to run some tasks concurrently, wait for the first one to complete, and cancel the others.
26
+
27
+
28
+ # Spawning tasks
29
+
30
+ A slightly more advanced use case is handling requests concurrently. It might look like this:
31
+
32
+ ```firefly
33
+ while {True} {
34
+ let request = waitForRequest()
35
+ system.mainTask().spawn {subtask =>
36
+ handleRequest(subtask, request)
37
+ }
38
+ }
39
+ ```
40
+
41
+ The infinite loop here calls some function to wait for the next request.
42
+ Then it spawns a subtask to handle the request, and loops back to waiting for the next request.
43
+ The subtask executes concurrently, and thus doesn't block the loop while the request is being handled.
44
+
45
+
46
+ # Channels
47
+
48
+ Concurrently running tasks may need to communicate while executing.
49
+ One mechanism for inter-task communication is the `Channel[T]` type, which represents an unbuffered multi-producer multi-consumer channel for messages of type `T`.
50
+
51
+ A function to read URLs from a channel, fetch JSON from those URLs, and write the results to another channel could look like this:
52
+
53
+ ```firefly
54
+ fetchTask(in: Channel[String], out: Channel[Json]) {
55
+ while {True} {
56
+ let url = in.read()
57
+ let result = system.httpClient().get(url) {_.readJson()}
58
+ out.write(result)
59
+ }
60
+ }
61
+ ```
62
+
63
+ The `in.read()` call waits until there's a task ready to write to the `in` channel.
64
+ Similarly, the `out.write()` call waits until there's a task ready to read from the `out` channel.
65
+
66
+ To do multiple requests concurrently, spawn multiple instances of the task:
67
+
68
+ ```firefly
69
+ let in = system.mainTask().channel()
70
+ let out = system.mainTask().channel()
71
+ 1.to(3).each {_ =>
72
+ system.mainTask().spawn {_ =>
73
+ fetchTask(in, out)
74
+ }
75
+ }
76
+ ```
77
+
78
+ Consider calling an API that either returns `{value: ...}` where `...` is some number, or `{add: ...}` where `...` is a list of API URLs to add up to a total.
79
+ A first attempt could be adding the following code:
80
+
81
+ ```firefly
82
+ mutable total = 0
83
+ in.write("https://example.com/my-api")
84
+ while {True} {
85
+ let json = out.read()
86
+ json.field("value").map {total += _.grabInt()}.else {
87
+ let urls = json.field("add").map {_.grabArray().map {_.grabString()}}
88
+ urls.each {url =>
89
+ in.write(url)
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ However, there are two problems here:
96
+
97
+ * If all the fetch tasks are waiting to write to the `out` channel, `in.write(url)` will block forever.
98
+ * There's no logic to discover that there are no API calls left to do, so the `total` will never be reported.
99
+
@@ -1,100 +1,100 @@
1
- # Traits and instances
2
-
3
- A trait defines an open set of types that support a common set of functions.
4
- For example, here's a trait for shapes with a common function to compute the area:
5
-
6
- ```firefly
7
- trait T: Shape {
8
- area(shape: T): Float
9
- }
10
- ```
11
-
12
- The function becomes a top level function `area[T: Shape](shape: T): Float`.
13
- Here `T` is a bounded type parameter: It can only be instantiated to a type that has an instance of the `Shape` trait.
14
-
15
- Consider these two types that would be good candidates for having an instance of the `Shape` trait:
16
-
17
- ```firefly
18
- data Circle(radius: Float)
19
- data Rectangle(width: Float, height: Float)
20
- ```
21
-
22
- Only types defined with the `data` or `newtype` keyword can have trait instances.
23
-
24
- Instances for these types can be created with the `instance` keyword as follows:
25
-
26
- ```firefly
27
- instance Circle: Shape {
28
- area(shape: Circle): Float {
29
- Float.pi() * (shape.radius ^ 2.0)
30
- }
31
- }
32
-
33
- instance Rectangle: Shape {
34
- area(shape: Rectangle): Float {
35
- shape.width * shape.height
36
- }
37
- }
38
- ```
39
-
40
- Each instance provides an implementation of `area` specific to the type.
41
-
42
- Here's an example of how to define a normal top level function with a bounded type parameter:
43
-
44
- ```firefly
45
- printArea[T: Shape](shape: T) {
46
- Log.trace("Area: " + area(shape))
47
- }
48
-
49
- printArea(Circle(0.0)) // Prints "Area: 0"
50
- printArea(Rectangle(5.0, 6.0)) // Prints "Area: 30"
51
- ```
52
-
53
- Multiple bounds are separated by colons, e.g. `foo[T: Bar: Baz]` means that `T` must have instances for both `Bar` and `Baz`.
54
-
55
-
56
- # Traits with type parameters
57
-
58
- Traits can have type parameters:
59
-
60
- ```firefly
61
- trait I: Rpc[O] {}
62
-
63
- instance MyMessage: Rpc[Int] {}
64
- ```
65
-
66
- The choice of `I` fully determines `O` - in this case, if `I` is `MyMessage`, then `O` is `Int`.
67
-
68
-
69
- # Automatic traits
70
-
71
- If instances for the following traits are not explicitly defined, they will be generated automatically.
72
- This only applies to types defined with the `data` or `newtype` keyword.
73
-
74
- ```firefly
75
- // Used for == !=
76
- trait T: Equal {
77
- equals(x: T, y: T): Bool
78
- }
79
-
80
- // Used for < > <= >= and sorting
81
- trait T: Order {
82
- compare(x: T, y: T): Ordering
83
- }
84
-
85
- // Used to display values for debugging
86
- trait T: Show {
87
- show(value: T): String
88
- }
89
-
90
- // Used for binary serialization
91
- trait T: Serializable {
92
- serializeUsing(serialization: Serialization, value: T): Unit
93
- deserializeUsing(serialization: Serialization): T
94
- }
95
-
96
- // Used for throwing and catching exceptions
97
- trait T: HasAnyTag {
98
- anyTag(): AnyTag[T]
99
- }
100
- ```
1
+ # Traits and instances
2
+
3
+ A trait defines an open set of types that support a common set of functions.
4
+ For example, here's a trait for shapes with a common function to compute the area:
5
+
6
+ ```firefly
7
+ trait T: Shape {
8
+ area(shape: T): Float
9
+ }
10
+ ```
11
+
12
+ The function becomes a top level function `area[T: Shape](shape: T): Float`.
13
+ Here `T` is a bounded type parameter: It can only be instantiated to a type that has an instance of the `Shape` trait.
14
+
15
+ Consider these two types that would be good candidates for having an instance of the `Shape` trait:
16
+
17
+ ```firefly
18
+ data Circle(radius: Float)
19
+ data Rectangle(width: Float, height: Float)
20
+ ```
21
+
22
+ Only types defined with the `data` or `newtype` keyword can have trait instances.
23
+
24
+ Instances for these types can be created with the `instance` keyword as follows:
25
+
26
+ ```firefly
27
+ instance Circle: Shape {
28
+ area(shape: Circle): Float {
29
+ Float.pi() * (shape.radius ^ 2.0)
30
+ }
31
+ }
32
+
33
+ instance Rectangle: Shape {
34
+ area(shape: Rectangle): Float {
35
+ shape.width * shape.height
36
+ }
37
+ }
38
+ ```
39
+
40
+ Each instance provides an implementation of `area` specific to the type.
41
+
42
+ Here's an example of how to define a normal top level function with a bounded type parameter:
43
+
44
+ ```firefly
45
+ printArea[T: Shape](shape: T) {
46
+ Log.trace("Area: " + area(shape))
47
+ }
48
+
49
+ printArea(Circle(0.0)) // Prints "Area: 0"
50
+ printArea(Rectangle(5.0, 6.0)) // Prints "Area: 30"
51
+ ```
52
+
53
+ Multiple bounds are separated by colons, e.g. `foo[T: Bar: Baz]` means that `T` must have instances for both `Bar` and `Baz`.
54
+
55
+
56
+ # Traits with type parameters
57
+
58
+ Traits can have type parameters:
59
+
60
+ ```firefly
61
+ trait I: Rpc[O] {}
62
+
63
+ instance MyMessage: Rpc[Int] {}
64
+ ```
65
+
66
+ The choice of `I` fully determines `O` - in this case, if `I` is `MyMessage`, then `O` is `Int`.
67
+
68
+
69
+ # Automatic traits
70
+
71
+ If instances for the following traits are not explicitly defined, they will be generated automatically.
72
+ This only applies to types defined with the `data` or `newtype` keyword.
73
+
74
+ ```firefly
75
+ // Used for == !=
76
+ trait T: Equal {
77
+ equals(x: T, y: T): Bool
78
+ }
79
+
80
+ // Used for < > <= >= and sorting
81
+ trait T: Order {
82
+ compare(x: T, y: T): Ordering
83
+ }
84
+
85
+ // Used to display values for debugging
86
+ trait T: Show {
87
+ show(value: T): String
88
+ }
89
+
90
+ // Used for binary serialization
91
+ trait T: Serializable {
92
+ serializeUsing(serialization: Serialization, value: T): Unit
93
+ deserializeUsing(serialization: Serialization): T
94
+ }
95
+
96
+ // Used for throwing and catching exceptions
97
+ trait T: HasAnyTag {
98
+ anyTag(): AnyTag[T]
99
+ }
100
+ ```