firefly-compiler 0.5.14 → 0.5.15
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/JsEmitter.ff +9 -0
- package/fireflysite/Test.ff +8 -2
- package/fireflysite/assets/markdown/reference/FunctionsAndMethods.md +33 -13
- package/output/js/ff/compiler/Builder.mjs +8 -4
- package/output/js/ff/compiler/Compiler.mjs +8 -4
- package/output/js/ff/compiler/Inference.mjs +42 -22
- package/output/js/ff/compiler/JsEmitter.mjs +28 -0
- package/output/js/ff/compiler/Parser.mjs +18 -10
- package/output/js/ff/compiler/Resolver.mjs +10 -6
- package/output/js/ff/compiler/Unification.mjs +16 -8
- package/output/js/ff/compiler/Workspace.mjs +6 -4
- package/output/js/ff/core/List.mjs +8 -4
- package/package.json +1 -1
- package/vscode/package.json +1 -1
package/compiler/JsEmitter.ff
CHANGED
|
@@ -692,6 +692,15 @@ extend self: JsEmitter {
|
|
|
692
692
|
invokeImmediately(doWhileBody) | body
|
|
693
693
|
} =>
|
|
694
694
|
Some("while(" + self.emitComma(body, async) + ") {}")
|
|
695
|
+
| "ff:core/Option.Option_each" {arguments | [list, ELambda(_, Lambda(_, _, [
|
|
696
|
+
MatchCase(_, [PVariable(_, name)], [], body)
|
|
697
|
+
]))]} =>
|
|
698
|
+
Some(
|
|
699
|
+
"for(let for_o = " + self.emitTerm(list, async) + "; for_o.Some;) {\n" +
|
|
700
|
+
name.map {"const " + escapeKeyword(_) + " = for_o.value_;\n"}.else {""} +
|
|
701
|
+
self.emitStatements(body, last, async) +
|
|
702
|
+
"\nbreak\n}"
|
|
703
|
+
)
|
|
695
704
|
| "ff:core/List.List_each" {arguments | [
|
|
696
705
|
ECall(_, StaticCall(r, _, _), _, _, [start, end], _)
|
|
697
706
|
ELambda(_, Lambda(_, _, [MatchCase(_, [PVariable(_, name)], [], body)]))
|
package/fireflysite/Test.ff
CHANGED
|
@@ -27,12 +27,18 @@ nodeMain(system: NodeSystem) {
|
|
|
27
27
|
let foo = {{_ + 1}(_)}
|
|
28
28
|
Log.show(foo(1))
|
|
29
29
|
|
|
30
|
+
/*
|
|
30
31
|
let x1 = work(initial = 3) {i =>
|
|
31
32
|
i + 1
|
|
32
33
|
} {s =>
|
|
33
34
|
"*" + s + "*"
|
|
34
|
-
}
|
|
35
|
+
}*/
|
|
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
|
+
}
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
factorial(n: Int): Int {
|
|
@@ -53,4 +59,4 @@ factorialTail(n: Int, acc: Int = 1): Int {
|
|
|
53
59
|
|
|
54
60
|
work(f: Int => Int, g: String => String, initial: Int = 0): String {
|
|
55
61
|
g("" + f(initial))
|
|
56
|
-
}
|
|
62
|
+
}
|
|
@@ -240,51 +240,70 @@ let f: Int => Int = {{_ + 1}(_)}
|
|
|
240
240
|
In this code, there is an outer and an inner anonymous function, both taking one argument. The first underscore belongs to the inner function, which is called immediately by the outer function with the outer function's anonymous parameter as the argument.
|
|
241
241
|
|
|
242
242
|
|
|
243
|
-
# Trailing
|
|
243
|
+
# Trailing Anonymous Function Arguments
|
|
244
244
|
|
|
245
|
-
Firefly has special syntax for
|
|
245
|
+
Firefly has a special syntax for calling functions with function arguments. When a call has a sequence of literal anonymous functions as the last arguments, these arguments may be given using this special syntax. Consider the `if` function from the standard library, with this signature:
|
|
246
246
|
|
|
247
247
|
```firefly
|
|
248
248
|
if[T](condition: Bool, body: () => T): Option[T]
|
|
249
249
|
```
|
|
250
250
|
|
|
251
|
-
The `if` function takes two parameters, where the last is a function. Calling `if` with the standard syntax
|
|
251
|
+
The `if` function takes two parameters, where the last is a function. Calling `if` with the standard syntax could look like this:
|
|
252
252
|
|
|
253
253
|
```firefly
|
|
254
254
|
if(x == 0, {"Zero"})
|
|
255
255
|
```
|
|
256
256
|
|
|
257
|
-
Using the special syntax for trailing
|
|
257
|
+
Using the special syntax for trailing anonymous function arguments, it looks like this:
|
|
258
258
|
|
|
259
259
|
```firefly
|
|
260
260
|
if(x == 0) {"Zero"}
|
|
261
261
|
```
|
|
262
262
|
|
|
263
|
-
With this
|
|
263
|
+
With this syntax, the anonymous function is written after the call parentheses. Multiple trailing function arguments may be given in sequence. Consider the `while` function from the standard library, with this signature:
|
|
264
264
|
|
|
265
|
-
|
|
265
|
+
```firefly
|
|
266
|
+
while(condition: () => Bool, body: () => Unit): Unit
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
The `while` function takes two parameters, both functions. Using the special syntax, a call to `while` may look like this:
|
|
266
270
|
|
|
267
271
|
```firefly
|
|
268
|
-
|
|
269
|
-
|
|
272
|
+
while {array.size() < 5} {
|
|
273
|
+
array.push("X")
|
|
270
274
|
}
|
|
271
275
|
```
|
|
272
276
|
|
|
273
|
-
|
|
277
|
+
The code above will push a string to an array while the size of the array is less than 5.
|
|
278
|
+
|
|
279
|
+
This syntax for trailing anonymous function arguments allows the use of `if` and `while` to resemble constructs in languages such as C and JavaScript, where these constructs are built-in keywords rather than functions.
|
|
280
|
+
|
|
281
|
+
# Trailing Colon Function Argument
|
|
282
|
+
|
|
283
|
+
Firefly has a variation of the trailing anonymous function argument syntax. The very last anonymous function argument may be written after a colon, without curly braces. The purpose of this syntax is to avoid aditional indentation.
|
|
284
|
+
|
|
285
|
+
The example below calls `if` with a trailing colon function argument:
|
|
274
286
|
|
|
275
287
|
```firefly
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
"*" + s + "*"
|
|
288
|
+
safeFactorial(n: Int, acc: Int = 1): Option[Int] {
|
|
289
|
+
if(n >= 0):
|
|
290
|
+
factorial(n)
|
|
280
291
|
}
|
|
281
292
|
```
|
|
282
293
|
|
|
294
|
+
In this example, the `if` function is called with the condition `n >= 0` and an anonymous function that computes `factorial(n)`. If `n` is negative, the `if` function returns `None` and so does `safeFactorial`. Using the colon syntax, the `safeFactorial` functions continues unindented otherwise.
|
|
295
|
+
|
|
283
296
|
|
|
284
297
|
# Local functions
|
|
285
298
|
|
|
286
299
|
Local functions are declared exactly like top-level functions but with the `function` keyword in front of the signature, like this:
|
|
287
300
|
|
|
301
|
+
```firefly
|
|
302
|
+
function square(n: Int): Int {
|
|
303
|
+
n * n
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
288
307
|
The above local function definition is a statement, similar to local variables declared with `let`. The function name `square` will be in scope for the rest of the code block.
|
|
289
308
|
|
|
290
309
|
Furthermore, local functions declared in sequence are in scope within each other's bodies, allowing them to be mutually recursive.
|
|
@@ -323,6 +342,7 @@ extend self[T]: Option[T] {
|
|
|
323
342
|
}
|
|
324
343
|
```
|
|
325
344
|
|
|
345
|
+
|
|
326
346
|
Methods can be defined for a more narrow targer type, like `flatten` below:
|
|
327
347
|
|
|
328
348
|
```firefly
|
|
@@ -137,9 +137,11 @@ if(printMeasurements_) {
|
|
|
137
137
|
ff_compiler_Compiler.Compiler_printMeasurements(compiler_)
|
|
138
138
|
};
|
|
139
139
|
ff_core_Map.Map_each(resolvedDependencies_.packagePaths_, ((packagePair_, packagePath_) => {
|
|
140
|
-
|
|
140
|
+
for(let for_o = ff_core_Map.Map_get(resolvedDependencies_.packages_, packagePair_, ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair); for_o.Some;) {
|
|
141
|
+
const packageInfo_ = for_o.value_;
|
|
141
142
|
ff_compiler_Builder.processIncludes_(jsPathFile_, packagePath_, packageInfo_)
|
|
142
|
-
|
|
143
|
+
break
|
|
144
|
+
}
|
|
143
145
|
}), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair);
|
|
144
146
|
return true
|
|
145
147
|
}));
|
|
@@ -334,9 +336,11 @@ if(printMeasurements_) {
|
|
|
334
336
|
(await ff_compiler_Compiler.Compiler_printMeasurements$(compiler_, $task))
|
|
335
337
|
};
|
|
336
338
|
(await ff_core_Map.Map_each$(resolvedDependencies_.packagePaths_, (async (packagePair_, packagePath_, $task) => {
|
|
337
|
-
(
|
|
339
|
+
for(let for_o = ff_core_Map.Map_get(resolvedDependencies_.packages_, packagePair_, ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair); for_o.Some;) {
|
|
340
|
+
const packageInfo_ = for_o.value_;
|
|
338
341
|
(await ff_compiler_Builder.processIncludes_$(jsPathFile_, packagePath_, packageInfo_, $task))
|
|
339
|
-
|
|
342
|
+
break
|
|
343
|
+
}
|
|
340
344
|
}), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair, $task));
|
|
341
345
|
return true
|
|
342
346
|
}), $task));
|
|
@@ -171,11 +171,13 @@ return ff_compiler_ModuleCache.ModuleCache_cacheParsedModule(self_.cache_, self_
|
|
|
171
171
|
const packageName_ = ff_compiler_Syntax.PackagePair_groupName(packagePair_, ":");
|
|
172
172
|
return ff_compiler_Compiler.Compiler_measure(self_, "Parse", packagePair_, moduleName_, (() => {
|
|
173
173
|
const code_ = ff_core_Option.Option_else(ff_core_Map.Map_get(self_.virtualFiles_, ff_core_Path.Path_absolute(path_), ff_core_Ordering.ff_core_Ordering_Order$ff_core_String_String), (() => {
|
|
174
|
-
|
|
174
|
+
for(let for_o = importedAt_; for_o.Some;) {
|
|
175
|
+
const at_ = for_o.value_;
|
|
175
176
|
if((!ff_core_Path.Path_exists(path_, false, false, false))) {
|
|
176
177
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(at_, ((("Imported module not found: " + packageName_) + "/") + moduleName_)), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
177
178
|
}
|
|
178
|
-
|
|
179
|
+
break
|
|
180
|
+
};
|
|
179
181
|
return ff_core_Path.Path_readText(path_)
|
|
180
182
|
}));
|
|
181
183
|
const completionAt_ = ((ff_compiler_LspHook.LspHook_isEnabled(self_.lspHook_) && self_.lspHook_.insertIdentifier_)
|
|
@@ -302,11 +304,13 @@ return (await ff_compiler_ModuleCache.ModuleCache_cacheParsedModule$(self_.cache
|
|
|
302
304
|
const packageName_ = ff_compiler_Syntax.PackagePair_groupName(packagePair_, ":");
|
|
303
305
|
return (await ff_compiler_Compiler.Compiler_measure$(self_, "Parse", packagePair_, moduleName_, (async ($task) => {
|
|
304
306
|
const code_ = (await ff_core_Option.Option_else$(ff_core_Map.Map_get(self_.virtualFiles_, (await ff_core_Path.Path_absolute$(path_, $task)), ff_core_Ordering.ff_core_Ordering_Order$ff_core_String_String), (async ($task) => {
|
|
305
|
-
(
|
|
307
|
+
for(let for_o = importedAt_; for_o.Some;) {
|
|
308
|
+
const at_ = for_o.value_;
|
|
306
309
|
if((!(await ff_core_Path.Path_exists$(path_, false, false, false, $task)))) {
|
|
307
310
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(at_, ((("Imported module not found: " + packageName_) + "/") + moduleName_)), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
308
311
|
}
|
|
309
|
-
|
|
312
|
+
break
|
|
313
|
+
};
|
|
310
314
|
return (await ff_core_Path.Path_readText$(path_, $task))
|
|
311
315
|
}), $task));
|
|
312
316
|
const completionAt_ = ((ff_compiler_LspHook.LspHook_isEnabled(self_.lspHook_) && self_.lspHook_.insertIdentifier_)
|
|
@@ -669,9 +669,11 @@ if(_1.EField) {
|
|
|
669
669
|
const e_ = _1;
|
|
670
670
|
const recordType_ = ff_compiler_Unification.Unification_freshUnificationVariable(self_.unification_, e_.at_);
|
|
671
671
|
if(ff_compiler_LspHook.LspHook_isAt(self_.lspHook_, term_.at_)) {
|
|
672
|
-
|
|
672
|
+
for(let for_o = hookRecordTypeBox_; for_o.Some;) {
|
|
673
|
+
const _w1 = for_o.value_;
|
|
673
674
|
_w1.value_ = ff_core_Option.Some(recordType_)
|
|
674
|
-
|
|
675
|
+
break
|
|
676
|
+
}
|
|
675
677
|
};
|
|
676
678
|
const record_ = ff_compiler_Inference.Inference_inferTerm(self_, environment_, recordType_, e_.record_);
|
|
677
679
|
{
|
|
@@ -1201,9 +1203,11 @@ if(_1.EField) {
|
|
|
1201
1203
|
const f_ = _1;
|
|
1202
1204
|
const recordType_ = ff_compiler_Unification.Unification_freshUnificationVariable(self_.unification_, f_.at_);
|
|
1203
1205
|
if(ff_compiler_LspHook.LspHook_isAt(self_.lspHook_, term_.at_)) {
|
|
1204
|
-
|
|
1206
|
+
for(let for_o = hookRecordTypeBox_; for_o.Some;) {
|
|
1207
|
+
const _w1 = for_o.value_;
|
|
1205
1208
|
_w1.value_ = ff_core_Option.Some(recordType_)
|
|
1206
|
-
|
|
1209
|
+
break
|
|
1210
|
+
}
|
|
1207
1211
|
};
|
|
1208
1212
|
const record_ = ff_compiler_Inference.Inference_inferTerm(self_, environment_, recordType_, f_.record_);
|
|
1209
1213
|
const e2_ = (((_c) => {
|
|
@@ -1503,9 +1507,11 @@ const arguments_ = ff_core_List.List_map(ff_core_List.List_zip(e_.arguments_, ar
|
|
|
1503
1507
|
{
|
|
1504
1508
|
const argument_ = _1.first_;
|
|
1505
1509
|
const t_ = _1.second_;
|
|
1506
|
-
|
|
1510
|
+
for(let for_o = argument_.name_; for_o.Some;) {
|
|
1511
|
+
const name_ = for_o.value_;
|
|
1507
1512
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(argument_.at_, ("Named argument not allowed here: " + name_)), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
1508
|
-
|
|
1513
|
+
break
|
|
1514
|
+
};
|
|
1509
1515
|
{
|
|
1510
1516
|
const _1 = argument_;
|
|
1511
1517
|
{
|
|
@@ -1516,9 +1522,11 @@ return ff_compiler_Syntax.Argument(_c.at_, _c.name_, ff_compiler_Inference.Infer
|
|
|
1516
1522
|
return
|
|
1517
1523
|
}
|
|
1518
1524
|
}));
|
|
1519
|
-
|
|
1525
|
+
for(let for_o = ff_core_List.List_first(e_.typeArguments_); for_o.Some;) {
|
|
1526
|
+
const typeArgument_ = for_o.value_;
|
|
1520
1527
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(typeArgument_.at_, "Type arguments not allowed here"), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
1521
|
-
|
|
1528
|
+
break
|
|
1529
|
+
};
|
|
1522
1530
|
ff_compiler_Unification.Unification_affect(self_.unification_, term_.at_, effect_, environment_.effect_);
|
|
1523
1531
|
{
|
|
1524
1532
|
const _1 = e_;
|
|
@@ -1881,11 +1889,13 @@ return ff_core_Option.Option_contains(_w1.name_, p_.name_, ff_core_Equal.ff_core
|
|
|
1881
1889
|
{
|
|
1882
1890
|
const at_ = _1.at_;
|
|
1883
1891
|
const e_ = _1.value_;
|
|
1884
|
-
|
|
1892
|
+
for(let for_o = ff_core_Array.Array_indexWhere(remainingArguments_, ((_w1) => {
|
|
1885
1893
|
return ff_core_Option.Option_contains(_w1.name_, p_.name_, ff_core_Equal.ff_core_Equal_Equal$ff_core_String_String)
|
|
1886
|
-
}))
|
|
1894
|
+
})); for_o.Some;) {
|
|
1895
|
+
const _w1 = for_o.value_;
|
|
1887
1896
|
ff_core_Array.Array_delete(remainingArguments_, _w1, 1)
|
|
1888
|
-
|
|
1897
|
+
break
|
|
1898
|
+
};
|
|
1889
1899
|
const e2_ = ff_compiler_Inference.Inference_inferTerm(self_, environment_, t_, e_);
|
|
1890
1900
|
return ff_compiler_Syntax.Argument(at_, ff_core_Option.Some(p_.name_), e2_)
|
|
1891
1901
|
}
|
|
@@ -2521,9 +2531,11 @@ if(_1.EField) {
|
|
|
2521
2531
|
const e_ = _1;
|
|
2522
2532
|
const recordType_ = ff_compiler_Unification.Unification_freshUnificationVariable(self_.unification_, e_.at_);
|
|
2523
2533
|
if(ff_compiler_LspHook.LspHook_isAt(self_.lspHook_, term_.at_)) {
|
|
2524
|
-
|
|
2534
|
+
for(let for_o = hookRecordTypeBox_; for_o.Some;) {
|
|
2535
|
+
const _w1 = for_o.value_;
|
|
2525
2536
|
_w1.value_ = ff_core_Option.Some(recordType_)
|
|
2526
|
-
|
|
2537
|
+
break
|
|
2538
|
+
}
|
|
2527
2539
|
};
|
|
2528
2540
|
const record_ = ff_compiler_Inference.Inference_inferTerm(self_, environment_, recordType_, e_.record_);
|
|
2529
2541
|
{
|
|
@@ -3053,9 +3065,11 @@ if(_1.EField) {
|
|
|
3053
3065
|
const f_ = _1;
|
|
3054
3066
|
const recordType_ = ff_compiler_Unification.Unification_freshUnificationVariable(self_.unification_, f_.at_);
|
|
3055
3067
|
if(ff_compiler_LspHook.LspHook_isAt(self_.lspHook_, term_.at_)) {
|
|
3056
|
-
|
|
3068
|
+
for(let for_o = hookRecordTypeBox_; for_o.Some;) {
|
|
3069
|
+
const _w1 = for_o.value_;
|
|
3057
3070
|
_w1.value_ = ff_core_Option.Some(recordType_)
|
|
3058
|
-
|
|
3071
|
+
break
|
|
3072
|
+
}
|
|
3059
3073
|
};
|
|
3060
3074
|
const record_ = ff_compiler_Inference.Inference_inferTerm(self_, environment_, recordType_, f_.record_);
|
|
3061
3075
|
const e2_ = (((_c) => {
|
|
@@ -3355,9 +3369,11 @@ const arguments_ = ff_core_List.List_map(ff_core_List.List_zip(e_.arguments_, ar
|
|
|
3355
3369
|
{
|
|
3356
3370
|
const argument_ = _1.first_;
|
|
3357
3371
|
const t_ = _1.second_;
|
|
3358
|
-
|
|
3372
|
+
for(let for_o = argument_.name_; for_o.Some;) {
|
|
3373
|
+
const name_ = for_o.value_;
|
|
3359
3374
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(argument_.at_, ("Named argument not allowed here: " + name_)), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
3360
|
-
|
|
3375
|
+
break
|
|
3376
|
+
};
|
|
3361
3377
|
{
|
|
3362
3378
|
const _1 = argument_;
|
|
3363
3379
|
{
|
|
@@ -3368,9 +3384,11 @@ return ff_compiler_Syntax.Argument(_c.at_, _c.name_, ff_compiler_Inference.Infer
|
|
|
3368
3384
|
return
|
|
3369
3385
|
}
|
|
3370
3386
|
}));
|
|
3371
|
-
|
|
3387
|
+
for(let for_o = ff_core_List.List_first(e_.typeArguments_); for_o.Some;) {
|
|
3388
|
+
const typeArgument_ = for_o.value_;
|
|
3372
3389
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(typeArgument_.at_, "Type arguments not allowed here"), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
3373
|
-
|
|
3390
|
+
break
|
|
3391
|
+
};
|
|
3374
3392
|
ff_compiler_Unification.Unification_affect(self_.unification_, term_.at_, effect_, environment_.effect_);
|
|
3375
3393
|
{
|
|
3376
3394
|
const _1 = e_;
|
|
@@ -3733,11 +3751,13 @@ return ff_core_Option.Option_contains(_w1.name_, p_.name_, ff_core_Equal.ff_core
|
|
|
3733
3751
|
{
|
|
3734
3752
|
const at_ = _1.at_;
|
|
3735
3753
|
const e_ = _1.value_;
|
|
3736
|
-
|
|
3754
|
+
for(let for_o = ff_core_Array.Array_indexWhere(remainingArguments_, ((_w1) => {
|
|
3737
3755
|
return ff_core_Option.Option_contains(_w1.name_, p_.name_, ff_core_Equal.ff_core_Equal_Equal$ff_core_String_String)
|
|
3738
|
-
}))
|
|
3756
|
+
})); for_o.Some;) {
|
|
3757
|
+
const _w1 = for_o.value_;
|
|
3739
3758
|
ff_core_Array.Array_delete(remainingArguments_, _w1, 1)
|
|
3740
|
-
|
|
3759
|
+
break
|
|
3760
|
+
};
|
|
3741
3761
|
const e2_ = ff_compiler_Inference.Inference_inferTerm(self_, environment_, t_, e_);
|
|
3742
3762
|
return ff_compiler_Syntax.Argument(at_, ff_core_Option.Some(p_.name_), e2_)
|
|
3743
3763
|
}
|
|
@@ -1971,6 +1971,20 @@ return ff_core_Option.Some((("while(" + ff_compiler_JsEmitter.JsEmitter_emitComm
|
|
|
1971
1971
|
}
|
|
1972
1972
|
}
|
|
1973
1973
|
}
|
|
1974
|
+
if(_1 === "ff:core/Option.Option_each") {
|
|
1975
|
+
const _guard1 = arguments_;
|
|
1976
|
+
if(_guard1.length === 2 && _guard1[1].ELambda && _guard1[1].lambda_.cases_.length === 1 && _guard1[1].lambda_.cases_[0].patterns_.length === 1 && _guard1[1].lambda_.cases_[0].patterns_[0].PVariable && _guard1[1].lambda_.cases_[0].guards_.length === 0) {
|
|
1977
|
+
const list_ = _guard1[0];
|
|
1978
|
+
const name_ = _guard1[1].lambda_.cases_[0].patterns_[0].name_;
|
|
1979
|
+
const body_ = _guard1[1].lambda_.cases_[0].body_;
|
|
1980
|
+
return ff_core_Option.Some(((((("for(let for_o = " + ff_compiler_JsEmitter.JsEmitter_emitTerm(self_, list_, async_)) + "; for_o.Some;) {\n") + ff_core_Option.Option_else(ff_core_Option.Option_map(name_, ((_w1) => {
|
|
1981
|
+
return (("const " + ff_compiler_JsEmitter.escapeKeyword_(_w1)) + " = for_o.value_;\n")
|
|
1982
|
+
})), (() => {
|
|
1983
|
+
return ""
|
|
1984
|
+
}))) + ff_compiler_JsEmitter.JsEmitter_emitStatements(self_, body_, last_, async_)) + "\nbreak\n}"))
|
|
1985
|
+
return
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1974
1988
|
if(_1 === "ff:core/List.List_each") {
|
|
1975
1989
|
const _guard2 = arguments_;
|
|
1976
1990
|
if(_guard2.length === 2 && _guard2[0].ECall && _guard2[0].target_.StaticCall && _guard2[0].arguments_.length === 2 && _guard2[1].ELambda && _guard2[1].lambda_.cases_.length === 1 && _guard2[1].lambda_.cases_[0].patterns_.length === 1 && _guard2[1].lambda_.cases_[0].patterns_[0].PVariable && _guard2[1].lambda_.cases_[0].guards_.length === 0) {
|
|
@@ -3944,6 +3958,20 @@ return ff_core_Option.Some((("while(" + (await ff_compiler_JsEmitter.JsEmitter_e
|
|
|
3944
3958
|
}
|
|
3945
3959
|
}
|
|
3946
3960
|
}
|
|
3961
|
+
if(_1 === "ff:core/Option.Option_each") {
|
|
3962
|
+
const _guard1 = arguments_;
|
|
3963
|
+
if(_guard1.length === 2 && _guard1[1].ELambda && _guard1[1].lambda_.cases_.length === 1 && _guard1[1].lambda_.cases_[0].patterns_.length === 1 && _guard1[1].lambda_.cases_[0].patterns_[0].PVariable && _guard1[1].lambda_.cases_[0].guards_.length === 0) {
|
|
3964
|
+
const list_ = _guard1[0];
|
|
3965
|
+
const name_ = _guard1[1].lambda_.cases_[0].patterns_[0].name_;
|
|
3966
|
+
const body_ = _guard1[1].lambda_.cases_[0].body_;
|
|
3967
|
+
return ff_core_Option.Some(((((("for(let for_o = " + (await ff_compiler_JsEmitter.JsEmitter_emitTerm$(self_, list_, async_, $task))) + "; for_o.Some;) {\n") + ff_core_Option.Option_else(ff_core_Option.Option_map(name_, ((_w1) => {
|
|
3968
|
+
return (("const " + ff_compiler_JsEmitter.escapeKeyword_(_w1)) + " = for_o.value_;\n")
|
|
3969
|
+
})), (() => {
|
|
3970
|
+
return ""
|
|
3971
|
+
}))) + (await ff_compiler_JsEmitter.JsEmitter_emitStatements$(self_, body_, last_, async_, $task))) + "\nbreak\n}"))
|
|
3972
|
+
return
|
|
3973
|
+
}
|
|
3974
|
+
}
|
|
3947
3975
|
if(_1 === "ff:core/List.List_each") {
|
|
3948
3976
|
const _guard2 = arguments_;
|
|
3949
3977
|
if(_guard2.length === 2 && _guard2[0].ECall && _guard2[0].target_.StaticCall && _guard2[0].arguments_.length === 2 && _guard2[1].ELambda && _guard2[1].lambda_.cases_.length === 1 && _guard2[1].lambda_.cases_[0].patterns_.length === 1 && _guard2[1].lambda_.cases_[0].patterns_[0].PVariable && _guard2[1].lambda_.cases_[0].guards_.length === 0) {
|
|
@@ -324,9 +324,11 @@ return ff_compiler_Parser.Parser_skip(self_, kind_)
|
|
|
324
324
|
|
|
325
325
|
export function Parser_parseModuleWithoutPackageInfo(self_) {
|
|
326
326
|
const moduleWithPackageInfo_ = ff_compiler_Parser.Parser_parseModuleWithPackageInfo(self_);
|
|
327
|
-
|
|
327
|
+
for(let for_o = moduleWithPackageInfo_.packageInfo_; for_o.Some;) {
|
|
328
|
+
const info_ = for_o.value_;
|
|
328
329
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(info_.package_.at_, "Package and dependencies already declared in package.ff"), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
329
|
-
|
|
330
|
+
break
|
|
331
|
+
};
|
|
330
332
|
return moduleWithPackageInfo_.module_
|
|
331
333
|
}
|
|
332
334
|
|
|
@@ -1571,11 +1573,13 @@ const member_ = ff_compiler_Syntax.EString(ff_compiler_Token.Token_at(token_), (
|
|
|
1571
1573
|
: (("\"" + ff_compiler_Token.Token_raw(token_)) + "\"")));
|
|
1572
1574
|
if(ff_compiler_Token.Token_rawIs(ff_compiler_Parser.Parser_current(self_), "(")) {
|
|
1573
1575
|
const arguments_ = ff_compiler_Parser.Parser_parseFunctionArguments(self_, record_.at_, false);
|
|
1574
|
-
|
|
1576
|
+
for(let for_o = ff_core_List.List_find(arguments_.first_, ((_w1) => {
|
|
1575
1577
|
return (!ff_core_Option.Option_isEmpty(_w1.name_))
|
|
1576
|
-
}))
|
|
1578
|
+
})); for_o.Some;) {
|
|
1579
|
+
const argument_ = for_o.value_;
|
|
1577
1580
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(argument_.at_, "Unexpected named argument"), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
1578
|
-
|
|
1581
|
+
break
|
|
1582
|
+
};
|
|
1579
1583
|
const effect_ = ff_compiler_Parser.Parser_freshUnificationVariable(self_, record_.at_);
|
|
1580
1584
|
const target_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EField(ff_compiler_Token.Token_at(token_), false, record_, ("call" + arguments_.first_.length)), false);
|
|
1581
1585
|
return ff_compiler_Syntax.ECall(record_.at_, target_, effect_, [], [ff_compiler_Syntax.Argument(member_.at_, ff_core_Option.None(), member_), ...arguments_.first_], [])
|
|
@@ -1906,9 +1910,11 @@ return ff_compiler_Parser.Parser_skip(self_, kind_)
|
|
|
1906
1910
|
|
|
1907
1911
|
export async function Parser_parseModuleWithoutPackageInfo$(self_, $task) {
|
|
1908
1912
|
const moduleWithPackageInfo_ = ff_compiler_Parser.Parser_parseModuleWithPackageInfo(self_);
|
|
1909
|
-
|
|
1913
|
+
for(let for_o = moduleWithPackageInfo_.packageInfo_; for_o.Some;) {
|
|
1914
|
+
const info_ = for_o.value_;
|
|
1910
1915
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(info_.package_.at_, "Package and dependencies already declared in package.ff"), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
1911
|
-
|
|
1916
|
+
break
|
|
1917
|
+
};
|
|
1912
1918
|
return moduleWithPackageInfo_.module_
|
|
1913
1919
|
}
|
|
1914
1920
|
|
|
@@ -3153,11 +3159,13 @@ const member_ = ff_compiler_Syntax.EString(ff_compiler_Token.Token_at(token_), (
|
|
|
3153
3159
|
: (("\"" + ff_compiler_Token.Token_raw(token_)) + "\"")));
|
|
3154
3160
|
if(ff_compiler_Token.Token_rawIs(ff_compiler_Parser.Parser_current(self_), "(")) {
|
|
3155
3161
|
const arguments_ = ff_compiler_Parser.Parser_parseFunctionArguments(self_, record_.at_, false);
|
|
3156
|
-
|
|
3162
|
+
for(let for_o = ff_core_List.List_find(arguments_.first_, ((_w1) => {
|
|
3157
3163
|
return (!ff_core_Option.Option_isEmpty(_w1.name_))
|
|
3158
|
-
}))
|
|
3164
|
+
})); for_o.Some;) {
|
|
3165
|
+
const argument_ = for_o.value_;
|
|
3159
3166
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(argument_.at_, "Unexpected named argument"), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
3160
|
-
|
|
3167
|
+
break
|
|
3168
|
+
};
|
|
3161
3169
|
const effect_ = ff_compiler_Parser.Parser_freshUnificationVariable(self_, record_.at_);
|
|
3162
3170
|
const target_ = ff_compiler_Syntax.DynamicCall(ff_compiler_Syntax.EField(ff_compiler_Token.Token_at(token_), false, record_, ("call" + arguments_.first_.length)), false);
|
|
3163
3171
|
return ff_compiler_Syntax.ECall(record_.at_, target_, effect_, [], [ff_compiler_Syntax.Argument(member_.at_, ff_core_Option.None(), member_), ...arguments_.first_], [])
|
|
@@ -867,11 +867,13 @@ return ff_compiler_Syntax.Signature(_c.at_, _c.name_, _c.member_, ["Q$", ...sign
|
|
|
867
867
|
: (((_c) => {
|
|
868
868
|
return ff_compiler_Syntax.Signature(_c.at_, _c.name_, _c.member_, _c.generics_, _c.constraints_, _c.parameters_, _c.returnType_, ff_compiler_Resolver.Resolver_freshUnificationVariable(self_, signature_.at_))
|
|
869
869
|
}))(signature_));
|
|
870
|
-
|
|
870
|
+
for(let for_o = ff_core_List.List_find(newSignature_.generics_, ((name_) => {
|
|
871
871
|
return ff_core_Set.Set_contains(self_.typeParameters_, name_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_String_String)
|
|
872
|
-
}))
|
|
872
|
+
})); for_o.Some;) {
|
|
873
|
+
const name_ = for_o.value_;
|
|
873
874
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(signature_.at_, (("Type parameter " + name_) + " is already in scope")), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
874
|
-
|
|
875
|
+
break
|
|
876
|
+
};
|
|
875
877
|
const self2_ = ff_compiler_Resolver.Resolver_withSignature(self_, newSignature_);
|
|
876
878
|
{
|
|
877
879
|
const _1 = newSignature_;
|
|
@@ -1810,11 +1812,13 @@ return ff_compiler_Syntax.Signature(_c.at_, _c.name_, _c.member_, ["Q$", ...sign
|
|
|
1810
1812
|
: (((_c) => {
|
|
1811
1813
|
return ff_compiler_Syntax.Signature(_c.at_, _c.name_, _c.member_, _c.generics_, _c.constraints_, _c.parameters_, _c.returnType_, ff_compiler_Resolver.Resolver_freshUnificationVariable(self_, signature_.at_))
|
|
1812
1814
|
}))(signature_));
|
|
1813
|
-
|
|
1815
|
+
for(let for_o = ff_core_List.List_find(newSignature_.generics_, ((name_) => {
|
|
1814
1816
|
return ff_core_Set.Set_contains(self_.typeParameters_, name_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_String_String)
|
|
1815
|
-
}))
|
|
1817
|
+
})); for_o.Some;) {
|
|
1818
|
+
const name_ = for_o.value_;
|
|
1816
1819
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(signature_.at_, (("Type parameter " + name_) + " is already in scope")), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
1817
|
-
|
|
1820
|
+
break
|
|
1821
|
+
};
|
|
1818
1822
|
const self2_ = ff_compiler_Resolver.Resolver_withSignature(self_, newSignature_);
|
|
1819
1823
|
{
|
|
1820
1824
|
const _1 = newSignature_;
|
|
@@ -469,7 +469,8 @@ const t_ = ff_compiler_Unification.Unification_substitute(self_, type_);
|
|
|
469
469
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(at_, ((("Infinite type: " + ff_compiler_Syntax.Type_show(ff_compiler_Syntax.TVariable(at_, index_), [t_])) + " = ") + ff_compiler_Syntax.Type_show(t_, []))), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
470
470
|
};
|
|
471
471
|
self_.substitution_ = ff_core_Map.Map_add(self_.substitution_, index_, type_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_Int_Int);
|
|
472
|
-
|
|
472
|
+
for(let for_o = ff_core_Map.Map_get(self_.constraints_, index_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_Int_Int); for_o.Some;) {
|
|
473
|
+
const map_ = for_o.value_;
|
|
473
474
|
self_.constraints_ = ff_core_Map.Map_remove(self_.constraints_, index_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_Int_Int);
|
|
474
475
|
ff_core_List.List_each(ff_core_Map.Map_pairs(map_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_String_String), ((_1) => {
|
|
475
476
|
{
|
|
@@ -480,13 +481,16 @@ ff_compiler_Unification.Unification_constrain(self_, at2_, type_, name_, generic
|
|
|
480
481
|
return
|
|
481
482
|
}
|
|
482
483
|
}))
|
|
483
|
-
|
|
484
|
-
|
|
484
|
+
break
|
|
485
|
+
};
|
|
486
|
+
for(let for_o = ff_core_Map.Map_get(self_.affects_, index_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_Int_Int); for_o.Some;) {
|
|
487
|
+
const affected_ = for_o.value_;
|
|
485
488
|
ff_core_Map.Map_remove(self_.affects_, index_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_Int_Int);
|
|
486
489
|
ff_core_Set.Set_each(affected_, ((i_) => {
|
|
487
490
|
ff_compiler_Unification.Unification_affect(self_, at_, type_, ff_compiler_Syntax.TVariable(at_, i_))
|
|
488
491
|
}), ff_core_Ordering.ff_core_Ordering_Order$ff_core_Int_Int)
|
|
489
|
-
|
|
492
|
+
break
|
|
493
|
+
}
|
|
490
494
|
}
|
|
491
495
|
|
|
492
496
|
export function Unification_affect(self_, at_, source_, target_) {
|
|
@@ -846,7 +850,8 @@ const t_ = ff_compiler_Unification.Unification_substitute(self_, type_);
|
|
|
846
850
|
throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_compiler_Syntax.CompileError(at_, ((("Infinite type: " + ff_compiler_Syntax.Type_show(ff_compiler_Syntax.TVariable(at_, index_), [t_])) + " = ") + ff_compiler_Syntax.Type_show(t_, []))), ff_compiler_Syntax.ff_core_Any_HasAnyTag$ff_compiler_Syntax_CompileError)})
|
|
847
851
|
};
|
|
848
852
|
self_.substitution_ = ff_core_Map.Map_add(self_.substitution_, index_, type_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_Int_Int);
|
|
849
|
-
|
|
853
|
+
for(let for_o = ff_core_Map.Map_get(self_.constraints_, index_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_Int_Int); for_o.Some;) {
|
|
854
|
+
const map_ = for_o.value_;
|
|
850
855
|
self_.constraints_ = ff_core_Map.Map_remove(self_.constraints_, index_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_Int_Int);
|
|
851
856
|
ff_core_List.List_each(ff_core_Map.Map_pairs(map_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_String_String), ((_1) => {
|
|
852
857
|
{
|
|
@@ -857,13 +862,16 @@ ff_compiler_Unification.Unification_constrain(self_, at2_, type_, name_, generic
|
|
|
857
862
|
return
|
|
858
863
|
}
|
|
859
864
|
}))
|
|
860
|
-
|
|
861
|
-
|
|
865
|
+
break
|
|
866
|
+
};
|
|
867
|
+
for(let for_o = ff_core_Map.Map_get(self_.affects_, index_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_Int_Int); for_o.Some;) {
|
|
868
|
+
const affected_ = for_o.value_;
|
|
862
869
|
ff_core_Map.Map_remove(self_.affects_, index_, ff_core_Ordering.ff_core_Ordering_Order$ff_core_Int_Int);
|
|
863
870
|
ff_core_Set.Set_each(affected_, ((i_) => {
|
|
864
871
|
ff_compiler_Unification.Unification_affect(self_, at_, type_, ff_compiler_Syntax.TVariable(at_, i_))
|
|
865
872
|
}), ff_core_Ordering.ff_core_Ordering_Order$ff_core_Int_Int)
|
|
866
|
-
|
|
873
|
+
break
|
|
874
|
+
}
|
|
867
875
|
}
|
|
868
876
|
|
|
869
877
|
export async function Unification_affect$(self_, at_, source_, target_, $task) {
|
|
@@ -136,9 +136,10 @@ const rules_ = ff_core_List.List_collect(lines_, ((line_) => {
|
|
|
136
136
|
const columns_ = ff_core_List.List_filter(ff_core_String.String_split(ff_core_String.String_replace(line_, "\t", " "), 32), ((_w1) => {
|
|
137
137
|
return (ff_core_String.String_size(_w1) !== 0)
|
|
138
138
|
}));
|
|
139
|
-
|
|
139
|
+
for(let for_o = defaultLocation_; for_o.Some;) {
|
|
140
140
|
ff_core_Core.panic_(("Unexpected rule after the * rule: " + line_))
|
|
141
|
-
|
|
141
|
+
break
|
|
142
|
+
};
|
|
142
143
|
if((columns_.length !== 2)) {
|
|
143
144
|
ff_core_Core.panic_(("Could not parse workspace rule: " + line_))
|
|
144
145
|
};
|
|
@@ -200,9 +201,10 @@ const rules_ = ff_core_List.List_collect(lines_, ((line_) => {
|
|
|
200
201
|
const columns_ = ff_core_List.List_filter(ff_core_String.String_split(ff_core_String.String_replace(line_, "\t", " "), 32), ((_w1) => {
|
|
201
202
|
return (ff_core_String.String_size(_w1) !== 0)
|
|
202
203
|
}));
|
|
203
|
-
|
|
204
|
+
for(let for_o = defaultLocation_; for_o.Some;) {
|
|
204
205
|
ff_core_Core.panic_(("Unexpected rule after the * rule: " + line_))
|
|
205
|
-
|
|
206
|
+
break
|
|
207
|
+
};
|
|
206
208
|
if((columns_.length !== 2)) {
|
|
207
209
|
ff_core_Core.panic_(("Could not parse workspace rule: " + line_))
|
|
208
210
|
};
|
|
@@ -466,9 +466,11 @@ export function List_collect(self_, body_) {
|
|
|
466
466
|
let result_ = ff_core_Array.new_();
|
|
467
467
|
for(let for_i = 0, for_a = self_, for_l = for_a.length; for_i < for_l; for_i++) {
|
|
468
468
|
const x_ = for_a[for_i];
|
|
469
|
-
|
|
469
|
+
for(let for_o = body_(x_); for_o.Some;) {
|
|
470
|
+
const _w1 = for_o.value_;
|
|
470
471
|
result_.array.push(_w1)
|
|
471
|
-
|
|
472
|
+
break
|
|
473
|
+
}
|
|
472
474
|
};
|
|
473
475
|
return ff_core_Array.Array_drain(result_)
|
|
474
476
|
}
|
|
@@ -830,9 +832,11 @@ export async function List_collect$(self_, body_, $task) {
|
|
|
830
832
|
let result_ = ff_core_Array.new_();
|
|
831
833
|
for(let for_i = 0, for_a = self_, for_l = for_a.length; for_i < for_l; for_i++) {
|
|
832
834
|
const x_ = for_a[for_i];
|
|
833
|
-
|
|
835
|
+
for(let for_o = (await body_(x_, $task)); for_o.Some;) {
|
|
836
|
+
const _w1 = for_o.value_;
|
|
834
837
|
result_.array.push(_w1)
|
|
835
|
-
|
|
838
|
+
break
|
|
839
|
+
}
|
|
836
840
|
};
|
|
837
841
|
return ff_core_Array.Array_drain(result_)
|
|
838
842
|
}
|
package/package.json
CHANGED