firefly-compiler 0.4.87 → 0.4.89
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/compiler/Parser.ff +37 -4
- package/compiler/Tokenizer.ff +3 -1
- package/compression/.firefly/package.ff +1 -0
- package/compression/Compression.ff +55 -0
- package/output/js/ff/compiler/Parser.mjs +80 -8
- package/output/js/ff/compiler/Tokenizer.mjs +2 -2
- package/package.json +1 -1
- package/unsafejs/UnsafeJs.ff +4 -0
- package/vscode/package.json +1 -1
package/compiler/Parser.ff
CHANGED
|
@@ -1184,11 +1184,44 @@ extend self: Parser {
|
|
|
1184
1184
|
}
|
|
1185
1185
|
|
|
1186
1186
|
parseDynamicMember(record: Term): Term {
|
|
1187
|
-
self.skip(LArrowThin)
|
|
1188
|
-
|
|
1189
|
-
self.
|
|
1190
|
-
|
|
1187
|
+
let token = self.skip(LArrowThin)
|
|
1188
|
+
if(self.current().rawIs("(")) {
|
|
1189
|
+
let arguments = self.parseFunctionArguments(token.at(), trailing = False)
|
|
1190
|
+
let effect = self.freshUnificationVariable(record.at)
|
|
1191
|
+
arguments.first.indexWhere {!_.name.isEmpty()}.{
|
|
1192
|
+
| None =>
|
|
1193
|
+
let objectTarget = DynamicCall(EField(token.at(), False, record, "object"), False)
|
|
1194
|
+
mutable result = ECall(record.at, objectTarget, effect, [], [], [])
|
|
1195
|
+
arguments.first.each {argument =>
|
|
1196
|
+
if(argument.name.isEmpty()) {
|
|
1197
|
+
throw(CompileError(argument.at, "Expected a named argument"))
|
|
1198
|
+
}
|
|
1199
|
+
let target = DynamicCall(EField(token.at(), False, record, "with"), False)
|
|
1200
|
+
result = ECall(record.at, target, effect, [], [
|
|
1201
|
+
Argument(argument.at, None, EString(argument.at, argument.name.grab()))
|
|
1202
|
+
argument
|
|
1203
|
+
], [])
|
|
1204
|
+
}
|
|
1205
|
+
result
|
|
1206
|
+
| Some(0) =>
|
|
1207
|
+
let target = DynamicCall(EField(token.at(), False, record, "new" + arguments.first.size()), False)
|
|
1208
|
+
ECall(record.at, target, effect, [], arguments.first, [])
|
|
1209
|
+
| Some(i) =>
|
|
1210
|
+
throw(CompileError(arguments.first.grab(i).at, "Unexpected named argument"))
|
|
1211
|
+
}
|
|
1212
|
+
} elseIf {self.current().rawIs("{")} {
|
|
1213
|
+
let lambda = self.parseLambda()
|
|
1214
|
+
let effect = self.freshUnificationVariable(record.at)
|
|
1215
|
+
let arguments = lambda.cases.grabFirst().patterns.size()
|
|
1216
|
+
let target = DynamicCall(EField(token.at(), False, record, "function" + arguments), False)
|
|
1217
|
+
ECall(record.at, target, effect, [], [
|
|
1218
|
+
Argument(lambda.at, None, ELambda(lambda.at, lambda))
|
|
1219
|
+
], [])
|
|
1220
|
+
} else:
|
|
1221
|
+
let token = if(self.current().is(LLower)) {
|
|
1191
1222
|
self.skip(LLower)
|
|
1223
|
+
} elseIf {self.current().is(LUpper)} {
|
|
1224
|
+
self.skip(LUpper)
|
|
1192
1225
|
} else {
|
|
1193
1226
|
self.skip(LString)
|
|
1194
1227
|
}
|
package/compiler/Tokenizer.ff
CHANGED
|
@@ -162,7 +162,9 @@ tokenize(file: String, code: String, completionAt: Option[Location], attemptFixe
|
|
|
162
162
|
let kind = if(code.grab(i) >= 'a') {LLower} else {LUpper}
|
|
163
163
|
i += 1
|
|
164
164
|
while {i < code.size() && code.grab(i).isAsciiLetterOrDigit()} {i += 1}
|
|
165
|
-
if(i < code.size() && kind == LUpper && code.grab(i) == '.'
|
|
165
|
+
if(i < code.size() && kind == LUpper && code.grab(i) == '.' && (
|
|
166
|
+
tokens.isEmpty() || tokens.grabLast().kind != LArrowThin
|
|
167
|
+
)) {
|
|
166
168
|
i += 1
|
|
167
169
|
emitToken(LNamespace, start, i)
|
|
168
170
|
} else {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
dependency ff:unsafejs:0.0.0
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import UnsafeJs from ff:unsafejs
|
|
2
|
+
|
|
3
|
+
capability Compression {}
|
|
4
|
+
|
|
5
|
+
extend self: Compression {
|
|
6
|
+
|
|
7
|
+
compressBrotli(uncompressed: Buffer, level: Int = 4): Buffer {
|
|
8
|
+
internalCompress("brotli", level, uncompressed)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
decompressBrotli(compressed: Buffer): Buffer {
|
|
12
|
+
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
compressGzip(uncompressed: Buffer, level: Int = 6): Buffer {
|
|
16
|
+
internalCompress("gzip", level, uncompressed)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
decompressGzip(compressed: Buffer): Buffer {
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
compressDeflate(uncompressed: Buffer, level: Int = 6): Buffer {
|
|
24
|
+
internalCompress("deflate", level, uncompressed)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
decompressDeflate(compressed: Buffer): Buffer {
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
newForBrowserSystem(browserSystem: BrowserSystem): Compression
|
|
34
|
+
target js async "return globalThis"
|
|
35
|
+
|
|
36
|
+
newForNodeSystem(nodeSystem: NodeSystem): Compression
|
|
37
|
+
target js async "return globalThis"
|
|
38
|
+
|
|
39
|
+
internalCompress(algorithm: String, level: Int, buffer: Buffer): Buffer {
|
|
40
|
+
let js = UnsafeJs.jsSystem()
|
|
41
|
+
let dataView = UnsafeJs.toJsValue(buffer)
|
|
42
|
+
let uint8Array = js->Uint8Array->(dataView->buffer, dataView->byteOffset, dataView->byteLength)
|
|
43
|
+
let stream = js->ReadableStream->(js->(
|
|
44
|
+
start = js->{controller =>
|
|
45
|
+
controller->enqueue(uint8Array)
|
|
46
|
+
controller->close()
|
|
47
|
+
}
|
|
48
|
+
))
|
|
49
|
+
let ds = js->DecompressionStream->(algorithm)
|
|
50
|
+
let decompressedStream = stream->pipeThrough(ds)
|
|
51
|
+
let response = UnsafeJs.await {js->Response->(decompressedStream)}
|
|
52
|
+
let decompressedData = UnsafeJs.await {response->arrayBuffer()}
|
|
53
|
+
js->DataView->(decompressedData).grabBuffer()
|
|
54
|
+
}
|
|
55
|
+
|
|
@@ -1539,11 +1539,46 @@ return result_
|
|
|
1539
1539
|
}
|
|
1540
1540
|
|
|
1541
1541
|
export function Parser_parseDynamicMember(self_, record_) {
|
|
1542
|
-
ff_compiler_Parser.Parser_skip(self_, ff_compiler_Token.LArrowThin());
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1542
|
+
const token_ = ff_compiler_Parser.Parser_skip(self_, ff_compiler_Token.LArrowThin());
|
|
1543
|
+
if(ff_compiler_Token.Token_rawIs(ff_compiler_Parser.Parser_current(self_), "(")) {
|
|
1544
|
+
const arguments_ = ff_compiler_Parser.Parser_parseFunctionArguments(self_, ff_compiler_Token.Token_at(token_), false);
|
|
1545
|
+
const effect_ = ff_compiler_Parser.Parser_freshUnificationVariable(self_, record_.at_);
|
|
1546
|
+
{
|
|
1547
|
+
const _1 = ff_core_List.List_indexWhere(arguments_.first_, ((_w1) => {
|
|
1548
|
+
return (!ff_core_Option.Option_isEmpty(_w1.name_))
|
|
1549
|
+
}));
|
|
1550
|
+
if(_1.None) {
|
|
1551
|
+
const objectTarget_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EField(ff_compiler_Token.Token_at(token_), false, record_, "object"), false);
|
|
1552
|
+
let result_ = ff_compiler_Syntax.ECall(record_.at_, objectTarget_, effect_, [], [], []);
|
|
1553
|
+
ff_core_List.List_each(arguments_.first_, ((argument_) => {
|
|
1554
|
+
if(ff_core_Option.Option_isEmpty(argument_.name_)) {
|
|
1555
|
+
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(argument_.at_, "Expected a named argument"), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
1556
|
+
};
|
|
1557
|
+
const target_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EField(ff_compiler_Token.Token_at(token_), false, record_, "with"), false);
|
|
1558
|
+
result_ = ff_compiler_Syntax.ECall(record_.at_, target_, effect_, [], [ff_compiler_Syntax.Argument(argument_.at_, ff_core_Option.None(), ff_compiler_Syntax.EString(argument_.at_, ff_core_Option.Option_grab(argument_.name_))), argument_], [])
|
|
1559
|
+
}));
|
|
1560
|
+
return result_
|
|
1561
|
+
}
|
|
1562
|
+
if(_1.Some && _1.value_ === 0) {
|
|
1563
|
+
const target_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EField(ff_compiler_Token.Token_at(token_), false, record_, ("new" + ff_core_List.List_size(arguments_.first_))), false);
|
|
1564
|
+
return ff_compiler_Syntax.ECall(record_.at_, target_, effect_, [], arguments_.first_, [])
|
|
1565
|
+
}
|
|
1566
|
+
if(_1.Some) {
|
|
1567
|
+
const i_ = _1.value_;
|
|
1568
|
+
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(ff_core_List.List_grab(arguments_.first_, i_).at_, "Unexpected named argument"), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
} else if(ff_compiler_Token.Token_rawIs(ff_compiler_Parser.Parser_current(self_), "{")) {
|
|
1572
|
+
const lambda_ = ff_compiler_Parser.Parser_parseLambda(self_, 0, false, false);
|
|
1573
|
+
const effect_ = ff_compiler_Parser.Parser_freshUnificationVariable(self_, record_.at_);
|
|
1574
|
+
const arguments_ = ff_core_List.List_size(ff_core_List.List_grabFirst(lambda_.cases_).patterns_);
|
|
1575
|
+
const target_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EField(ff_compiler_Token.Token_at(token_), false, record_, ("function" + arguments_)), false);
|
|
1576
|
+
return ff_compiler_Syntax.ECall(record_.at_, target_, effect_, [], [ff_compiler_Syntax.Argument(lambda_.at_, ff_core_Option.None(), ff_compiler_Syntax.ELambda(lambda_.at_, lambda_))], [])
|
|
1577
|
+
} else {
|
|
1578
|
+
const token_ = (ff_compiler_Token.Token_is(ff_compiler_Parser.Parser_current(self_), ff_compiler_Token.LLower())
|
|
1546
1579
|
? ff_compiler_Parser.Parser_skip(self_, ff_compiler_Token.LLower())
|
|
1580
|
+
: ff_compiler_Token.Token_is(ff_compiler_Parser.Parser_current(self_), ff_compiler_Token.LUpper())
|
|
1581
|
+
? ff_compiler_Parser.Parser_skip(self_, ff_compiler_Token.LUpper())
|
|
1547
1582
|
: ff_compiler_Parser.Parser_skip(self_, ff_compiler_Token.LString()));
|
|
1548
1583
|
const member_ = ff_compiler_Syntax.EString(ff_compiler_Token.Token_at(token_), (ff_compiler_Token.Token_is(token_, ff_compiler_Token.LString())
|
|
1549
1584
|
? ff_compiler_Token.Token_raw(token_)
|
|
@@ -1578,6 +1613,7 @@ const target_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EField(ff_comp
|
|
|
1578
1613
|
return ff_compiler_Syntax.ECall(record_.at_, target_, effect_, [], [ff_compiler_Syntax.Argument(member_.at_, ff_core_Option.None(), member_)], [])
|
|
1579
1614
|
}
|
|
1580
1615
|
}
|
|
1616
|
+
}
|
|
1581
1617
|
|
|
1582
1618
|
export function Parser_parseAtom(self_) {
|
|
1583
1619
|
if(ff_compiler_Token.Token_is(ff_compiler_Parser.Parser_current(self_), ff_compiler_Token.LString())) {
|
|
@@ -3108,11 +3144,46 @@ return result_
|
|
|
3108
3144
|
}
|
|
3109
3145
|
|
|
3110
3146
|
export async function Parser_parseDynamicMember$(self_, record_, $task) {
|
|
3111
|
-
ff_compiler_Parser.Parser_skip(self_, ff_compiler_Token.LArrowThin());
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3147
|
+
const token_ = ff_compiler_Parser.Parser_skip(self_, ff_compiler_Token.LArrowThin());
|
|
3148
|
+
if(ff_compiler_Token.Token_rawIs(ff_compiler_Parser.Parser_current(self_), "(")) {
|
|
3149
|
+
const arguments_ = ff_compiler_Parser.Parser_parseFunctionArguments(self_, ff_compiler_Token.Token_at(token_), false);
|
|
3150
|
+
const effect_ = ff_compiler_Parser.Parser_freshUnificationVariable(self_, record_.at_);
|
|
3151
|
+
{
|
|
3152
|
+
const _1 = ff_core_List.List_indexWhere(arguments_.first_, ((_w1) => {
|
|
3153
|
+
return (!ff_core_Option.Option_isEmpty(_w1.name_))
|
|
3154
|
+
}));
|
|
3155
|
+
if(_1.None) {
|
|
3156
|
+
const objectTarget_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EField(ff_compiler_Token.Token_at(token_), false, record_, "object"), false);
|
|
3157
|
+
let result_ = ff_compiler_Syntax.ECall(record_.at_, objectTarget_, effect_, [], [], []);
|
|
3158
|
+
ff_core_List.List_each(arguments_.first_, ((argument_) => {
|
|
3159
|
+
if(ff_core_Option.Option_isEmpty(argument_.name_)) {
|
|
3160
|
+
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(argument_.at_, "Expected a named argument"), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
3161
|
+
};
|
|
3162
|
+
const target_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EField(ff_compiler_Token.Token_at(token_), false, record_, "with"), false);
|
|
3163
|
+
result_ = ff_compiler_Syntax.ECall(record_.at_, target_, effect_, [], [ff_compiler_Syntax.Argument(argument_.at_, ff_core_Option.None(), ff_compiler_Syntax.EString(argument_.at_, ff_core_Option.Option_grab(argument_.name_))), argument_], [])
|
|
3164
|
+
}));
|
|
3165
|
+
return result_
|
|
3166
|
+
}
|
|
3167
|
+
if(_1.Some && _1.value_ === 0) {
|
|
3168
|
+
const target_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EField(ff_compiler_Token.Token_at(token_), false, record_, ("new" + ff_core_List.List_size(arguments_.first_))), false);
|
|
3169
|
+
return ff_compiler_Syntax.ECall(record_.at_, target_, effect_, [], arguments_.first_, [])
|
|
3170
|
+
}
|
|
3171
|
+
if(_1.Some) {
|
|
3172
|
+
const i_ = _1.value_;
|
|
3173
|
+
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(ff_core_List.List_grab(arguments_.first_, i_).at_, "Unexpected named argument"), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3176
|
+
} else if(ff_compiler_Token.Token_rawIs(ff_compiler_Parser.Parser_current(self_), "{")) {
|
|
3177
|
+
const lambda_ = ff_compiler_Parser.Parser_parseLambda(self_, 0, false, false);
|
|
3178
|
+
const effect_ = ff_compiler_Parser.Parser_freshUnificationVariable(self_, record_.at_);
|
|
3179
|
+
const arguments_ = ff_core_List.List_size(ff_core_List.List_grabFirst(lambda_.cases_).patterns_);
|
|
3180
|
+
const target_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EField(ff_compiler_Token.Token_at(token_), false, record_, ("function" + arguments_)), false);
|
|
3181
|
+
return ff_compiler_Syntax.ECall(record_.at_, target_, effect_, [], [ff_compiler_Syntax.Argument(lambda_.at_, ff_core_Option.None(), ff_compiler_Syntax.ELambda(lambda_.at_, lambda_))], [])
|
|
3182
|
+
} else {
|
|
3183
|
+
const token_ = (ff_compiler_Token.Token_is(ff_compiler_Parser.Parser_current(self_), ff_compiler_Token.LLower())
|
|
3115
3184
|
? ff_compiler_Parser.Parser_skip(self_, ff_compiler_Token.LLower())
|
|
3185
|
+
: ff_compiler_Token.Token_is(ff_compiler_Parser.Parser_current(self_), ff_compiler_Token.LUpper())
|
|
3186
|
+
? ff_compiler_Parser.Parser_skip(self_, ff_compiler_Token.LUpper())
|
|
3116
3187
|
: ff_compiler_Parser.Parser_skip(self_, ff_compiler_Token.LString()));
|
|
3117
3188
|
const member_ = ff_compiler_Syntax.EString(ff_compiler_Token.Token_at(token_), (ff_compiler_Token.Token_is(token_, ff_compiler_Token.LString())
|
|
3118
3189
|
? ff_compiler_Token.Token_raw(token_)
|
|
@@ -3147,6 +3218,7 @@ const target_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EField(ff_comp
|
|
|
3147
3218
|
return ff_compiler_Syntax.ECall(record_.at_, target_, effect_, [], [ff_compiler_Syntax.Argument(member_.at_, ff_core_Option.None(), member_)], [])
|
|
3148
3219
|
}
|
|
3149
3220
|
}
|
|
3221
|
+
}
|
|
3150
3222
|
|
|
3151
3223
|
export async function Parser_parseAtom$(self_, $task) {
|
|
3152
3224
|
if(ff_compiler_Token.Token_is(ff_compiler_Parser.Parser_current(self_), ff_compiler_Token.LString())) {
|
|
@@ -245,7 +245,7 @@ i_ += 1;
|
|
|
245
245
|
while(((i_ < ff_core_String.String_size(code_)) && ff_core_Char.Char_isAsciiLetterOrDigit(ff_core_String.String_grab(code_, i_)))) {
|
|
246
246
|
i_ += 1
|
|
247
247
|
};
|
|
248
|
-
if((((i_ < ff_core_String.String_size(code_)) && ff_compiler_Token.ff_core_Equal_Equal$ff_compiler_Token_TokenKind.equals_(kind_, ff_compiler_Token.LUpper())) && (ff_core_String.String_grab(code_, i_) === 46))) {
|
|
248
|
+
if(((((i_ < ff_core_String.String_size(code_)) && ff_compiler_Token.ff_core_Equal_Equal$ff_compiler_Token_TokenKind.equals_(kind_, ff_compiler_Token.LUpper())) && (ff_core_String.String_grab(code_, i_) === 46)) && (ff_core_Array.Array_isEmpty(tokens_) || ff_core_Equal.notEquals_(ff_core_Array.Array_grabLast(tokens_).kind_, ff_compiler_Token.LArrowThin(), ff_compiler_Token.ff_core_Equal_Equal$ff_compiler_Token_TokenKind)))) {
|
|
249
249
|
i_ += 1;
|
|
250
250
|
emitToken_(ff_compiler_Token.LNamespace(), start_, i_)
|
|
251
251
|
} else {
|
|
@@ -489,7 +489,7 @@ i_ += 1;
|
|
|
489
489
|
while(((i_ < ff_core_String.String_size(code_)) && ff_core_Char.Char_isAsciiLetterOrDigit(ff_core_String.String_grab(code_, i_)))) {
|
|
490
490
|
i_ += 1
|
|
491
491
|
};
|
|
492
|
-
if((((i_ < ff_core_String.String_size(code_)) && ff_compiler_Token.ff_core_Equal_Equal$ff_compiler_Token_TokenKind.equals_(kind_, ff_compiler_Token.LUpper())) && (ff_core_String.String_grab(code_, i_) === 46))) {
|
|
492
|
+
if(((((i_ < ff_core_String.String_size(code_)) && ff_compiler_Token.ff_core_Equal_Equal$ff_compiler_Token_TokenKind.equals_(kind_, ff_compiler_Token.LUpper())) && (ff_core_String.String_grab(code_, i_) === 46)) && (ff_core_Array.Array_isEmpty(tokens_) || ff_core_Equal.notEquals_(ff_core_Array.Array_grabLast(tokens_).kind_, ff_compiler_Token.LArrowThin(), ff_compiler_Token.ff_core_Equal_Equal$ff_compiler_Token_TokenKind)))) {
|
|
493
493
|
i_ += 1;
|
|
494
494
|
emitToken_(ff_compiler_Token.LNamespace(), start_, i_)
|
|
495
495
|
} else {
|
package/package.json
CHANGED
package/unsafejs/UnsafeJs.ff
CHANGED