firefly-compiler 0.5.39 → 0.5.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.hintrc +4 -4
- package/.vscode/settings.json +4 -4
- package/bin/Release.ff +158 -157
- package/bin/firefly.mjs +1 -1
- package/compiler/Builder.ff +275 -275
- package/compiler/Compiler.ff +234 -234
- package/compiler/Dependencies.ff +186 -186
- package/compiler/DependencyLock.ff +17 -17
- package/compiler/JsEmitter.ff +1437 -1437
- package/compiler/LspHook.ff +202 -202
- package/compiler/ModuleCache.ff +178 -178
- package/compiler/Workspace.ff +88 -88
- package/core/.firefly/include/package.json +5 -5
- package/core/.firefly/package.ff +2 -2
- package/core/Any.ff +25 -25
- package/core/Array.ff +298 -298
- package/core/Atomic.ff +63 -63
- package/core/Box.ff +7 -7
- package/core/BrowserSystem.ff +40 -40
- package/core/BuildSystem.ff +156 -156
- package/core/Crypto.ff +94 -94
- package/core/Equal.ff +41 -41
- package/core/Error.ff +25 -25
- package/core/HttpClient.ff +142 -142
- package/core/Instant.ff +24 -24
- package/core/Js.ff +305 -305
- package/core/JsSystem.ff +135 -135
- package/core/Json.ff +423 -423
- package/core/List.ff +482 -482
- package/core/Lock.ff +108 -108
- package/core/NodeSystem.ff +198 -198
- package/core/Ordering.ff +160 -160
- package/core/Path.ff +377 -378
- package/core/Queue.ff +90 -90
- package/core/Random.ff +140 -140
- package/core/RbMap.ff +216 -216
- package/core/Show.ff +44 -44
- package/core/SourceLocation.ff +68 -68
- package/core/Task.ff +165 -165
- package/experimental/benchmarks/ListGrab.ff +23 -23
- package/experimental/benchmarks/ListGrab.java +55 -55
- package/experimental/benchmarks/Pyrotek45.ff +30 -30
- package/experimental/benchmarks/Pyrotek45.java +64 -64
- package/experimental/bidirectional/Bidi.ff +88 -88
- package/experimental/lines/Main.ff +40 -40
- package/experimental/random/Index.ff +53 -53
- package/experimental/random/Process.ff +120 -120
- package/experimental/random/RunLength.ff +65 -65
- package/experimental/random/Scrape.ff +51 -51
- package/experimental/random/Symbols.ff +73 -73
- package/experimental/random/Tensor.ff +52 -52
- package/experimental/random/Units.ff +36 -36
- package/experimental/s3/S3TestAuthorizationHeader.ff +39 -39
- package/experimental/s3/S3TestPut.ff +16 -16
- package/experimental/tests/TestJson.ff +26 -26
- package/firefly.sh +0 -0
- package/fireflysite/.firefly/package.ff +4 -4
- package/fireflysite/CommunityOverview.ff +20 -20
- package/fireflysite/CountingButtonDemo.ff +58 -58
- package/fireflysite/DocumentParser.ff +325 -325
- package/fireflysite/ExamplesOverview.ff +40 -40
- package/fireflysite/FrontPage.ff +344 -344
- package/fireflysite/GettingStarted.ff +45 -45
- package/fireflysite/Guide.ff +456 -456
- package/fireflysite/Main.ff +163 -163
- package/fireflysite/MatchingPasswordsDemo.ff +82 -82
- package/fireflysite/PackagesOverview.ff +49 -49
- package/fireflysite/PostgresqlDemo.ff +34 -34
- package/fireflysite/ReferenceAll.ff +18 -18
- package/fireflysite/ReferenceIntroduction.ff +11 -11
- package/fireflysite/Styles.ff +567 -567
- package/fireflysite/Test.ff +121 -121
- package/fireflysite/assets/markdown/reference/BaseTypes.md +209 -209
- package/fireflysite/assets/markdown/reference/EmittedJavascript.md +65 -65
- package/fireflysite/assets/markdown/reference/Exceptions.md +101 -101
- package/fireflysite/assets/markdown/reference/FunctionsAndMethods.md +364 -364
- package/fireflysite/assets/markdown/reference/JavascriptInterop.md +235 -235
- package/fireflysite/assets/markdown/reference/ModulesAndPackages.md +162 -162
- package/fireflysite/assets/markdown/reference/OldStructuredConcurrency.md +48 -48
- package/fireflysite/assets/markdown/reference/PatternMatching.md +224 -224
- package/fireflysite/assets/markdown/reference/StatementsAndExpressions.md +86 -86
- package/fireflysite/assets/markdown/reference/StructuredConcurrency.md +99 -99
- package/fireflysite/assets/markdown/reference/TraitsAndInstances.md +100 -100
- package/fireflysite/assets/markdown/reference/UserDefinedTypes.md +184 -184
- package/fireflysite/assets/markdown/scratch/ControlFlow.md +136 -136
- package/fireflysite/assets/markdown/scratch/Toc.md +40 -40
- package/lsp/.firefly/package.ff +1 -1
- package/lsp/CompletionHandler.ff +827 -827
- package/lsp/Handler.ff +714 -714
- package/lsp/HoverHandler.ff +79 -79
- package/lsp/LanguageServer.ff +272 -272
- package/lsp/SignatureHelpHandler.ff +55 -55
- package/lsp/SymbolHandler.ff +181 -181
- package/lsp/TestReferences.ff +17 -17
- package/lsp/TestReferencesCase.ff +7 -7
- package/lsp/stderr.txt +1 -1
- package/lsp/stdout.txt +34 -34
- package/lux/.firefly/package.ff +1 -1
- package/lux/Css.ff +648 -648
- package/lux/CssTest.ff +48 -48
- package/lux/Lux.ff +608 -608
- package/lux/LuxEvent.ff +79 -79
- package/lux/Main.ff +123 -123
- package/lux/Main2.ff +143 -143
- package/lux/TestDry.ff +28 -28
- package/output/js/ff/compiler/Builder.mjs +36 -36
- package/output/js/ff/core/Path.mjs +0 -2
- package/package.json +1 -1
- package/rpc/.firefly/package.ff +1 -1
- package/rpc/Rpc.ff +70 -70
- package/s3/.firefly/package.ff +1 -1
- package/s3/S3.ff +92 -92
- package/vscode/LICENSE.txt +21 -21
- package/vscode/Prepublish.ff +15 -15
- package/vscode/README.md +16 -16
- package/vscode/client/package-lock.json +544 -544
- package/vscode/client/package.json +22 -22
- package/vscode/client/src/extension.ts +104 -104
- package/vscode/icons/firefly-icon.svg +10 -10
- package/vscode/language-configuration.json +61 -61
- package/vscode/package-lock.json +3623 -3623
- package/vscode/package.json +1 -1
- package/vscode/snippets.json +241 -241
- package/vscode/syntaxes/firefly-markdown-injection.json +45 -45
- package/webserver/.firefly/include/package.json +5 -5
- package/webserver/.firefly/package.ff +2 -2
- package/webserver/WebServer.ff +647 -647
- package/websocket/.firefly/package.ff +1 -1
- package/websocket/WebSocket.ff +100 -100
package/fireflysite/Test.ff
CHANGED
|
@@ -1,121 +1,121 @@
|
|
|
1
|
-
import WebServer from ff:webserver // This is required to run the file.
|
|
2
|
-
|
|
3
|
-
nodeMain(system: NodeSystem) {
|
|
4
|
-
let f = {x, y => Pair(x, y)}
|
|
5
|
-
let g = {Pair(_, _)}
|
|
6
|
-
Log.show(f(1, 2))
|
|
7
|
-
Log.show(g(1, 2))
|
|
8
|
-
Log.show(factorial(5))
|
|
9
|
-
Log.show(factorialTail(5))
|
|
10
|
-
Log.show([1, 2].map({x => x + x}))
|
|
11
|
-
|
|
12
|
-
let x = {a, b => Pair(a, b)}(1, 2)
|
|
13
|
-
let f0: () => Unit = {42}
|
|
14
|
-
let p = {Pair(1, _)}
|
|
15
|
-
let p2 = {Pair(_, _)}
|
|
16
|
-
|
|
17
|
-
let increment: Int => Int = {i => i + 1}
|
|
18
|
-
let plus: (Int, Int) => Int = {a, b => a + b}
|
|
19
|
-
|
|
20
|
-
Log.show([1, 2].map(increment))
|
|
21
|
-
|
|
22
|
-
Log.show(p(42))
|
|
23
|
-
let f2 = {42}
|
|
24
|
-
Log.show(f2())
|
|
25
|
-
let pairs = {Pair(_, {_})}
|
|
26
|
-
let pp = pairs(42)
|
|
27
|
-
let foo = {{_ + 1}(_)}
|
|
28
|
-
Log.show(foo(1))
|
|
29
|
-
|
|
30
|
-
/*
|
|
31
|
-
let x1 = work(initial = 3) {i =>
|
|
32
|
-
i + 1
|
|
33
|
-
} {s =>
|
|
34
|
-
"*" + s + "*"
|
|
35
|
-
}*/
|
|
36
|
-
//let x2 = work(initial = 3, {i => i + 1}, {s => s + "*"})
|
|
37
|
-
|
|
38
|
-
let array = Array.new()
|
|
39
|
-
while {array.size() < 5} {
|
|
40
|
-
array.push("X")
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
testSplice([], 0, [], 0, [])
|
|
44
|
-
testSplice([], 0, [0], 0, [0])
|
|
45
|
-
testSplice([1, 2, 3], 0, [], 0, [1, 2, 3])
|
|
46
|
-
|
|
47
|
-
testSplice([1, 2, 3], 0, [0], 0, [0, 1, 2, 3])
|
|
48
|
-
testSplice([1, 2, 3], 1, [0], 0, [1, 0, 2, 3])
|
|
49
|
-
testSplice([1, 2, 3], 2, [0], 0, [1, 2, 0, 3])
|
|
50
|
-
testSplice([1, 2, 3], 3, [0], 0, [1, 2, 3, 0])
|
|
51
|
-
|
|
52
|
-
testSplice([1, 2, 3], 0, [0], 1, [0, 2, 3])
|
|
53
|
-
testSplice([1, 2, 3], 1, [0], 1, [1, 0, 3])
|
|
54
|
-
testSplice([1, 2, 3], 2, [0], 1, [1, 2, 0])
|
|
55
|
-
|
|
56
|
-
testSplice([1, 2, 3], 0, [0], 3, [0])
|
|
57
|
-
testSplice([1, 2, 3], 1, [0], 2, [1, 0])
|
|
58
|
-
testSplice([1, 2, 3], 2, [0], 1, [1, 2, 0])
|
|
59
|
-
testSplice([1, 2, 3], 3, [0], 0, [1, 2, 3, 0])
|
|
60
|
-
|
|
61
|
-
testSplice([1, 2, 3], 1, [0, -1, -2, -3, -4], 1, [1, 0, -1, -2, -3, -4, 3])
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
//Some(42) + Some(42)
|
|
65
|
-
//let f = {x, y => x + y}
|
|
66
|
-
let jsInt = []!->length
|
|
67
|
-
let jsInt2 = []!->length
|
|
68
|
-
jsInt + jsInt
|
|
69
|
-
32
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
testSplice(
|
|
73
|
-
self: List[Int],
|
|
74
|
-
start: Int,
|
|
75
|
-
itemsArray: List[Int],
|
|
76
|
-
deleteCount: Int,
|
|
77
|
-
expected: List[Int]
|
|
78
|
-
) {
|
|
79
|
-
do {
|
|
80
|
-
let array = self.toArray()
|
|
81
|
-
Log.debug("Test " + Show.show(array.toList()) + ".insertList(" + start + ", " + Show.show(itemsArray) + ", " + deleteCount + ") == " + Show.show(expected))
|
|
82
|
-
array.insertList(start, itemsArray, deleteCount)
|
|
83
|
-
if(array.toList() == expected) {
|
|
84
|
-
Log.debug("Passed")
|
|
85
|
-
} else {
|
|
86
|
-
Log.debug("Failed: " + Show.show(array))
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
do {
|
|
91
|
-
let array = self.toArray()
|
|
92
|
-
Log.debug("Test " + Show.show(array.toList()) + ".insertArray(" + start + ", " + Show.show(itemsArray) + ", " + deleteCount + ") == " + Show.show(expected))
|
|
93
|
-
array.insertArray(start, itemsArray.toArray(), deleteCount)
|
|
94
|
-
if(array.toList() == expected) {
|
|
95
|
-
Log.debug("Passed")
|
|
96
|
-
} else {
|
|
97
|
-
Log.debug("Failed: " + Show.show(array))
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
factorial(n: Int): Int {
|
|
104
|
-
if(n == 0) {
|
|
105
|
-
1
|
|
106
|
-
} else {
|
|
107
|
-
n * factorial(n - 1)
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
factorialTail(n: Int, acc: Int = 1): Int {
|
|
112
|
-
if(n == 0) {
|
|
113
|
-
acc
|
|
114
|
-
} else {
|
|
115
|
-
tailcall factorialTail(n - 1, n * acc)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
work(f: Int => Int, g: String => String, initial: Int = 0): String {
|
|
120
|
-
g("" + f(initial))
|
|
121
|
-
}
|
|
1
|
+
import WebServer from ff:webserver // This is required to run the file.
|
|
2
|
+
|
|
3
|
+
nodeMain(system: NodeSystem) {
|
|
4
|
+
let f = {x, y => Pair(x, y)}
|
|
5
|
+
let g = {Pair(_, _)}
|
|
6
|
+
Log.show(f(1, 2))
|
|
7
|
+
Log.show(g(1, 2))
|
|
8
|
+
Log.show(factorial(5))
|
|
9
|
+
Log.show(factorialTail(5))
|
|
10
|
+
Log.show([1, 2].map({x => x + x}))
|
|
11
|
+
|
|
12
|
+
let x = {a, b => Pair(a, b)}(1, 2)
|
|
13
|
+
let f0: () => Unit = {42}
|
|
14
|
+
let p = {Pair(1, _)}
|
|
15
|
+
let p2 = {Pair(_, _)}
|
|
16
|
+
|
|
17
|
+
let increment: Int => Int = {i => i + 1}
|
|
18
|
+
let plus: (Int, Int) => Int = {a, b => a + b}
|
|
19
|
+
|
|
20
|
+
Log.show([1, 2].map(increment))
|
|
21
|
+
|
|
22
|
+
Log.show(p(42))
|
|
23
|
+
let f2 = {42}
|
|
24
|
+
Log.show(f2())
|
|
25
|
+
let pairs = {Pair(_, {_})}
|
|
26
|
+
let pp = pairs(42)
|
|
27
|
+
let foo = {{_ + 1}(_)}
|
|
28
|
+
Log.show(foo(1))
|
|
29
|
+
|
|
30
|
+
/*
|
|
31
|
+
let x1 = work(initial = 3) {i =>
|
|
32
|
+
i + 1
|
|
33
|
+
} {s =>
|
|
34
|
+
"*" + s + "*"
|
|
35
|
+
}*/
|
|
36
|
+
//let x2 = work(initial = 3, {i => i + 1}, {s => s + "*"})
|
|
37
|
+
|
|
38
|
+
let array = Array.new()
|
|
39
|
+
while {array.size() < 5} {
|
|
40
|
+
array.push("X")
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
testSplice([], 0, [], 0, [])
|
|
44
|
+
testSplice([], 0, [0], 0, [0])
|
|
45
|
+
testSplice([1, 2, 3], 0, [], 0, [1, 2, 3])
|
|
46
|
+
|
|
47
|
+
testSplice([1, 2, 3], 0, [0], 0, [0, 1, 2, 3])
|
|
48
|
+
testSplice([1, 2, 3], 1, [0], 0, [1, 0, 2, 3])
|
|
49
|
+
testSplice([1, 2, 3], 2, [0], 0, [1, 2, 0, 3])
|
|
50
|
+
testSplice([1, 2, 3], 3, [0], 0, [1, 2, 3, 0])
|
|
51
|
+
|
|
52
|
+
testSplice([1, 2, 3], 0, [0], 1, [0, 2, 3])
|
|
53
|
+
testSplice([1, 2, 3], 1, [0], 1, [1, 0, 3])
|
|
54
|
+
testSplice([1, 2, 3], 2, [0], 1, [1, 2, 0])
|
|
55
|
+
|
|
56
|
+
testSplice([1, 2, 3], 0, [0], 3, [0])
|
|
57
|
+
testSplice([1, 2, 3], 1, [0], 2, [1, 0])
|
|
58
|
+
testSplice([1, 2, 3], 2, [0], 1, [1, 2, 0])
|
|
59
|
+
testSplice([1, 2, 3], 3, [0], 0, [1, 2, 3, 0])
|
|
60
|
+
|
|
61
|
+
testSplice([1, 2, 3], 1, [0, -1, -2, -3, -4], 1, [1, 0, -1, -2, -3, -4, 3])
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
//Some(42) + Some(42)
|
|
65
|
+
//let f = {x, y => x + y}
|
|
66
|
+
let jsInt = []!->length
|
|
67
|
+
let jsInt2 = []!->length
|
|
68
|
+
jsInt + jsInt
|
|
69
|
+
32
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
testSplice(
|
|
73
|
+
self: List[Int],
|
|
74
|
+
start: Int,
|
|
75
|
+
itemsArray: List[Int],
|
|
76
|
+
deleteCount: Int,
|
|
77
|
+
expected: List[Int]
|
|
78
|
+
) {
|
|
79
|
+
do {
|
|
80
|
+
let array = self.toArray()
|
|
81
|
+
Log.debug("Test " + Show.show(array.toList()) + ".insertList(" + start + ", " + Show.show(itemsArray) + ", " + deleteCount + ") == " + Show.show(expected))
|
|
82
|
+
array.insertList(start, itemsArray, deleteCount)
|
|
83
|
+
if(array.toList() == expected) {
|
|
84
|
+
Log.debug("Passed")
|
|
85
|
+
} else {
|
|
86
|
+
Log.debug("Failed: " + Show.show(array))
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
do {
|
|
91
|
+
let array = self.toArray()
|
|
92
|
+
Log.debug("Test " + Show.show(array.toList()) + ".insertArray(" + start + ", " + Show.show(itemsArray) + ", " + deleteCount + ") == " + Show.show(expected))
|
|
93
|
+
array.insertArray(start, itemsArray.toArray(), deleteCount)
|
|
94
|
+
if(array.toList() == expected) {
|
|
95
|
+
Log.debug("Passed")
|
|
96
|
+
} else {
|
|
97
|
+
Log.debug("Failed: " + Show.show(array))
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
factorial(n: Int): Int {
|
|
104
|
+
if(n == 0) {
|
|
105
|
+
1
|
|
106
|
+
} else {
|
|
107
|
+
n * factorial(n - 1)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
factorialTail(n: Int, acc: Int = 1): Int {
|
|
112
|
+
if(n == 0) {
|
|
113
|
+
acc
|
|
114
|
+
} else {
|
|
115
|
+
tailcall factorialTail(n - 1, n * acc)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
work(f: Int => Int, g: String => String, initial: Int = 0): String {
|
|
120
|
+
g("" + f(initial))
|
|
121
|
+
}
|
|
@@ -1,209 +1,209 @@
|
|
|
1
|
-
# Base types
|
|
2
|
-
|
|
3
|
-
In Firefly, all named types are defined in a `.ff` file somewhere.
|
|
4
|
-
However, some of the types in the `ff:core` package have dedicated syntax.
|
|
5
|
-
These are considered base types and are documented in the following sections.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
# Bool
|
|
9
|
-
|
|
10
|
-
Values of the `Bool` type represent truth values. They are either `False` or `True`.
|
|
11
|
-
|
|
12
|
-
The type is defined in `ff:core` as follows:
|
|
13
|
-
|
|
14
|
-
```firefly
|
|
15
|
-
data Bool {
|
|
16
|
-
False
|
|
17
|
-
True
|
|
18
|
-
}
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
Logical negation is an operator on booleans:
|
|
22
|
-
|
|
23
|
-
```firefly
|
|
24
|
-
!True == False
|
|
25
|
-
!False == True
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Logical and is an operator on booleans. The right hand side is only evaluated when the left hand side is `True`:
|
|
29
|
-
|
|
30
|
-
```firefly
|
|
31
|
-
True && True == True
|
|
32
|
-
True && False == False
|
|
33
|
-
False && True == False
|
|
34
|
-
False && False == False
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Logical or is an operator on booleans. The right hand side is only evaluated when the left hand side is `False`:
|
|
38
|
-
|
|
39
|
-
```firefly
|
|
40
|
-
True || True == True
|
|
41
|
-
True || False == True
|
|
42
|
-
False || True == True
|
|
43
|
-
False || False == False
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
The comparison operators are supported for `Bool`:
|
|
47
|
-
|
|
48
|
-
```firefly
|
|
49
|
-
True == True // Equality
|
|
50
|
-
True != False // Inequality
|
|
51
|
-
False < True // Less than
|
|
52
|
-
False <= True // Less than or equal
|
|
53
|
-
True > False // Greater than
|
|
54
|
-
True >= True // Greater than or equal
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
In addition, the standard library defines `if`, `while`, etc. as a functions with a `Bool` condition.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
# Int
|
|
61
|
-
|
|
62
|
-
Values of the `Int` type represent whole numbers in the range `-9,007,199,254,740,991` to `9,007,199,254,740,991`. This range is specifically chosen to work inside the safe integer range of the `Number` type in JavaScript. Outside of this range, `Int` values may act like `Float` values.
|
|
63
|
-
|
|
64
|
-
They can be constructed using the following literal syntax:
|
|
65
|
-
|
|
66
|
-
```firefly
|
|
67
|
-
42 // Fourty two
|
|
68
|
-
0 // Zero
|
|
69
|
-
-1 // Minus one
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
Basic arithmetic operators are supported:
|
|
73
|
-
|
|
74
|
-
```firefly
|
|
75
|
-
3 + 5 // Addition, == 8
|
|
76
|
-
3 - 5 // Subtraction, == -2
|
|
77
|
-
3 * 5 // Multiplication, == 15
|
|
78
|
-
-(3 + 5) // Negation, == -8
|
|
79
|
-
3 / 5 // Division, == 0.6
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
As are the comparison operators.
|
|
83
|
-
|
|
84
|
-
Note that the division `3 / 5` does not return an `Int`, but rather a `Float` value `0.6`. If you want integer division, which rounds towards zero, you can do `3.div(5) == 0`.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
# Float
|
|
88
|
-
|
|
89
|
-
Values of the `Float` type are floating point numbers with the semantics of the `Number` type in JavaScript.
|
|
90
|
-
|
|
91
|
-
They be constructed using following literal syntax:
|
|
92
|
-
|
|
93
|
-
```firefly
|
|
94
|
-
42.0 // Fourty two point zero
|
|
95
|
-
0.0 // Zero point zero
|
|
96
|
-
-1.0 // Minus one point zero
|
|
97
|
-
1.0e3 // == 1000.0
|
|
98
|
-
1.0e-3 // == 0.001
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
Like `Number` values in JavaScript, `Float` values may also be `Float.nan()`, `Float.infinity()` or `-Float.infinity()`.
|
|
102
|
-
|
|
103
|
-
Basic arithmetic operators are supported:
|
|
104
|
-
|
|
105
|
-
```firefly
|
|
106
|
-
3.5 + 5.75 // Addition, == 9.25
|
|
107
|
-
3.0 - 5.0 // Subtraction, == -2.0
|
|
108
|
-
3.0 * 5.0 // Multiplication, == 15.0
|
|
109
|
-
-(3.0 + 5.0) // Negation, == -8.0
|
|
110
|
-
3.0 / 5.0 // Division, == 0.6
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
As are the comparison operators.
|
|
114
|
-
However, as with `Number` values in JavaScript, comparing `Float.nan()` with any floating point value, including `Float.nan()` will return `False`.
|
|
115
|
-
To test whether a number is `Float.nan()`, use the `isNan()` method, e.g. `x.isNan()`.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
# Char
|
|
119
|
-
|
|
120
|
-
Values of the `Char` type represent UTF-16 code units.
|
|
121
|
-
Graphemes outside of the Unicode Basic Multilingual Plane may consist of multiple UTF-16 code units and thus require multiple `Char` values.
|
|
122
|
-
|
|
123
|
-
They can be constructed using following literal syntax, where `\` (backslash) is used to escape characters:
|
|
124
|
-
|
|
125
|
-
```firefly
|
|
126
|
-
' ' // A space
|
|
127
|
-
'\'' // Single quote
|
|
128
|
-
'\r' // Carriage return
|
|
129
|
-
'\n' // Line feed (Unix newline)
|
|
130
|
-
'\t' // Horizontal tab
|
|
131
|
-
'\\' // Backslash
|
|
132
|
-
'A' // Capital A
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
The comparison operators also works for `Char` values, but note that they compare the code unit rather than compare by any language-specific character ordering.
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
# String
|
|
139
|
-
|
|
140
|
-
Values of the `String` type are immutable sequences of `Char` values, representing Unicode strings.
|
|
141
|
-
|
|
142
|
-
Single line strings must be contained within a single line, and can be constructed using following literal syntax:
|
|
143
|
-
|
|
144
|
-
```firefly
|
|
145
|
-
"Hello, World!"
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
Multiline string literals begin and end with three double quotes, and may contain newlines:
|
|
149
|
-
|
|
150
|
-
```firefly
|
|
151
|
-
"""
|
|
152
|
-
Once upon a time,
|
|
153
|
-
in a land far, far away...
|
|
154
|
-
"""
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
There's an operator for string concatenation:
|
|
158
|
-
|
|
159
|
-
```firefly
|
|
160
|
-
"ban" + "ana" == "banana"
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
The comparison operators are supported, but note that they compare the string as a sequence of `Char` values rather than by any language-specific ordering.
|
|
164
|
-
|
|
165
|
-
The escape mechanism is the same as with the `Char` type.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
# List
|
|
169
|
-
|
|
170
|
-
Values of the `List[T]` types are immutable sequences of `T` values, where `T` is a type of your choice.
|
|
171
|
-
|
|
172
|
-
They can be constructed using list literals:
|
|
173
|
-
|
|
174
|
-
```firefly
|
|
175
|
-
[1, 2, 3] // A List[Int] with three elements
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
Note that commas can be omitted when they would occur before a newline:
|
|
179
|
-
|
|
180
|
-
```firefly
|
|
181
|
-
[
|
|
182
|
-
1
|
|
183
|
-
2
|
|
184
|
-
3
|
|
185
|
-
]
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
Lists can be flattened into other lists using the spread syntax:
|
|
189
|
-
|
|
190
|
-
```firefly
|
|
191
|
-
[1, ...[2, 3], 4, 5] == [1, 2, 3, 4, 5]
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
The comparison operators are available for values of type `List[T]` when they're available for values of type `T`.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
# Unit
|
|
198
|
-
|
|
199
|
-
The `Unit` type has just one possible value, and is used as the return type for functions that have no interesting return value.
|
|
200
|
-
|
|
201
|
-
The type is defined in `ff:core` as follows:
|
|
202
|
-
|
|
203
|
-
```firefly
|
|
204
|
-
data Unit {
|
|
205
|
-
Unit
|
|
206
|
-
}
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
If you omit the return type, the `Unit` type is assumed. If you don't end a function with an expression, the `Unit` value is returned.
|
|
1
|
+
# Base types
|
|
2
|
+
|
|
3
|
+
In Firefly, all named types are defined in a `.ff` file somewhere.
|
|
4
|
+
However, some of the types in the `ff:core` package have dedicated syntax.
|
|
5
|
+
These are considered base types and are documented in the following sections.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Bool
|
|
9
|
+
|
|
10
|
+
Values of the `Bool` type represent truth values. They are either `False` or `True`.
|
|
11
|
+
|
|
12
|
+
The type is defined in `ff:core` as follows:
|
|
13
|
+
|
|
14
|
+
```firefly
|
|
15
|
+
data Bool {
|
|
16
|
+
False
|
|
17
|
+
True
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Logical negation is an operator on booleans:
|
|
22
|
+
|
|
23
|
+
```firefly
|
|
24
|
+
!True == False
|
|
25
|
+
!False == True
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Logical and is an operator on booleans. The right hand side is only evaluated when the left hand side is `True`:
|
|
29
|
+
|
|
30
|
+
```firefly
|
|
31
|
+
True && True == True
|
|
32
|
+
True && False == False
|
|
33
|
+
False && True == False
|
|
34
|
+
False && False == False
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Logical or is an operator on booleans. The right hand side is only evaluated when the left hand side is `False`:
|
|
38
|
+
|
|
39
|
+
```firefly
|
|
40
|
+
True || True == True
|
|
41
|
+
True || False == True
|
|
42
|
+
False || True == True
|
|
43
|
+
False || False == False
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The comparison operators are supported for `Bool`:
|
|
47
|
+
|
|
48
|
+
```firefly
|
|
49
|
+
True == True // Equality
|
|
50
|
+
True != False // Inequality
|
|
51
|
+
False < True // Less than
|
|
52
|
+
False <= True // Less than or equal
|
|
53
|
+
True > False // Greater than
|
|
54
|
+
True >= True // Greater than or equal
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
In addition, the standard library defines `if`, `while`, etc. as a functions with a `Bool` condition.
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# Int
|
|
61
|
+
|
|
62
|
+
Values of the `Int` type represent whole numbers in the range `-9,007,199,254,740,991` to `9,007,199,254,740,991`. This range is specifically chosen to work inside the safe integer range of the `Number` type in JavaScript. Outside of this range, `Int` values may act like `Float` values.
|
|
63
|
+
|
|
64
|
+
They can be constructed using the following literal syntax:
|
|
65
|
+
|
|
66
|
+
```firefly
|
|
67
|
+
42 // Fourty two
|
|
68
|
+
0 // Zero
|
|
69
|
+
-1 // Minus one
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Basic arithmetic operators are supported:
|
|
73
|
+
|
|
74
|
+
```firefly
|
|
75
|
+
3 + 5 // Addition, == 8
|
|
76
|
+
3 - 5 // Subtraction, == -2
|
|
77
|
+
3 * 5 // Multiplication, == 15
|
|
78
|
+
-(3 + 5) // Negation, == -8
|
|
79
|
+
3 / 5 // Division, == 0.6
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
As are the comparison operators.
|
|
83
|
+
|
|
84
|
+
Note that the division `3 / 5` does not return an `Int`, but rather a `Float` value `0.6`. If you want integer division, which rounds towards zero, you can do `3.div(5) == 0`.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# Float
|
|
88
|
+
|
|
89
|
+
Values of the `Float` type are floating point numbers with the semantics of the `Number` type in JavaScript.
|
|
90
|
+
|
|
91
|
+
They be constructed using following literal syntax:
|
|
92
|
+
|
|
93
|
+
```firefly
|
|
94
|
+
42.0 // Fourty two point zero
|
|
95
|
+
0.0 // Zero point zero
|
|
96
|
+
-1.0 // Minus one point zero
|
|
97
|
+
1.0e3 // == 1000.0
|
|
98
|
+
1.0e-3 // == 0.001
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Like `Number` values in JavaScript, `Float` values may also be `Float.nan()`, `Float.infinity()` or `-Float.infinity()`.
|
|
102
|
+
|
|
103
|
+
Basic arithmetic operators are supported:
|
|
104
|
+
|
|
105
|
+
```firefly
|
|
106
|
+
3.5 + 5.75 // Addition, == 9.25
|
|
107
|
+
3.0 - 5.0 // Subtraction, == -2.0
|
|
108
|
+
3.0 * 5.0 // Multiplication, == 15.0
|
|
109
|
+
-(3.0 + 5.0) // Negation, == -8.0
|
|
110
|
+
3.0 / 5.0 // Division, == 0.6
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
As are the comparison operators.
|
|
114
|
+
However, as with `Number` values in JavaScript, comparing `Float.nan()` with any floating point value, including `Float.nan()` will return `False`.
|
|
115
|
+
To test whether a number is `Float.nan()`, use the `isNan()` method, e.g. `x.isNan()`.
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# Char
|
|
119
|
+
|
|
120
|
+
Values of the `Char` type represent UTF-16 code units.
|
|
121
|
+
Graphemes outside of the Unicode Basic Multilingual Plane may consist of multiple UTF-16 code units and thus require multiple `Char` values.
|
|
122
|
+
|
|
123
|
+
They can be constructed using following literal syntax, where `\` (backslash) is used to escape characters:
|
|
124
|
+
|
|
125
|
+
```firefly
|
|
126
|
+
' ' // A space
|
|
127
|
+
'\'' // Single quote
|
|
128
|
+
'\r' // Carriage return
|
|
129
|
+
'\n' // Line feed (Unix newline)
|
|
130
|
+
'\t' // Horizontal tab
|
|
131
|
+
'\\' // Backslash
|
|
132
|
+
'A' // Capital A
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The comparison operators also works for `Char` values, but note that they compare the code unit rather than compare by any language-specific character ordering.
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# String
|
|
139
|
+
|
|
140
|
+
Values of the `String` type are immutable sequences of `Char` values, representing Unicode strings.
|
|
141
|
+
|
|
142
|
+
Single line strings must be contained within a single line, and can be constructed using following literal syntax:
|
|
143
|
+
|
|
144
|
+
```firefly
|
|
145
|
+
"Hello, World!"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Multiline string literals begin and end with three double quotes, and may contain newlines:
|
|
149
|
+
|
|
150
|
+
```firefly
|
|
151
|
+
"""
|
|
152
|
+
Once upon a time,
|
|
153
|
+
in a land far, far away...
|
|
154
|
+
"""
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
There's an operator for string concatenation:
|
|
158
|
+
|
|
159
|
+
```firefly
|
|
160
|
+
"ban" + "ana" == "banana"
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
The comparison operators are supported, but note that they compare the string as a sequence of `Char` values rather than by any language-specific ordering.
|
|
164
|
+
|
|
165
|
+
The escape mechanism is the same as with the `Char` type.
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
# List
|
|
169
|
+
|
|
170
|
+
Values of the `List[T]` types are immutable sequences of `T` values, where `T` is a type of your choice.
|
|
171
|
+
|
|
172
|
+
They can be constructed using list literals:
|
|
173
|
+
|
|
174
|
+
```firefly
|
|
175
|
+
[1, 2, 3] // A List[Int] with three elements
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Note that commas can be omitted when they would occur before a newline:
|
|
179
|
+
|
|
180
|
+
```firefly
|
|
181
|
+
[
|
|
182
|
+
1
|
|
183
|
+
2
|
|
184
|
+
3
|
|
185
|
+
]
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Lists can be flattened into other lists using the spread syntax:
|
|
189
|
+
|
|
190
|
+
```firefly
|
|
191
|
+
[1, ...[2, 3], 4, 5] == [1, 2, 3, 4, 5]
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The comparison operators are available for values of type `List[T]` when they're available for values of type `T`.
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
# Unit
|
|
198
|
+
|
|
199
|
+
The `Unit` type has just one possible value, and is used as the return type for functions that have no interesting return value.
|
|
200
|
+
|
|
201
|
+
The type is defined in `ff:core` as follows:
|
|
202
|
+
|
|
203
|
+
```firefly
|
|
204
|
+
data Unit {
|
|
205
|
+
Unit
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
If you omit the return type, the `Unit` type is assumed. If you don't end a function with an expression, the `Unit` value is returned.
|