firefly-compiler 0.5.4 → 0.5.6
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/bin/Release.ff +0 -1
- package/compiler/Parser.ff +3 -3
- package/compiler/Tokenizer.ff +8 -0
- package/core/List.ff +13 -0
- package/fireflysite/assets/markdown/reference/JavascriptInterop.md +17 -0
- package/output/js/ff/compiler/Parser.mjs +4 -4
- package/output/js/ff/compiler/Tokenizer.mjs +6 -0
- package/output/js/ff/core/List.mjs +24 -0
- package/package.json +1 -1
- package/vscode/package.json +1 -1
package/bin/Release.ff
CHANGED
|
@@ -35,7 +35,6 @@ release(
|
|
|
35
35
|
releaseFireflyPackage(system, accessKeyId, secretAccessKey, "postgresql")
|
|
36
36
|
releaseFireflyPackage(system, accessKeyId, secretAccessKey, "rpc")
|
|
37
37
|
releaseFireflyPackage(system, accessKeyId, secretAccessKey, "s3")
|
|
38
|
-
releaseFireflyPackage(system, accessKeyId, secretAccessKey, "unsafejs")
|
|
39
38
|
releaseFireflyPackage(system, accessKeyId, secretAccessKey, "webserver")
|
|
40
39
|
runSuccessful(system, "git", ["commit", "-a", "-m", "Autorelease " + version], system.path(".."))
|
|
41
40
|
runSuccessful(system, "git", ["push"], system.path(".."))
|
package/compiler/Parser.ff
CHANGED
|
@@ -1152,7 +1152,7 @@ extend self: Parser {
|
|
|
1152
1152
|
True
|
|
1153
1153
|
} else {False}
|
|
1154
1154
|
mutable result = self.parseAtom()
|
|
1155
|
-
while {self.current().is4(LBracketLeft, LColon, LDot, LArrowThin)} {
|
|
1155
|
+
while {self.current().is4(LBracketLeft, LColon, LDot, LArrowThin) || self.current().rawIs2("!", "?")} {
|
|
1156
1156
|
if(self.current().is(LDot)) {
|
|
1157
1157
|
self.skip(LDot)
|
|
1158
1158
|
if(self.current().rawIs("{")) {
|
|
@@ -1172,9 +1172,9 @@ extend self: Parser {
|
|
|
1172
1172
|
let method = if(token.rawIs("!")) {"ff:core/UnsafeJs.value"} else {"ff:core/UnsafeJs.fromValue"}
|
|
1173
1173
|
let target = DynamicCall(EVariable(token.at(), method), False)
|
|
1174
1174
|
let effect = self.freshUnificationVariable(token.at())
|
|
1175
|
-
result =
|
|
1175
|
+
result = ECall(token.at(), target, effect, [], [
|
|
1176
1176
|
Argument(result.at, None, result)
|
|
1177
|
-
], [])
|
|
1177
|
+
], [])
|
|
1178
1178
|
} else {
|
|
1179
1179
|
let at = self.current().at()
|
|
1180
1180
|
let typeArguments = if(!self.current().rawIs("[")) {[]} else {self.parseTypeArguments()}
|
package/compiler/Tokenizer.ff
CHANGED
|
@@ -204,6 +204,14 @@ tokenize(file: String, code: String, completionAt: Option[Location], attemptFixe
|
|
|
204
204
|
i += 1
|
|
205
205
|
emitToken(LComma, start, i)
|
|
206
206
|
|
|
207
|
+
} elseIf {
|
|
208
|
+
(code.grab(i) == '!' || code.grab(i) == '?') && i + 1 < code.size() &&
|
|
209
|
+
(code.grab(i + 1) == '.' || code.grab(i + 1) == '-')
|
|
210
|
+
} {
|
|
211
|
+
|
|
212
|
+
i += 1
|
|
213
|
+
emitToken(LOperator, start, i)
|
|
214
|
+
|
|
207
215
|
} elseIf {operatorCharacters.contains(code.grab(i))} {
|
|
208
216
|
|
|
209
217
|
i += 1
|
package/core/List.ff
CHANGED
|
@@ -308,6 +308,19 @@ extend self[T]: List[T] {
|
|
|
308
308
|
return result;
|
|
309
309
|
"""
|
|
310
310
|
|
|
311
|
+
map2[S](body: T => S): List[S] {
|
|
312
|
+
if(!UnsafeJs.inAsync()) {
|
|
313
|
+
self!->map(body!)?
|
|
314
|
+
} else {
|
|
315
|
+
let result = Array.new()
|
|
316
|
+
0.until(self.size()).each {i =>
|
|
317
|
+
result.push(body(self.grab(i)))
|
|
318
|
+
}
|
|
319
|
+
result.drain()
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
|
|
311
324
|
flatMap[S](body: T => List[S]): List[S] {
|
|
312
325
|
let results = Array.new()
|
|
313
326
|
self.each {x =>
|
|
@@ -40,6 +40,8 @@ The `->` is shorthand for calling the methods `get`, `set`, `increment`, `decrem
|
|
|
40
40
|
|
|
41
41
|
The `js` variable is of the type `JsSystem` and the rest of the expressions return `JsValue`, which represents an arbitrary JavaScript value.
|
|
42
42
|
|
|
43
|
+
In addition, the `!` and `?` postfix operators can be used as shorthand for `UnsafeJs.value(...)` and `UnsafeJs.fromValue(...)`.
|
|
44
|
+
|
|
43
45
|
|
|
44
46
|
# The UnsafeJs module
|
|
45
47
|
|
|
@@ -61,8 +63,23 @@ throwIfCancelled(): Unit
|
|
|
61
63
|
// Returns true if the current task has been aborted
|
|
62
64
|
cancelled(): Bool
|
|
63
65
|
|
|
66
|
+
// Returns true if the current target is async
|
|
67
|
+
inAsync(): Bool
|
|
68
|
+
|
|
69
|
+
// Returns true if the current target is browser
|
|
70
|
+
inBrowser(): Bool
|
|
71
|
+
|
|
72
|
+
// Returns true if the current target is node
|
|
73
|
+
inNode(): Bool
|
|
74
|
+
|
|
75
|
+
// Returns true if the current target is build
|
|
76
|
+
inBuild(): Bool
|
|
77
|
+
|
|
64
78
|
// Casts any Firefly value to a JavaScript value without conversion
|
|
65
79
|
value[T](value: T): JsValue
|
|
80
|
+
|
|
81
|
+
// Casts any JavaScript value to a Firefly value without conversion
|
|
82
|
+
fromValue[T](value: JsValue): T
|
|
66
83
|
```
|
|
67
84
|
|
|
68
85
|
In the future, it may be possible to provide a whitelist of dependencies that are allowed to use this module.
|
|
@@ -1507,7 +1507,7 @@ return true
|
|
|
1507
1507
|
})()
|
|
1508
1508
|
: false);
|
|
1509
1509
|
let result_ = ff_compiler_Parser.Parser_parseAtom(self_);
|
|
1510
|
-
while(ff_compiler_Token.Token_is4(ff_compiler_Parser.Parser_current(self_), ff_compiler_Token.LBracketLeft(), ff_compiler_Token.LColon(), ff_compiler_Token.LDot(), ff_compiler_Token.LArrowThin())) {
|
|
1510
|
+
while((ff_compiler_Token.Token_is4(ff_compiler_Parser.Parser_current(self_), ff_compiler_Token.LBracketLeft(), ff_compiler_Token.LColon(), ff_compiler_Token.LDot(), ff_compiler_Token.LArrowThin()) || ff_compiler_Token.Token_rawIs2(ff_compiler_Parser.Parser_current(self_), "!", "?"))) {
|
|
1511
1511
|
if(ff_compiler_Token.Token_is(ff_compiler_Parser.Parser_current(self_), ff_compiler_Token.LDot())) {
|
|
1512
1512
|
ff_compiler_Parser.Parser_skip(self_, ff_compiler_Token.LDot());
|
|
1513
1513
|
if(ff_compiler_Token.Token_rawIs(ff_compiler_Parser.Parser_current(self_), "{")) {
|
|
@@ -1529,7 +1529,7 @@ const method_ = (ff_compiler_Token.Token_rawIs(token_, "!")
|
|
|
1529
1529
|
: "ff:core/UnsafeJs.fromValue");
|
|
1530
1530
|
const target_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EVariable(ff_compiler_Token.Token_at(token_), method_), false);
|
|
1531
1531
|
const effect_ = ff_compiler_Parser.Parser_freshUnificationVariable(self_, ff_compiler_Token.Token_at(token_));
|
|
1532
|
-
result_ =
|
|
1532
|
+
result_ = ff_compiler_Syntax.ECall(ff_compiler_Token.Token_at(token_), target_, effect_, [], [ff_compiler_Syntax.Argument(result_.at_, ff_core_Option.None(), result_)], [])
|
|
1533
1533
|
} else {
|
|
1534
1534
|
const at_ = ff_compiler_Token.Token_at(ff_compiler_Parser.Parser_current(self_));
|
|
1535
1535
|
const typeArguments_ = ((!ff_compiler_Token.Token_rawIs(ff_compiler_Parser.Parser_current(self_), "["))
|
|
@@ -3125,7 +3125,7 @@ return true
|
|
|
3125
3125
|
})())
|
|
3126
3126
|
: false);
|
|
3127
3127
|
let result_ = ff_compiler_Parser.Parser_parseAtom(self_);
|
|
3128
|
-
while(ff_compiler_Token.Token_is4(ff_compiler_Parser.Parser_current(self_), ff_compiler_Token.LBracketLeft(), ff_compiler_Token.LColon(), ff_compiler_Token.LDot(), ff_compiler_Token.LArrowThin())) {
|
|
3128
|
+
while((ff_compiler_Token.Token_is4(ff_compiler_Parser.Parser_current(self_), ff_compiler_Token.LBracketLeft(), ff_compiler_Token.LColon(), ff_compiler_Token.LDot(), ff_compiler_Token.LArrowThin()) || ff_compiler_Token.Token_rawIs2(ff_compiler_Parser.Parser_current(self_), "!", "?"))) {
|
|
3129
3129
|
if(ff_compiler_Token.Token_is(ff_compiler_Parser.Parser_current(self_), ff_compiler_Token.LDot())) {
|
|
3130
3130
|
ff_compiler_Parser.Parser_skip(self_, ff_compiler_Token.LDot());
|
|
3131
3131
|
if(ff_compiler_Token.Token_rawIs(ff_compiler_Parser.Parser_current(self_), "{")) {
|
|
@@ -3147,7 +3147,7 @@ const method_ = (ff_compiler_Token.Token_rawIs(token_, "!")
|
|
|
3147
3147
|
: "ff:core/UnsafeJs.fromValue");
|
|
3148
3148
|
const target_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EVariable(ff_compiler_Token.Token_at(token_), method_), false);
|
|
3149
3149
|
const effect_ = ff_compiler_Parser.Parser_freshUnificationVariable(self_, ff_compiler_Token.Token_at(token_));
|
|
3150
|
-
result_ =
|
|
3150
|
+
result_ = ff_compiler_Syntax.ECall(ff_compiler_Token.Token_at(token_), target_, effect_, [], [ff_compiler_Syntax.Argument(result_.at_, ff_core_Option.None(), result_)], [])
|
|
3151
3151
|
} else {
|
|
3152
3152
|
const at_ = ff_compiler_Token.Token_at(ff_compiler_Parser.Parser_current(self_));
|
|
3153
3153
|
const typeArguments_ = ((!ff_compiler_Token.Token_rawIs(ff_compiler_Parser.Parser_current(self_), "["))
|
|
@@ -280,6 +280,9 @@ emitToken_(ff_compiler_Token.LWildcard(), start_, i_)
|
|
|
280
280
|
} else if((ff_core_String.String_grab(code_, i_) === 44)) {
|
|
281
281
|
i_ += 1;
|
|
282
282
|
emitToken_(ff_compiler_Token.LComma(), start_, i_)
|
|
283
|
+
} else if(((((ff_core_String.String_grab(code_, i_) === 33) || (ff_core_String.String_grab(code_, i_) === 63)) && ((i_ + 1) < ff_core_String.String_size(code_))) && ((ff_core_String.String_grab(code_, (i_ + 1)) === 46) || (ff_core_String.String_grab(code_, (i_ + 1)) === 45)))) {
|
|
284
|
+
i_ += 1;
|
|
285
|
+
emitToken_(ff_compiler_Token.LOperator(), start_, i_)
|
|
283
286
|
} else if(ff_core_Set.Set_contains(operatorCharacters_, ff_core_String.String_grab(code_, i_), ff_core_Ordering.ff_core_Ordering_Order$ff_core_Char_Char)) {
|
|
284
287
|
i_ += 1;
|
|
285
288
|
if(((((ff_core_String.String_grab(code_, (i_ - 1)) === 46) && ((i_ + 1) < ff_core_String.String_size(code_))) && (ff_core_String.String_grab(code_, i_) === 46)) && (ff_core_String.String_grab(code_, (i_ + 1)) !== 46))) {
|
|
@@ -524,6 +527,9 @@ emitToken_(ff_compiler_Token.LWildcard(), start_, i_)
|
|
|
524
527
|
} else if((ff_core_String.String_grab(code_, i_) === 44)) {
|
|
525
528
|
i_ += 1;
|
|
526
529
|
emitToken_(ff_compiler_Token.LComma(), start_, i_)
|
|
530
|
+
} else if(((((ff_core_String.String_grab(code_, i_) === 33) || (ff_core_String.String_grab(code_, i_) === 63)) && ((i_ + 1) < ff_core_String.String_size(code_))) && ((ff_core_String.String_grab(code_, (i_ + 1)) === 46) || (ff_core_String.String_grab(code_, (i_ + 1)) === 45)))) {
|
|
531
|
+
i_ += 1;
|
|
532
|
+
emitToken_(ff_compiler_Token.LOperator(), start_, i_)
|
|
527
533
|
} else if(ff_core_Set.Set_contains(operatorCharacters_, ff_core_String.String_grab(code_, i_), ff_core_Ordering.ff_core_Ordering_Order$ff_core_Char_Char)) {
|
|
528
534
|
i_ += 1;
|
|
529
535
|
if(((((ff_core_String.String_grab(code_, (i_ - 1)) === 46) && ((i_ + 1) < ff_core_String.String_size(code_))) && (ff_core_String.String_grab(code_, i_) === 46)) && (ff_core_String.String_grab(code_, (i_ + 1)) !== 46))) {
|
|
@@ -453,6 +453,18 @@ export function List_map(self_, body_) {
|
|
|
453
453
|
|
|
454
454
|
}
|
|
455
455
|
|
|
456
|
+
export function List_map2(self_, body_) {
|
|
457
|
+
if((!false)) {
|
|
458
|
+
return ff_core_JsValue.JsValue_call1(self_, "map", body_, ff_core_JsValue.ff_core_JsValue_IsJsValue$ff_core_JsValue_JsValue)
|
|
459
|
+
} else {
|
|
460
|
+
const result_ = ff_core_Array.new_();
|
|
461
|
+
ff_core_List.List_each(ff_core_Int.Int_until(0, ff_core_List.List_size(self_)), ((i_) => {
|
|
462
|
+
ff_core_Array.Array_push(result_, body_((self_[i_] ?? ff_core_List.internalGrab_(self_, i_))))
|
|
463
|
+
}));
|
|
464
|
+
return ff_core_Array.Array_drain(result_)
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
456
468
|
export function List_flatMap(self_, body_) {
|
|
457
469
|
const results_ = ff_core_Array.new_();
|
|
458
470
|
ff_core_List.List_each(self_, ((x_) => {
|
|
@@ -815,6 +827,18 @@ export async function List_map$(self_, body_, $task) {
|
|
|
815
827
|
|
|
816
828
|
}
|
|
817
829
|
|
|
830
|
+
export async function List_map2$(self_, body_, $task) {
|
|
831
|
+
if((!true)) {
|
|
832
|
+
return ff_core_JsValue.JsValue_call1(self_, "map", body_, ff_core_JsValue.ff_core_JsValue_IsJsValue$ff_core_JsValue_JsValue)
|
|
833
|
+
} else {
|
|
834
|
+
const result_ = ff_core_Array.new_();
|
|
835
|
+
(await ff_core_List.List_each$(ff_core_Int.Int_until(0, ff_core_List.List_size(self_)), (async (i_, $task) => {
|
|
836
|
+
ff_core_Array.Array_push(result_, (await body_((self_[i_] ?? ff_core_List.internalGrab_(self_, i_)), $task)))
|
|
837
|
+
}), $task));
|
|
838
|
+
return ff_core_Array.Array_drain(result_)
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
818
842
|
export async function List_flatMap$(self_, body_, $task) {
|
|
819
843
|
const results_ = ff_core_Array.new_();
|
|
820
844
|
(await ff_core_List.List_each$(self_, (async (x_, $task) => {
|
package/package.json
CHANGED