firefly-compiler 0.4.17 → 0.4.19
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/Builder.ff +1 -1
- package/compiler/Compiler.ff +6 -5
- package/compiler/Inference.ff +31 -19
- package/compiler/JsEmitter.ff +98 -71
- package/compiler/JsImporter.ff +1 -1
- package/compiler/LspHook.ff +4 -4
- package/compiler/Main.ff +6 -6
- package/compiler/Parser.ff +39 -39
- package/compiler/Patterns.ff +2 -0
- package/compiler/Syntax.ff +1 -1
- package/compiler/Tokenizer.ff +2 -2
- package/compiler/Workspace.ff +2 -2
- package/core/Array.ff +135 -294
- package/core/Buffer.ff +3 -3
- package/core/BuildSystem.ff +1 -1
- package/core/Equal.ff +36 -52
- package/core/HttpClient.ff +1 -1
- package/core/IntMap.ff +14 -18
- package/core/JsSystem.ff +1 -1
- package/core/JsValue.ff +6 -12
- package/core/Json.ff +19 -28
- package/core/List.ff +281 -312
- package/core/Map.ff +4 -8
- package/core/NodeSystem.ff +2 -2
- package/core/Option.ff +0 -4
- package/core/Ordering.ff +10 -6
- package/core/Pair.ff +0 -4
- package/core/Random.ff +12 -26
- package/core/RbMap.ff +216 -216
- package/core/Serializable.ff +9 -18
- package/core/Set.ff +0 -1
- package/core/SourceLocation.ff +1 -1
- package/core/Stack.ff +32 -45
- package/core/Stream.ff +10 -14
- package/core/String.ff +24 -6
- package/core/StringMap.ff +15 -19
- package/guide/Main.ff +20 -2
- package/lsp/CompletionHandler.ff +4 -4
- package/lsp/Handler.ff +45 -34
- package/lsp/HoverHandler.ff +2 -2
- package/lsp/LanguageServer.ff +2 -2
- package/lsp/SignatureHelpHandler.ff +1 -1
- package/lsp/SymbolHandler.ff +1 -1
- package/lux/Lux.ff +3 -3
- package/output/js/ff/compiler/Builder.mjs +19 -21
- package/output/js/ff/compiler/Compiler.mjs +18 -20
- package/output/js/ff/compiler/Dependencies.mjs +8 -10
- package/output/js/ff/compiler/Deriver.mjs +234 -236
- package/output/js/ff/compiler/Dictionaries.mjs +6 -8
- package/output/js/ff/compiler/Environment.mjs +42 -44
- package/output/js/ff/compiler/Inference.mjs +346 -304
- package/output/js/ff/compiler/JsEmitter.mjs +907 -833
- package/output/js/ff/compiler/JsImporter.mjs +0 -2
- package/output/js/ff/compiler/LspHook.mjs +10 -12
- package/output/js/ff/compiler/Main.mjs +109 -111
- package/output/js/ff/compiler/Parser.mjs +405 -407
- package/output/js/ff/compiler/Patterns.mjs +64 -50
- package/output/js/ff/compiler/Resolver.mjs +36 -38
- package/output/js/ff/compiler/Substitution.mjs +4 -6
- package/output/js/ff/compiler/Syntax.mjs +160 -162
- package/output/js/ff/compiler/Token.mjs +52 -54
- package/output/js/ff/compiler/Tokenizer.mjs +16 -18
- package/output/js/ff/compiler/Unification.mjs +24 -26
- package/output/js/ff/compiler/Wildcards.mjs +0 -2
- package/output/js/ff/compiler/Workspace.mjs +18 -20
- package/output/js/ff/core/Any.mjs +0 -2
- package/output/js/ff/core/Array.mjs +216 -613
- package/output/js/ff/core/AssetSystem.mjs +2 -4
- package/output/js/ff/core/Atomic.mjs +0 -2
- package/output/js/ff/core/Bool.mjs +0 -2
- package/output/js/ff/core/Box.mjs +0 -2
- package/output/js/ff/core/BrowserSystem.mjs +0 -2
- package/output/js/ff/core/Buffer.mjs +0 -2
- package/output/js/ff/core/BuildSystem.mjs +12 -14
- package/output/js/ff/core/Channel.mjs +0 -2
- package/output/js/ff/core/Char.mjs +0 -2
- package/output/js/ff/core/Core.mjs +0 -2
- package/output/js/ff/core/Duration.mjs +0 -2
- package/output/js/ff/core/Equal.mjs +0 -22
- package/output/js/ff/core/Error.mjs +0 -2
- package/output/js/ff/core/FileHandle.mjs +0 -2
- package/output/js/ff/core/Float.mjs +0 -2
- package/output/js/ff/core/HttpClient.mjs +2 -4
- package/output/js/ff/core/Instant.mjs +0 -2
- package/output/js/ff/core/Int.mjs +8 -10
- package/output/js/ff/core/IntMap.mjs +32 -42
- package/output/js/ff/core/JsSystem.mjs +1 -3
- package/output/js/ff/core/JsValue.mjs +5 -12
- package/output/js/ff/core/Json.mjs +23 -56
- package/output/js/ff/core/List.mjs +648 -1989
- package/output/js/ff/core/Lock.mjs +0 -2
- package/output/js/ff/core/Log.mjs +0 -2
- package/output/js/ff/core/Map.mjs +10 -20
- package/output/js/ff/core/NodeSystem.mjs +6 -8
- package/output/js/ff/core/Nothing.mjs +0 -2
- package/output/js/ff/core/Option.mjs +8 -18
- package/output/js/ff/core/Ordering.mjs +20 -98
- package/output/js/ff/core/Pair.mjs +6 -16
- package/output/js/ff/core/Path.mjs +12 -14
- package/output/js/ff/core/Random.mjs +24 -54
- package/output/js/ff/core/RbMap.mjs +54 -56
- package/output/js/ff/core/Serializable.mjs +19 -36
- package/output/js/ff/core/Set.mjs +0 -14
- package/output/js/ff/core/Show.mjs +0 -2
- package/output/js/ff/core/SourceLocation.mjs +0 -2
- package/output/js/ff/core/Stream.mjs +34 -44
- package/output/js/ff/core/String.mjs +31 -5
- package/output/js/ff/core/StringMap.mjs +32 -42
- package/output/js/ff/core/Task.mjs +0 -2
- package/output/js/ff/core/Try.mjs +0 -2
- package/output/js/ff/core/Unit.mjs +0 -2
- package/package.json +1 -1
- package/vscode/package.json +1 -1
- package/webserver/WebServer.ff +8 -8
- package/output/js/ff/core/Stack.mjs +0 -603
package/compiler/Main.ff
CHANGED
|
@@ -108,7 +108,7 @@ main(system: NodeSystem): Unit {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
try {
|
|
111
|
-
let command = parseCommandLine(system.arguments()
|
|
111
|
+
let command = parseCommandLine(system.arguments())
|
|
112
112
|
runCommand(command)
|
|
113
113
|
} catch {| CommandLineError(message), error =>
|
|
114
114
|
Log.debug(message)
|
|
@@ -144,7 +144,7 @@ parseCommandLine(arguments: List[String]): MainCommand {
|
|
|
144
144
|
browserArguments.{
|
|
145
145
|
| [mainFile] {mainFile.removeLast(".ff") | Some(mainName)} =>
|
|
146
146
|
BrowserCommand(mainName)
|
|
147
|
-
| [_, _, ...
|
|
147
|
+
| [_, _, ...] => throw(CommandLineError(
|
|
148
148
|
"You must only specify a single argument to browser." + usageString
|
|
149
149
|
))
|
|
150
150
|
| _ => throw(CommandLineError(
|
|
@@ -155,7 +155,7 @@ parseCommandLine(arguments: List[String]): MainCommand {
|
|
|
155
155
|
buildArguments.{
|
|
156
156
|
| [mainFile] {mainFile.removeLast(".ff") | Some(mainName)} =>
|
|
157
157
|
BuildCommand(mainName)
|
|
158
|
-
| [_, _, ...
|
|
158
|
+
| [_, _, ...] => throw(CommandLineError(
|
|
159
159
|
"You must only specify a single argument to build." + usageString
|
|
160
160
|
))
|
|
161
161
|
| _ => throw(CommandLineError(
|
|
@@ -166,7 +166,7 @@ parseCommandLine(arguments: List[String]): MainCommand {
|
|
|
166
166
|
checkArguments.{
|
|
167
167
|
| [fileName] {fileName.removeLast(".ff") | Some(_)} =>
|
|
168
168
|
CheckCommand(fileName)
|
|
169
|
-
| [_, _, ...
|
|
169
|
+
| [_, _, ...] => throw(CommandLineError(
|
|
170
170
|
"You must only specify a single argument to check." + usageString
|
|
171
171
|
))
|
|
172
172
|
| _ => throw(CommandLineError(
|
|
@@ -177,7 +177,7 @@ parseCommandLine(arguments: List[String]): MainCommand {
|
|
|
177
177
|
throw(CommandLineError("bootstrap takes no arguments" + usageString))
|
|
178
178
|
| ["bootstrap"] => BootstrapCommand
|
|
179
179
|
| [] => throw(CommandLineError("You must specify a command or a main file to run." + usageString))
|
|
180
|
-
| [s, ...
|
|
180
|
+
| [s, ...] => throw(CommandLineError("Unknown command '" + s + "'" + usageString))
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
bundleForPkg(system: NodeSystem, packagePair: PackagePair, mainFile: String) {
|
|
@@ -213,7 +213,7 @@ importAndRun(
|
|
|
213
213
|
const workingDirectory = cwd.indexOf(':') == 1 ? 'file:///' + cwd : cwd;
|
|
214
214
|
const packagePath = packagePair_.group_ + "/" + packagePair_.name_
|
|
215
215
|
const main = await import(workingDirectory + "/.firefly/output/" + target_ + "/" + packagePath + "/" + mainFile_ + ".mjs");
|
|
216
|
-
await main.$run$(fireflyPath_,
|
|
216
|
+
await main.$run$(fireflyPath_, arguments_)
|
|
217
217
|
"""
|
|
218
218
|
|
|
219
219
|
prepareFireflyDirectory(path: Path) {
|
package/compiler/Parser.ff
CHANGED
|
@@ -6,7 +6,7 @@ import LspHook
|
|
|
6
6
|
class Parser(
|
|
7
7
|
packagePair: PackagePair
|
|
8
8
|
file: String
|
|
9
|
-
tokens:
|
|
9
|
+
tokens: List[Token]
|
|
10
10
|
end: Token
|
|
11
11
|
targetIsNode: Bool
|
|
12
12
|
lspHook: LspHook
|
|
@@ -32,7 +32,7 @@ data ParsedTargets(
|
|
|
32
32
|
make(
|
|
33
33
|
packagePair: PackagePair
|
|
34
34
|
file: String
|
|
35
|
-
tokens:
|
|
35
|
+
tokens: List[Token]
|
|
36
36
|
targetIsNode: Bool
|
|
37
37
|
lspHook: LspHook
|
|
38
38
|
): Parser {
|
|
@@ -151,12 +151,12 @@ extend self: Parser {
|
|
|
151
151
|
/* TODO: if(self.package != None && self.current().is(LKeyword) && self.current().rawIs("dependency")) {
|
|
152
152
|
self.fail(self.current().at(), "Dependencies must be defined in the same file as the package declaration")
|
|
153
153
|
}*/
|
|
154
|
-
let dependencies =
|
|
154
|
+
let dependencies = Array.make[DDependency]()
|
|
155
155
|
while {self.current().is(LKeyword) && self.current().rawIs("dependency")} {
|
|
156
156
|
dependencies.push(self.parseDependencyDefinition(package.targets))
|
|
157
157
|
if(!self.current().is(LEnd)) {self.skipSeparator(LSemicolon)}
|
|
158
158
|
}
|
|
159
|
-
let includes =
|
|
159
|
+
let includes = Array.make[DInclude]()
|
|
160
160
|
while {self.current().is(LKeyword) && self.current().rawIs("include")} {
|
|
161
161
|
includes.push(self.parseIncludeDefinition())
|
|
162
162
|
if(!self.current().is(LEnd)) {self.skipSeparator(LSemicolon)}
|
|
@@ -166,13 +166,13 @@ extend self: Parser {
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
parseModule(): Module {
|
|
169
|
-
let imports =
|
|
170
|
-
let types =
|
|
171
|
-
let traits =
|
|
172
|
-
let instances =
|
|
173
|
-
let extends =
|
|
174
|
-
let lets =
|
|
175
|
-
let functions =
|
|
169
|
+
let imports = Array.make[DImport]()
|
|
170
|
+
let types = Array.make[DType]()
|
|
171
|
+
let traits = Array.make[DTrait]()
|
|
172
|
+
let instances = Array.make[DInstance]()
|
|
173
|
+
let extends = Array.make[DExtend]()
|
|
174
|
+
let lets = Array.make[DLet]()
|
|
175
|
+
let functions = Array.make[DFunction]()
|
|
176
176
|
while {!self.current().is(LEnd)} {
|
|
177
177
|
if(self.current().is(LLower) && (self.ahead().is(LAssign) || self.ahead().is(LColon))) {
|
|
178
178
|
lets.push(self.parseLetDefinition())
|
|
@@ -349,7 +349,7 @@ extend self: Parser {
|
|
|
349
349
|
self.skip(LColon)
|
|
350
350
|
let type = self.parseType()
|
|
351
351
|
self.rawSkip(LBracketLeft, "{")
|
|
352
|
-
let methods =
|
|
352
|
+
let methods = Array.make[DFunction]()
|
|
353
353
|
while {!self.current().is(LBracketRight)} {
|
|
354
354
|
methods.push(self.parseFunctionDefinition(member = True))
|
|
355
355
|
if(!self.current().is(LBracketRight)) {self.skipSeparator(LSemicolon)}
|
|
@@ -389,7 +389,7 @@ extend self: Parser {
|
|
|
389
389
|
self.skip(LColon)
|
|
390
390
|
let nameToken = self.skip(LUpper)
|
|
391
391
|
let poly = if(!self.current().rawIs("[")) {Poly([], [])} else {self.parseTypeParameters()}
|
|
392
|
-
let constraints =
|
|
392
|
+
let constraints = Array.make[Constraint]()
|
|
393
393
|
while {self.current().is(LColon)} {
|
|
394
394
|
self.fail(self.current().at(), "Trait constraints is not yet implemented")
|
|
395
395
|
self.skip(LColon)
|
|
@@ -399,10 +399,10 @@ extend self: Parser {
|
|
|
399
399
|
))
|
|
400
400
|
}
|
|
401
401
|
let generatorParameters = if(!self.current().rawIs("(")) {[]} else {self.parseFunctionParameters()}
|
|
402
|
-
let methodGenerators =
|
|
403
|
-
let methodDefaults =
|
|
402
|
+
let methodGenerators = Array.make[Pair[String, Lambda]]()
|
|
403
|
+
let methodDefaults = Array.make[Pair[String, Lambda]]()
|
|
404
404
|
let methodSignatures = if(!self.current().rawIs("{")) {[]} else {
|
|
405
|
-
let signatures =
|
|
405
|
+
let signatures = Array.make[Signature]()
|
|
406
406
|
self.rawSkip(LBracketLeft, "{")
|
|
407
407
|
while {!self.current().is(LBracketRight)} {
|
|
408
408
|
if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}
|
|
@@ -460,7 +460,7 @@ extend self: Parser {
|
|
|
460
460
|
let instanceToken = self.rawSkip(LKeyword, "instance")
|
|
461
461
|
let token = self.skip(LUpper)
|
|
462
462
|
let poly = if(!self.current().rawIs("[")) {Poly([], [])} else {self.parseTypeParameters()}
|
|
463
|
-
let typeArguments =
|
|
463
|
+
let typeArguments = Array.make[Type]()
|
|
464
464
|
typeArguments.push(TConstructor(token.at(), token.raw(), poly.generics.map {TConstructor(token.at(), _, [])}))
|
|
465
465
|
self.skip(LColon)
|
|
466
466
|
let nameToken = self.skip(LUpper)
|
|
@@ -474,7 +474,7 @@ extend self: Parser {
|
|
|
474
474
|
}
|
|
475
475
|
let generatorArguments = self.parseFunctionArguments(nameToken.at(), False).first
|
|
476
476
|
let methods = if(!self.current().rawIs("{")) {[]} else {
|
|
477
|
-
let definitions =
|
|
477
|
+
let definitions = Array.make[DFunction]()
|
|
478
478
|
self.rawSkip(LBracketLeft, "{")
|
|
479
479
|
while {!self.current().is(LBracketRight)} {
|
|
480
480
|
definitions.push(self.parseFunctionDefinition(member = False))
|
|
@@ -528,7 +528,7 @@ extend self: Parser {
|
|
|
528
528
|
[Variant(nameToken.at(), nameToken.raw(), [])]
|
|
529
529
|
} else {
|
|
530
530
|
self.rawSkip(LBracketLeft, "{")
|
|
531
|
-
let variantsBuilder =
|
|
531
|
+
let variantsBuilder = Array.make[Variant]()
|
|
532
532
|
while {!self.current().is(LBracketRight)} {
|
|
533
533
|
if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}
|
|
534
534
|
let variantNameToken = self.skip(LUpper)
|
|
@@ -583,7 +583,7 @@ extend self: Parser {
|
|
|
583
583
|
|
|
584
584
|
parseImportDefinition(currentPackagePair: PackagePair): DImport {
|
|
585
585
|
let importToken = self.rawSkip(LKeyword, "import")
|
|
586
|
-
let path =
|
|
586
|
+
let path = Array.make[String]()
|
|
587
587
|
while {self.current().is(LLower)} {
|
|
588
588
|
path.push(self.parseDashedName())
|
|
589
589
|
self.skip(LDot)
|
|
@@ -712,8 +712,8 @@ extend self: Parser {
|
|
|
712
712
|
|
|
713
713
|
parseTypeParameters(): Poly {
|
|
714
714
|
self.rawSkip(LBracketLeft, "[")
|
|
715
|
-
let parameters =
|
|
716
|
-
let constraints =
|
|
715
|
+
let parameters = Array.make[String]()
|
|
716
|
+
let constraints = Array.make[Constraint]()
|
|
717
717
|
while {!self.current().is(LBracketRight) && !self.current().is(LSemicolon)} {
|
|
718
718
|
if(self.ahead().is(LBracketLeft)) {
|
|
719
719
|
constraints.push(self.parseConstraint())
|
|
@@ -736,7 +736,7 @@ extend self: Parser {
|
|
|
736
736
|
|
|
737
737
|
parseTypeArguments(parenthesis: Bool = False): List[Type] {
|
|
738
738
|
self.rawSkip(LBracketLeft, if(parenthesis) {"("} else {"["})
|
|
739
|
-
let types =
|
|
739
|
+
let types = Array.make[Type]()
|
|
740
740
|
while {!self.current().is(LBracketRight)} {
|
|
741
741
|
types.push(self.parseType())
|
|
742
742
|
if(!self.current().is(LBracketRight)) {self.skip(LComma)}
|
|
@@ -746,7 +746,7 @@ extend self: Parser {
|
|
|
746
746
|
}
|
|
747
747
|
|
|
748
748
|
parseFunctionParameters(allowMutable: Bool = False): List[Parameter] {
|
|
749
|
-
let parameters =
|
|
749
|
+
let parameters = Array.make[Parameter]()
|
|
750
750
|
self.rawSkip(LBracketLeft, "(")
|
|
751
751
|
while {!self.current().is(LBracketRight)} {
|
|
752
752
|
let lspTrackSymbols = self.lspHook.trackSymbols && allowMutable
|
|
@@ -784,7 +784,7 @@ extend self: Parser {
|
|
|
784
784
|
}
|
|
785
785
|
|
|
786
786
|
parseFunctionArguments(callAt: Location, trailing: Bool): Pair[List[Argument], Bool] {
|
|
787
|
-
let arguments =
|
|
787
|
+
let arguments = Array.make[Argument]()
|
|
788
788
|
if(self.current().rawIs("(")){
|
|
789
789
|
self.rawSkip(LBracketLeft, "(")
|
|
790
790
|
while {!self.current().is(LBracketRight)} {
|
|
@@ -854,13 +854,13 @@ extend self: Parser {
|
|
|
854
854
|
let token = if(colon) {self.skip(LColon)} else {self.rawSkip(LBracketLeft, "{")}
|
|
855
855
|
if(ignoreGenerateKeyword && self.current().is(LKeyword) && self.current().rawIs("generate")) {self.skip(LKeyword)}
|
|
856
856
|
let result = if(self.current().is(LPipe)) {
|
|
857
|
-
let cases =
|
|
857
|
+
let cases = Array.make[MatchCase]()
|
|
858
858
|
while {self.current().is(LPipe)} {
|
|
859
859
|
cases.push(self.parseCase())
|
|
860
860
|
}
|
|
861
861
|
cases.toList()
|
|
862
862
|
} elseIf {self.current().is2(LLower, LWildcard) && self.ahead().is2(LComma, LArrowThick)} {
|
|
863
|
-
let parameters =
|
|
863
|
+
let parameters = Array.make[MatchPattern]()
|
|
864
864
|
while {!self.current().is(LArrowThick)} {
|
|
865
865
|
let isVariable = self.current().is(LLower)
|
|
866
866
|
let parameterToken = if(isVariable) {self.skip(LLower)} else {self.skip(LWildcard)}
|
|
@@ -888,14 +888,14 @@ extend self: Parser {
|
|
|
888
888
|
|
|
889
889
|
parseCase(): MatchCase {
|
|
890
890
|
let token = self.skip(LPipe)
|
|
891
|
-
let patterns =
|
|
891
|
+
let patterns = Array.make[MatchPattern]()
|
|
892
892
|
while {!self.current().is3(LArrowThick, LPipe, LBracketRight) && !self.current().rawIs("{")} {
|
|
893
893
|
patterns.push(self.parsePattern())
|
|
894
894
|
if(!self.current().is3(LArrowThick, LPipe, LBracketRight) && !self.current().rawIs("{")) {
|
|
895
895
|
self.skip(LComma)
|
|
896
896
|
}
|
|
897
897
|
}
|
|
898
|
-
let guards =
|
|
898
|
+
let guards = Array.make[MatchGuard]()
|
|
899
899
|
while {self.current().rawIs("{")} {
|
|
900
900
|
guards.push(self.parseCaseGuard())
|
|
901
901
|
}
|
|
@@ -944,7 +944,7 @@ extend self: Parser {
|
|
|
944
944
|
} else {
|
|
945
945
|
let token = self.skip(LUpper)
|
|
946
946
|
if(self.current().rawIs("(")) {
|
|
947
|
-
let patterns =
|
|
947
|
+
let patterns = Array.make[MatchPattern]()
|
|
948
948
|
self.rawSkip(LBracketLeft, "(")
|
|
949
949
|
while {!self.current().is(LBracketRight)} {
|
|
950
950
|
let pattern = self.parsePattern()
|
|
@@ -1080,7 +1080,7 @@ extend self: Parser {
|
|
|
1080
1080
|
|
|
1081
1081
|
parseFunctions(): Term {
|
|
1082
1082
|
let at = self.current().at()
|
|
1083
|
-
let functions =
|
|
1083
|
+
let functions = Array.make[DFunction]()
|
|
1084
1084
|
while {self.current().rawIs("function")} {
|
|
1085
1085
|
if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}
|
|
1086
1086
|
let functionAt = self.rawSkip(LKeyword, "function").at()
|
|
@@ -1256,7 +1256,7 @@ extend self: Parser {
|
|
|
1256
1256
|
}
|
|
1257
1257
|
|
|
1258
1258
|
parseRecord(copyAt: Option[Location]): List[Field] {
|
|
1259
|
-
let fields =
|
|
1259
|
+
let fields = Array.make[Field]()
|
|
1260
1260
|
let startBracketAt = self.rawSkip(LBracketLeft, "(").at()
|
|
1261
1261
|
let startAt = copyAt.else {startBracketAt}
|
|
1262
1262
|
while {!self.current().is(LBracketRight)} {
|
|
@@ -1287,7 +1287,7 @@ extend self: Parser {
|
|
|
1287
1287
|
}
|
|
1288
1288
|
|
|
1289
1289
|
parseRecordType(): List[Pair[String, Type]] {
|
|
1290
|
-
let fields =
|
|
1290
|
+
let fields = Array.make[Pair[String, Type]]()
|
|
1291
1291
|
self.rawSkip(LBracketLeft, "(")
|
|
1292
1292
|
while {!self.current().is(LBracketRight)} {
|
|
1293
1293
|
let fieldToken = self.skip(LLower)
|
|
@@ -1300,7 +1300,7 @@ extend self: Parser {
|
|
|
1300
1300
|
}
|
|
1301
1301
|
|
|
1302
1302
|
parseRecordPattern(): List[Pair[String, MatchPattern]] {
|
|
1303
|
-
let fields =
|
|
1303
|
+
let fields = Array.make[Pair[String, MatchPattern]]()
|
|
1304
1304
|
self.rawSkip(LBracketLeft, "(")
|
|
1305
1305
|
while {!self.current().is(LBracketRight)} {
|
|
1306
1306
|
let fieldToken = self.skip(LLower)
|
|
@@ -1314,14 +1314,14 @@ extend self: Parser {
|
|
|
1314
1314
|
|
|
1315
1315
|
parseListPattern(): MatchPattern {
|
|
1316
1316
|
function convertListPattern(at: Location, items: List[Pair[MatchPattern, Bool]]): MatchPattern {
|
|
1317
|
-
| _, [] => PVariant(at, "
|
|
1317
|
+
| _, [] => PVariant(at, "List$Empty", [])
|
|
1318
1318
|
| _, [Pair(p, False), ...ps] =>
|
|
1319
|
-
PVariant(at, "
|
|
1319
|
+
PVariant(at, "List$Link", [p, convertListPattern(at, ps)])
|
|
1320
1320
|
| _, [Pair(p, True)] => p
|
|
1321
1321
|
| _, [Pair(p, True), ...] =>
|
|
1322
1322
|
throw(CompileError(p.at, "Invalid pattern: ... is only allowed for the last element in a list"))
|
|
1323
1323
|
}
|
|
1324
|
-
let items =
|
|
1324
|
+
let items = Array.make[Pair[MatchPattern, Bool]]()
|
|
1325
1325
|
let at = self.rawSkip(LBracketLeft, "[").at()
|
|
1326
1326
|
while {!self.current().rawIs("]")} {
|
|
1327
1327
|
let spread = self.current().is(LDotDotDot)
|
|
@@ -1339,7 +1339,7 @@ extend self: Parser {
|
|
|
1339
1339
|
}
|
|
1340
1340
|
|
|
1341
1341
|
parseList(): Term {
|
|
1342
|
-
let items =
|
|
1342
|
+
let items = Array.make[Pair[Term, Bool]]()
|
|
1343
1343
|
let at = self.rawSkip(LBracketLeft, "[").at()
|
|
1344
1344
|
while {!self.current().rawIs("]")} {
|
|
1345
1345
|
let spread = self.current().is(LDotDotDot)
|
|
@@ -1361,7 +1361,7 @@ binaryOperators = [
|
|
|
1361
1361
|
["+", "-"]
|
|
1362
1362
|
["*", "/", "%"]
|
|
1363
1363
|
["^"]
|
|
1364
|
-
]
|
|
1364
|
+
]
|
|
1365
1365
|
|
|
1366
1366
|
findBestTarget(targetIsNode: Bool, body: Option[Lambda], targets: ParsedTargets): Target {
|
|
1367
1367
|
let foreignTarget = if(targetIsNode) {
|
package/compiler/Patterns.ff
CHANGED
|
@@ -50,6 +50,8 @@ convert(modules: Map[String, Module], cases: List[MatchCase]): List[PatternCaseI
|
|
|
50
50
|
name.reverse().takeWhile {_ != '.'}.reverse()
|
|
51
51
|
}
|
|
52
52
|
function otherVariants(name: String): Set[String] {
|
|
53
|
+
if(name == "List$Empty") {["List$Link"].toSet()} else:
|
|
54
|
+
if(name == "List$Link") {["List$Empty"].toSet()} else:
|
|
53
55
|
let variantName = unqualifiedName(name)
|
|
54
56
|
let moduleName = name.dropLast(variantName.size() + 1)
|
|
55
57
|
let variantModule = modules.grab(moduleName)
|
package/compiler/Syntax.ff
CHANGED
|
@@ -264,7 +264,7 @@ extend self: Type {
|
|
|
264
264
|
| TConstructor(at, name, [_, ...generics]) {name.startsWith("Function$")} =>
|
|
265
265
|
"(" + generics.dropLast().map {go(_)}.join(", ") + ") => " + go(generics.grabLast())
|
|
266
266
|
| TConstructor(at, name, generics) {name.startsWith("Record$")} =>
|
|
267
|
-
let as = name.split('$').
|
|
267
|
+
let as = name.split('$').dropFirst().zip(generics)
|
|
268
268
|
"(" + as.map {| Pair(label, t) => label + ": " + go(t)}.join(", ") + ")"
|
|
269
269
|
| TConstructor(at, name, generics) =>
|
|
270
270
|
let shortenedName = shortenType(name)
|
package/compiler/Tokenizer.ff
CHANGED
|
@@ -2,12 +2,12 @@ import Token
|
|
|
2
2
|
import Syntax
|
|
3
3
|
import LspHook
|
|
4
4
|
|
|
5
|
-
tokenize(file: String, code: String, completionAt: Option[Location], attemptFixes: Bool):
|
|
5
|
+
tokenize(file: String, code: String, completionAt: Option[Location], attemptFixes: Bool): List[Token] {
|
|
6
6
|
|
|
7
7
|
let completionLine = completionAt.filter {_.file == file}.map {_.line}.else {-1}
|
|
8
8
|
let completionColumn = completionAt.filter {_.file == file}.map {_.column}.else {-1}
|
|
9
9
|
|
|
10
|
-
let tokens =
|
|
10
|
+
let tokens = Array.make[Token]()
|
|
11
11
|
mutable line = 1
|
|
12
12
|
mutable lineOffset = 0
|
|
13
13
|
|
package/compiler/Workspace.ff
CHANGED
|
@@ -29,9 +29,9 @@ loadWorkspace(path: Path): Workspace {
|
|
|
29
29
|
parseWorkspaceFile(path: Path, packageDirectory: Path): Workspace {
|
|
30
30
|
let text = path.readText()
|
|
31
31
|
mutable defaultLocation = None
|
|
32
|
-
let lines = text.split('\n').
|
|
32
|
+
let lines = text.split('\n').map {_.replace("\r", "").takeWhile {_ != '#'}}.filter {_.size() != 0}
|
|
33
33
|
let rules = lines.collect {line =>
|
|
34
|
-
let columns = line.replace("\t", " ").split(' ').
|
|
34
|
+
let columns = line.replace("\t", " ").split(' ').filter {_.size() != 0}
|
|
35
35
|
defaultLocation.each {_ =>
|
|
36
36
|
panic("Unexpected rule after the * rule: " + line)
|
|
37
37
|
}
|