firefly-compiler 0.5.79 → 0.5.80

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.
Files changed (105) hide show
  1. package/compiler/Builder.ff +31 -39
  2. package/compiler/Compiler.ff +14 -4
  3. package/compiler/DevelopMode.ff +406 -0
  4. package/compiler/Main.ff +73 -53
  5. package/compiler/ModuleCache.ff +5 -5
  6. package/core/.firefly/include/package.json +1 -1
  7. package/core/BuildSystem.ff +82 -11
  8. package/core/NodeSystem.ff +47 -30
  9. package/core/Path.ff +7 -2
  10. package/experimental/proxy/Main.ff +60 -0
  11. package/experimental/proxy/Runner.ff +11 -0
  12. package/experimental/proxy/Tcp.ff +162 -0
  13. package/experimental/random/Superdigit.ff +18 -0
  14. package/experimental/terrain/Main.ff +40 -0
  15. package/experimental/terrain/Terrain.ff +97 -0
  16. package/experimental/terrain/Terrain2.ff +109 -0
  17. package/fireflysite/Main.ff +0 -1
  18. package/fireflysite/assets/markdown/reference/statements-and-expressions.md +1 -1
  19. package/lsp/CompletionHandler.ff +2 -2
  20. package/output/js/ff/compiler/Builder.mjs +24 -48
  21. package/output/js/ff/compiler/Builder.mjs.map +7 -11
  22. package/output/js/ff/compiler/Compiler.mjs +66 -12
  23. package/output/js/ff/compiler/Compiler.mjs.map +18 -14
  24. package/output/js/ff/compiler/Dependencies.mjs.map +2 -2
  25. package/output/js/ff/compiler/DependencyLock.mjs.map +1 -1
  26. package/output/js/ff/compiler/Deriver.mjs.map +1 -1
  27. package/output/js/ff/compiler/DevelopMode.mjs +1049 -0
  28. package/output/js/ff/compiler/DevelopMode.mjs.map +183 -0
  29. package/output/js/ff/compiler/Dictionaries.mjs.map +1 -1
  30. package/output/js/ff/compiler/Environment.mjs.map +1 -1
  31. package/output/js/ff/compiler/Inference.mjs.map +1 -1
  32. package/output/js/ff/compiler/JsEmitter.mjs.map +1 -1
  33. package/output/js/ff/compiler/JsImporter.mjs.map +1 -1
  34. package/output/js/ff/compiler/LspHook.mjs.map +1 -1
  35. package/output/js/ff/compiler/Main.mjs +256 -105
  36. package/output/js/ff/compiler/Main.mjs.map +43 -38
  37. package/output/js/ff/compiler/ModuleCache.mjs +12 -8
  38. package/output/js/ff/compiler/ModuleCache.mjs.map +4 -3
  39. package/output/js/ff/compiler/Parser.mjs.map +1 -1
  40. package/output/js/ff/compiler/Patterns.mjs.map +1 -1
  41. package/output/js/ff/compiler/Resolver.mjs.map +1 -1
  42. package/output/js/ff/compiler/SourceMap.mjs.map +1 -1
  43. package/output/js/ff/compiler/Substitution.mjs.map +1 -1
  44. package/output/js/ff/compiler/Syntax.mjs.map +1 -1
  45. package/output/js/ff/compiler/Token.mjs.map +1 -1
  46. package/output/js/ff/compiler/Tokenizer.mjs.map +1 -1
  47. package/output/js/ff/compiler/Unification.mjs.map +1 -1
  48. package/output/js/ff/compiler/Wildcards.mjs.map +1 -1
  49. package/output/js/ff/compiler/Workspace.mjs.map +1 -1
  50. package/output/js/ff/core/Any.mjs.map +1 -1
  51. package/output/js/ff/core/Array.mjs.map +1 -1
  52. package/output/js/ff/core/AssetSystem.mjs.map +1 -1
  53. package/output/js/ff/core/Atomic.mjs.map +1 -1
  54. package/output/js/ff/core/Bool.mjs.map +1 -1
  55. package/output/js/ff/core/BrowserSystem.mjs.map +1 -1
  56. package/output/js/ff/core/Buffer.mjs.map +1 -1
  57. package/output/js/ff/core/BuildSystem.mjs +116 -12
  58. package/output/js/ff/core/BuildSystem.mjs.map +35 -6
  59. package/output/js/ff/core/Channel.mjs.map +1 -1
  60. package/output/js/ff/core/Char.mjs.map +1 -1
  61. package/output/js/ff/core/Core.mjs.map +1 -1
  62. package/output/js/ff/core/Crypto.mjs.map +1 -1
  63. package/output/js/ff/core/Date.mjs.map +1 -1
  64. package/output/js/ff/core/Duration.mjs.map +1 -1
  65. package/output/js/ff/core/Equal.mjs.map +1 -1
  66. package/output/js/ff/core/Error.mjs.map +1 -1
  67. package/output/js/ff/core/FileHandle.mjs.map +1 -1
  68. package/output/js/ff/core/Float.mjs.map +1 -1
  69. package/output/js/ff/core/HttpClient.mjs.map +1 -1
  70. package/output/js/ff/core/Int.mjs.map +1 -1
  71. package/output/js/ff/core/IntMap.mjs.map +1 -1
  72. package/output/js/ff/core/Js.mjs.map +1 -1
  73. package/output/js/ff/core/JsSystem.mjs.map +1 -1
  74. package/output/js/ff/core/JsValue.mjs.map +1 -1
  75. package/output/js/ff/core/Json.mjs.map +1 -1
  76. package/output/js/ff/core/List.mjs.map +1 -1
  77. package/output/js/ff/core/Lock.mjs.map +1 -1
  78. package/output/js/ff/core/Log.mjs.map +1 -1
  79. package/output/js/ff/core/Map.mjs.map +1 -1
  80. package/output/js/ff/core/NodeSystem.mjs +54 -20
  81. package/output/js/ff/core/NodeSystem.mjs.map +14 -6
  82. package/output/js/ff/core/Nothing.mjs.map +1 -1
  83. package/output/js/ff/core/Option.mjs.map +1 -1
  84. package/output/js/ff/core/Ordering.mjs.map +1 -1
  85. package/output/js/ff/core/Pair.mjs.map +1 -1
  86. package/output/js/ff/core/Path.mjs +30 -4
  87. package/output/js/ff/core/Path.mjs.map +8 -6
  88. package/output/js/ff/core/Queue.mjs.map +1 -1
  89. package/output/js/ff/core/Random.mjs.map +1 -1
  90. package/output/js/ff/core/RbMap.mjs.map +1 -1
  91. package/output/js/ff/core/Serializable.mjs.map +1 -1
  92. package/output/js/ff/core/Set.mjs.map +1 -1
  93. package/output/js/ff/core/Show.mjs.map +1 -1
  94. package/output/js/ff/core/SourceLocation.mjs.map +1 -1
  95. package/output/js/ff/core/Stream.mjs.map +1 -1
  96. package/output/js/ff/core/String.mjs.map +1 -1
  97. package/output/js/ff/core/StringMap.mjs.map +1 -1
  98. package/output/js/ff/core/Task.mjs.map +1 -1
  99. package/output/js/ff/core/Try.mjs.map +1 -1
  100. package/output/js/ff/core/Unit.mjs.map +1 -1
  101. package/output/js/ff/core/node_modules +1 -0
  102. package/package.json +1 -1
  103. package/vscode/package.json +1 -1
  104. package/webserver/.firefly/include/package.json +1 -1
  105. package/webserver/WebServer.ff +6 -3
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": [
4
- "../../../../../compiler/ModuleCache.ff"
4
+ "../../../../compiler/ModuleCache.ff"
5
5
  ],
6
6
  "sourcesContent": [
7
- "import Syntax\r\n\r\nclass ModuleCache(\r\n version: Int\r\n mutable parsedModules: Map[String, Pair[Module, Int]]\r\n mutable resolvedModules: Map[String, Pair[Module, Int]]\r\n mutable derivedModules: Map[String, Pair[Module, Int]]\r\n mutable inferredModules: Map[String, Pair[Module, Int]]\r\n mutable emittedModules: Map[String, Int]\r\n)\r\n\r\nnew(version: Int): ModuleCache {\r\n ModuleCache(\r\n version = version\r\n parsedModules = Map.new()\r\n resolvedModules = Map.new()\r\n derivedModules = Map.new()\r\n inferredModules = Map.new()\r\n emittedModules = Map.new()\r\n )\r\n}\r\n\r\nextend self: ModuleCache {\r\n \r\n remove(keys: List[String]) {\r\n if(!keys.isEmpty()):\r\n self.parsedModules = self.parsedModules.removeList(keys)\r\n self.resolvedModules = self.resolvedModules.removeList(keys)\r\n self.derivedModules = self.derivedModules.removeList(keys)\r\n self.inferredModules = self.inferredModules.removeList(keys)\r\n self.emittedModules = self.emittedModules.removeList(keys)\r\n }\r\n \r\n invalidate(key: String) {\r\n //Log.trace(\"Invalidate: \" + uri)\r\n self.parsedModules.get(key).each: | Pair(module, _) =>\r\n self.remove([key])\r\n self.parsedModules.each {| k, Pair(m, _) =>\r\n if(m.imports.any {i => i.moduleKey == module.moduleKey}) {\r\n //Log.trace(\"Invalidating due to import of invalidated module: \" + m.packagePair.groupName() + \"/\" + m.file)\r\n self.remove([k])\r\n }\r\n }\r\n }\r\n \r\n filesNotImporting(moduleKey: ModuleKey): List[String] {\r\n self.parsedModules.toList().collect {| Pair(k, Pair(m, _)) =>\r\n if(!m.imports.any {i => i.moduleKey == moduleKey}): k\r\n }\r\n }\r\n \r\n without(newVersion: Int, path: Path): ModuleCache {\r\n let key = path.absolute()\r\n if(path.isFile()) {\r\n self.ModuleCache(\r\n version = newVersion\r\n parsedModules = self.parsedModules.remove(key)\r\n resolvedModules = self.resolvedModules.remove(key)\r\n derivedModules = self.derivedModules.remove(key)\r\n inferredModules = self.inferredModules.remove(key)\r\n emittedModules = self.emittedModules.remove(key)\r\n )\r\n } else {\r\n function invalidated(p: String): Bool {\r\n p.startsWith(key) && !p.contains(\".firefly/dependencies\") && !p.contains(\".firefly\\\\dependencies\")\r\n }\r\n self.ModuleCache(\r\n version = newVersion\r\n parsedModules = self.parsedModules.toList().filter {| Pair(p, _) => !invalidated(p)}.toMap()\r\n resolvedModules = self.resolvedModules.toList().filter {| Pair(p, _) => !invalidated(p)}.toMap()\r\n derivedModules = self.derivedModules.toList().filter {| Pair(p, _) => !invalidated(p)}.toMap()\r\n inferredModules = self.inferredModules.toList().filter {| Pair(p, _) => !invalidated(p)}.toMap()\r\n emittedModules = self.emittedModules.toList().filter {| Pair(p, _) => !invalidated(p)}.toMap()\r\n )\r\n }\r\n }\r\n \r\n mergeVersions(cache: ModuleCache): Unit {\r\n self.parsedModules = mergeVersionedMap(self.parsedModules, cache.parsedModules) {_.second}\r\n self.resolvedModules = mergeVersionedMap(self.resolvedModules, cache.resolvedModules) {_.second}\r\n self.derivedModules = mergeVersionedMap(self.derivedModules, cache.derivedModules) {_.second}\r\n self.inferredModules = mergeVersionedMap(self.inferredModules, cache.inferredModules) {_.second}\r\n self.emittedModules = mergeVersionedMap(self.emittedModules, cache.emittedModules) {_}\r\n }\r\n \r\n cacheParsedModule(\r\n packagePaths: Map[PackagePair, Path]\r\n moduleKey: ModuleKey\r\n body: Path => Module\r\n ): Module {\r\n let path = modulePath(packagePaths, moduleKey)\r\n self.parsedModules.get(path.absolute()).map {_.first}.else:\r\n let result = body(path)\r\n self.parsedModules = self.parsedModules.add(path.absolute(), Pair(result, self.version))\r\n result\r\n }\r\n \r\n cacheResolvedModule(\r\n packagePaths: Map[PackagePair, Path]\r\n moduleKey: ModuleKey\r\n body: Path => Module\r\n ): Module {\r\n let path = modulePath(packagePaths, moduleKey)\r\n self.resolvedModules.get(path.absolute()).map {_.first}.else:\r\n let result = body(path)\r\n self.resolvedModules = self.resolvedModules.add(path.absolute(), Pair(result, self.version))\r\n result\r\n }\r\n\r\n cacheDerivedModule(\r\n packagePaths: Map[PackagePair, Path]\r\n moduleKey: ModuleKey\r\n body: Path => Module\r\n ): Module {\r\n let path = modulePath(packagePaths, moduleKey)\r\n self.derivedModules.get(path.absolute()).map {_.first}.else:\r\n let result = body(path)\r\n self.derivedModules = self.derivedModules.add(path.absolute(), Pair(result, self.version))\r\n result\r\n }\r\n \r\n cacheInferredModule(\r\n packagePaths: Map[PackagePair, Path]\r\n moduleKey: ModuleKey\r\n body: Path => Module\r\n ): Module {\r\n let path = modulePath(packagePaths, moduleKey)\r\n self.inferredModules.get(path.absolute()).map {_.first}.else:\r\n let result = body(path)\r\n self.inferredModules = self.inferredModules.add(path.absolute(), Pair(result, self.version))\r\n result\r\n }\r\n \r\n cacheEmittedModule(\r\n packagePaths: Map[PackagePair, Path]\r\n moduleKey: ModuleKey\r\n isMainModule: Bool\r\n body: Path => Unit\r\n ): Unit {\r\n let path = modulePath(packagePaths, moduleKey)\r\n if(isMainModule || !self.emittedModules.contains(path.absolute())):\r\n self.emittedModules = self.emittedModules.add(path.absolute(), self.version)\r\n try {\r\n body(path)\r\n } catchAny {error =>\r\n self.emittedModules = self.emittedModules.remove(path.absolute())\r\n error.rethrow()\r\n }\r\n }\r\n \r\n}\r\n\r\nmergeVersionedMap[T](oldMap: Map[String, T], newMap: Map[String, T], getVersion: T => Int): Map[String, T] {\r\n mutable result = newMap\r\n oldMap.each {k, v =>\r\n if(!newMap.get(k).any {getVersion(_) >= getVersion(v)}) {\r\n result = result.add(k, v)\r\n }\r\n }\r\n result\r\n}\r\n\r\nmodulePath(\r\n packagePaths: Map[PackagePair, Path]\r\n moduleKey: ModuleKey\r\n): Path {\r\n let packagePath = packagePaths.get(moduleKey.packagePair).else {\r\n panic(\"Internal error - package path missing: \" + moduleKey.packagePair.groupName())\r\n }\r\n moduleKey.path(packagePath)\r\n}\r\n"
7
+ "import Syntax\r\n\r\nclass ModuleCache(\r\n version: Int\r\n mutable parsedModules: Map[String, Pair[Module, Int]]\r\n mutable resolvedModules: Map[String, Pair[Module, Int]]\r\n mutable derivedModules: Map[String, Pair[Module, Int]]\r\n mutable inferredModules: Map[String, Pair[Module, Int]]\r\n mutable emittedModules: Map[String, Int]\r\n)\r\n\r\nnew(version: Int): ModuleCache {\r\n ModuleCache(\r\n version = version\r\n parsedModules = Map.new()\r\n resolvedModules = Map.new()\r\n derivedModules = Map.new()\r\n inferredModules = Map.new()\r\n emittedModules = Map.new()\r\n )\r\n}\r\n\r\nextend self: ModuleCache {\r\n \r\n remove(keys: List[String], removeParsed: Bool = True) {\r\n if(!keys.isEmpty()):\r\n if(removeParsed) {\r\n self.parsedModules = self.parsedModules.removeList(keys)\r\n }\r\n self.resolvedModules = self.resolvedModules.removeList(keys)\r\n self.derivedModules = self.derivedModules.removeList(keys)\r\n self.inferredModules = self.inferredModules.removeList(keys)\r\n self.emittedModules = self.emittedModules.removeList(keys)\r\n }\r\n \r\n invalidate(key: String) {\r\n self.parsedModules.get(key).each: | Pair(module, _) =>\r\n self.remove([key])\r\n self.parsedModules.each {| k, Pair(m, _) =>\r\n if(m.imports.any {i => i.moduleKey == module.moduleKey}) {\r\n self.remove([k], removeParsed = False)\r\n }\r\n }\r\n }\r\n \r\n filesNotImporting(moduleKey: ModuleKey): List[String] {\r\n self.parsedModules.toList().collect {| Pair(k, Pair(m, _)) =>\r\n if(!m.imports.any {i => i.moduleKey == moduleKey}): k\r\n }\r\n }\r\n \r\n without(newVersion: Int, path: Path): ModuleCache {\r\n let key = path.absolute()\r\n if(path.isFile()) {\r\n self.ModuleCache(\r\n version = newVersion\r\n parsedModules = self.parsedModules.remove(key)\r\n resolvedModules = self.resolvedModules.remove(key)\r\n derivedModules = self.derivedModules.remove(key)\r\n inferredModules = self.inferredModules.remove(key)\r\n emittedModules = self.emittedModules.remove(key)\r\n )\r\n } else {\r\n function invalidated(p: String): Bool {\r\n p.startsWith(key) && !p.contains(\".firefly/dependencies\") && !p.contains(\".firefly\\\\dependencies\")\r\n }\r\n self.ModuleCache(\r\n version = newVersion\r\n parsedModules = self.parsedModules.toList().filter {| Pair(p, _) => !invalidated(p)}.toMap()\r\n resolvedModules = self.resolvedModules.toList().filter {| Pair(p, _) => !invalidated(p)}.toMap()\r\n derivedModules = self.derivedModules.toList().filter {| Pair(p, _) => !invalidated(p)}.toMap()\r\n inferredModules = self.inferredModules.toList().filter {| Pair(p, _) => !invalidated(p)}.toMap()\r\n emittedModules = self.emittedModules.toList().filter {| Pair(p, _) => !invalidated(p)}.toMap()\r\n )\r\n }\r\n }\r\n \r\n mergeVersions(cache: ModuleCache): Unit {\r\n self.parsedModules = mergeVersionedMap(self.parsedModules, cache.parsedModules) {_.second}\r\n self.resolvedModules = mergeVersionedMap(self.resolvedModules, cache.resolvedModules) {_.second}\r\n self.derivedModules = mergeVersionedMap(self.derivedModules, cache.derivedModules) {_.second}\r\n self.inferredModules = mergeVersionedMap(self.inferredModules, cache.inferredModules) {_.second}\r\n self.emittedModules = mergeVersionedMap(self.emittedModules, cache.emittedModules) {_}\r\n }\r\n \r\n cacheParsedModule(\r\n packagePaths: Map[PackagePair, Path]\r\n moduleKey: ModuleKey\r\n body: Path => Module\r\n ): Module {\r\n let path = modulePath(packagePaths, moduleKey)\r\n self.parsedModules.get(path.absolute()).map {_.first}.else:\r\n let result = body(path)\r\n self.parsedModules = self.parsedModules.add(path.absolute(), Pair(result, self.version))\r\n result\r\n }\r\n \r\n cacheResolvedModule(\r\n packagePaths: Map[PackagePair, Path]\r\n moduleKey: ModuleKey\r\n body: Path => Module\r\n ): Module {\r\n let path = modulePath(packagePaths, moduleKey)\r\n self.resolvedModules.get(path.absolute()).map {_.first}.else:\r\n let result = body(path)\r\n self.resolvedModules = self.resolvedModules.add(path.absolute(), Pair(result, self.version))\r\n result\r\n }\r\n\r\n cacheDerivedModule(\r\n packagePaths: Map[PackagePair, Path]\r\n moduleKey: ModuleKey\r\n body: Path => Module\r\n ): Module {\r\n let path = modulePath(packagePaths, moduleKey)\r\n self.derivedModules.get(path.absolute()).map {_.first}.else:\r\n let result = body(path)\r\n self.derivedModules = self.derivedModules.add(path.absolute(), Pair(result, self.version))\r\n result\r\n }\r\n \r\n cacheInferredModule(\r\n packagePaths: Map[PackagePair, Path]\r\n moduleKey: ModuleKey\r\n body: Path => Module\r\n ): Module {\r\n let path = modulePath(packagePaths, moduleKey)\r\n self.inferredModules.get(path.absolute()).map {_.first}.else:\r\n let result = body(path)\r\n self.inferredModules = self.inferredModules.add(path.absolute(), Pair(result, self.version))\r\n result\r\n }\r\n \r\n cacheEmittedModule(\r\n packagePaths: Map[PackagePair, Path]\r\n moduleKey: ModuleKey\r\n isMainModule: Bool\r\n body: Path => Unit\r\n ): Unit {\r\n let path = modulePath(packagePaths, moduleKey)\r\n if(isMainModule || !self.emittedModules.contains(path.absolute())):\r\n self.emittedModules = self.emittedModules.add(path.absolute(), self.version)\r\n try {\r\n body(path)\r\n } catchAny {error =>\r\n self.emittedModules = self.emittedModules.remove(path.absolute())\r\n error.rethrow()\r\n }\r\n }\r\n \r\n}\r\n\r\nmergeVersionedMap[T](oldMap: Map[String, T], newMap: Map[String, T], getVersion: T => Int): Map[String, T] {\r\n mutable result = newMap\r\n oldMap.each {k, v =>\r\n if(!newMap.get(k).any {getVersion(_) >= getVersion(v)}) {\r\n result = result.add(k, v)\r\n }\r\n }\r\n result\r\n}\r\n\r\nmodulePath(\r\n packagePaths: Map[PackagePair, Path]\r\n moduleKey: ModuleKey\r\n): Path {\r\n let packagePath = packagePaths.get(moduleKey.packagePair).else {\r\n panic(\"Internal error - package path missing: \" + moduleKey.packagePair.groupName())\r\n }\r\n moduleKey.path(packagePath)\r\n}\r\n"
8
8
  ],
9
9
  "names": [
10
10
  "ModuleCache",
@@ -39,6 +39,7 @@
39
39
  "remove",
40
40
  "self",
41
41
  "keys",
42
+ "removeParsed",
42
43
  "isEmpty",
43
44
  "removeList",
44
45
  "invalidate",
@@ -78,5 +79,5 @@
78
79
  "error",
79
80
  "rethrow"
80
81
  ],
81
- "mappings": "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"
82
+ "mappings": "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"
82
83
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": [
4
- "../../../../../compiler/Parser.ff"
4
+ "../../../../compiler/Parser.ff"
5
5
  ],
6
6
  "sourcesContent": [
7
7
  "import Token\r\nimport Wildcards\r\nimport Syntax\r\nimport LspHook\r\n\r\nclass Parser(\r\n moduleKey: ModuleKey\r\n tokens: List[Token]\r\n end: Token\r\n targetIsNode: Bool\r\n lspHook: LspHook\r\n mutable lspEmittedArgumentHook: Bool\r\n mutable offset: Int\r\n mutable nextUnificationVariableIndex: Int\r\n)\r\n\r\ndata Poly(generics: List[String], constraints: List[Constraint])\r\n\r\nnew(\r\n moduleKey: ModuleKey\r\n tokens: List[Token]\r\n targetIsNode: Bool\r\n lspHook: LspHook\r\n): Parser {\r\n Parser(\r\n moduleKey = moduleKey\r\n tokens = tokens\r\n end = tokens.grabLast()\r\n targetIsNode = targetIsNode\r\n lspHook = lspHook\r\n lspEmittedArgumentHook = False\r\n offset = 0\r\n nextUnificationVariableIndex = 1 // To avoid collision with the unification and resolver\r\n )\r\n}\r\n\r\nextend self: Parser {\r\n\r\n fail[T](at: Location, message: String): T {\r\n panic(message + \" \" + at.show())\r\n }\r\n\r\n behind(): Token {\r\n if(self.offset == 0) {self.current()} else {\r\n if(self.offset - 1 < self.tokens.size()) {self.tokens.grab(self.offset - 1)} else {self.end}\r\n }\r\n }\r\n\r\n current(): Token {\r\n if(self.offset < self.tokens.size()) {self.tokens.grab(self.offset)} else {self.end}\r\n }\r\n\r\n ahead(): Token {\r\n if(self.offset + 1 < self.tokens.size()) {self.tokens.grab(self.offset + 1)} else {self.end}\r\n }\r\n\r\n aheadAhead(): Token {\r\n if(self.offset + 2 < self.tokens.size()) {self.tokens.grab(self.offset + 2)} else {self.end}\r\n }\r\n\r\n skip(kind: TokenKind): Token {\r\n let c = self.current()\r\n if(c.kind != kind) {\r\n if(self.lspHook.isEnabled() && kind == LUpper && c.kind == LLower) {} else:\r\n throw(CompileError(c.at(), \"Expected \" + Show.show(kind) + \", got \" + c.raw()))\r\n }\r\n self.offset += 1\r\n c\r\n }\r\n\r\n rawSkip(kind: TokenKind, value: String): Token {\r\n let c = self.current()\r\n if(c.kind != kind) {\r\n if(self.lspHook.isEnabled() && (value == \")\" || value == \"]\" || value == \"}\")) {} else:\r\n throw(CompileError(c.at(), \"Expected \" + Show.show(kind) + \" \" + value + \", got \" + c.raw()))\r\n }\r\n if(!c.rawIs(value)) {\r\n if(self.lspHook.isEnabled() && (value == \")\" || value == \"]\" || value == \"}\")) {self.offset -= 1} else:\r\n throw(CompileError(c.at(), \"Expected \" + value + \" got \" + c.raw()))\r\n }\r\n self.offset += 1\r\n c\r\n }\r\n\r\n freshUnificationVariable(at: Location): Type {\r\n let result = TVariable(at, self.nextUnificationVariableIndex)\r\n self.nextUnificationVariableIndex += 3\r\n result\r\n }\r\n\r\n currentIsSeparator(kind: TokenKind): Bool {\r\n self.current().is(kind) || self.current().is(LSeparator)\r\n }\r\n\r\n skipSeparator(kind: TokenKind): Token {\r\n if(self.current().is(LSeparator)) {\r\n self.skip(LSeparator)\r\n } else {\r\n self.skip(kind)\r\n }\r\n }\r\n\r\n parseModuleWithoutPackageInfo(): Module {\r\n let moduleWithPackageInfo = self.parseModuleWithPackageInfo()\r\n moduleWithPackageInfo.packageInfo.each {info =>\r\n throw(CompileError(info.package.at, \"Package and dependencies already declared in package.ff\"))\r\n }\r\n moduleWithPackageInfo.module\r\n }\r\n\r\n parseModuleWithPackageInfo(): ModuleWithPackageInfo {\r\n let packageInfo = if(self.current().is(LKeyword) && self.current().rawIs3(\"package\", \"dependency\", \"include\")) {\r\n self.parsePackageInfo()\r\n }\r\n let module = self.parseModule()\r\n ModuleWithPackageInfo(packageInfo, module)\r\n }\r\n\r\n parsePackageInfo(): PackageInfo {\r\n let location = self.current().at()\r\n let package = if(self.current().is(LKeyword) && self.current().rawIs(\"package\")) {\r\n let p = self.parsePackageDefinition()\r\n if(!self.current().is(LEnd)) {self.skipSeparator(LSemicolon)}\r\n p\r\n } else {\r\n DPackage(\r\n location\r\n self.moduleKey.packagePair\r\n Version(location, 0, 0, 0)\r\n TargetNames(node = self.targetIsNode, browser = !self.targetIsNode)\r\n )\r\n }\r\n if(self.current().is(LKeyword) && self.current().rawIs(\"package\")) {\r\n throw(CompileError(self.current().at(), \"Duplicate package definition\"))\r\n }\r\n /* TODO: if(self.package != None && self.current().is(LKeyword) && self.current().rawIs(\"dependency\")) {\r\n self.fail(self.current().at(), \"Dependencies must be defined in the same file as the package declaration\")\r\n }*/\r\n let dependencies = Array.new[DDependency]()\r\n while {self.current().is(LKeyword) && self.current().rawIs(\"dependency\")} {\r\n dependencies.push(self.parseDependencyDefinition(package.targets))\r\n if(!self.current().is(LEnd)) {self.skipSeparator(LSemicolon)}\r\n }\r\n let includes = Array.new[DInclude]()\r\n while {self.current().is(LKeyword) && self.current().rawIs(\"include\")} {\r\n includes.push(self.parseIncludeDefinition())\r\n if(!self.current().is(LEnd)) {self.skipSeparator(LSemicolon)}\r\n }\r\n // TODO: When this method is called directly for package.ff, check that the whole file has been consumed\r\n PackageInfo(package, dependencies.toList(), includes.toList())\r\n }\r\n\r\n parseModule(): Module {\r\n let imports = Array.new[DImport]()\r\n let types = Array.new[DType]()\r\n let traits = Array.new[DTrait]()\r\n let instances = Array.new[DInstance]()\r\n let extends = Array.new[DExtend]()\r\n let lets = Array.new[DLet]()\r\n let functions = Array.new[DFunction]()\r\n while {!self.current().is(LEnd)} {\r\n if(self.current().is(LLower) && (self.ahead().is(LAssign) || self.ahead().is(LColon))) {\r\n lets.push(self.parseLetDefinition())\r\n } elseIf {self.current().is(LLower)} {\r\n functions.push(self.parseFunctionDefinition(member = False))\r\n } elseIf {self.current().is(LKeyword) && self.current().rawIs(\"extend\")} {\r\n extends.push(self.parseExtendDefinition())\r\n } elseIf {self.current().is(LKeyword) && self.current().rawIs(\"trait\")} {\r\n traits.push(self.parseTraitDefinition())\r\n } elseIf {self.current().is(LKeyword) && self.current().rawIs(\"instance\")} {\r\n instances.push(self.parseInstanceDefinition())\r\n } elseIf {self.current().is(LKeyword) && self.current().rawIs4(\"data\", \"class\", \"capability\", \"newtype\")} {\r\n types.push(self.parseTypeDefinition())\r\n } elseIf {self.current().is(LKeyword) && self.current().rawIs(\"import\")} {\r\n if(self.lspHook.isEnabled() && self.ahead().is(LLower) && !self.aheadAhead().is(LDot)) {\r\n self.skip(LKeyword)\r\n self.skip(LLower)\r\n } else {\r\n imports.push(self.parseImportDefinition(self.moduleKey.packagePair))\r\n }\r\n } elseIf {self.current().is(LKeyword) && self.current().rawIs(\"include\")} {\r\n throw(CompileError(self.current().at()\r\n \"Includes must be at the top of the file or below 'package'\"\r\n ))\r\n } elseIf {self.current().is(LKeyword) && self.current().rawIs(\"dependency\")} {\r\n throw(CompileError(self.current().at()\r\n \"Dependencies must be at the top of the file or below 'package'\"\r\n ))\r\n } elseIf {self.current().is(LKeyword) && self.current().rawIs(\"package\")} {\r\n throw(CompileError(self.current().at()\r\n \"Package definition must be at the top of the file\"\r\n ))\r\n } else {\r\n self.skip(LEnd)\r\n }\r\n if(!self.current().is(LEnd)) {self.skipSeparator(LSemicolon)}\r\n }\r\n\r\n Module(\r\n moduleKey = self.moduleKey\r\n imports = imports.toList()\r\n lets = lets.toList()\r\n functions = functions.toList()\r\n extends = extends.toList()\r\n types = types.toList()\r\n traits = traits.toList()\r\n instances = instances.toList()\r\n )\r\n }\r\n\r\n parseLetDefinition(): DLet {\r\n if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}\r\n let nameToken = self.skip(LLower)\r\n let variableType = if(self.current().is(LColon)) {\r\n self.skip(LColon)\r\n self.parseType()\r\n } else {self.freshUnificationVariable(nameToken.at())}\r\n self.skip(LAssign)\r\n let value = self.parseTerm()\r\n let retult = DLet(nameToken.at(), nameToken.raw(), variableType, value)\r\n if(self.lspHook.trackSymbols) {\r\n self.lspHook.emit(ParseSymbolEnd(\r\n name = nameToken.raw()\r\n kind = SLet(mutable = False)\r\n selectionStart = nameToken.at()\r\n selectionEnd = nameToken.end()\r\n start = nameToken.at()\r\n end = self.behind().end()\r\n ))\r\n }\r\n retult\r\n }\r\n\r\n parseFunctionDefinition(member: Bool): DFunction {\r\n if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}\r\n let signature = self.parseSignature(member)\r\n let body = self.parseLambda(signature.parameters.size())\r\n let result = DFunction(\r\n signature.at\r\n signature\r\n body\r\n )\r\n if(self.lspHook.trackSymbols) {\r\n self.lspHook.emit(ParseSymbolEnd(\r\n name = signature.name\r\n kind = SFunction(member)\r\n selectionStart = signature.at\r\n selectionEnd = signature.at.Location(column = signature.at.column + signature.name.size())\r\n start = signature.at\r\n end = self.behind().end()\r\n ))\r\n }\r\n result\r\n }\r\n\r\n parseSignature(member: Bool): Signature {\r\n let nameToken = self.skip(LLower)\r\n let poly = if(self.current().rawIs(\"[\")) {self.parseTypeParameters()} else {Poly([], [])}\r\n let parameters = if(self.lspHook.isEnabled() && !self.current().rawIs(\"(\")) {[]} else {self.parseFunctionParameters()}\r\n let returnType = if(self.current().is(LColon)) {\r\n self.skip(LColon)\r\n self.parseType()\r\n } else {\r\n TConstructor(self.current().at(), \"ff:core/Unit.Unit\", [])\r\n }\r\n let temporaryEffect = TConstructor(nameToken.at(), \"TemporaryEffect$\", [])\r\n Signature(nameToken.at(), nameToken.raw(), member, poly.generics, poly.constraints, parameters, returnType, temporaryEffect)\r\n }\r\n\r\n parseExtendDefinition(): DExtend {\r\n if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}\r\n let extendToken = self.rawSkip(LKeyword, \"extend\")\r\n let nameToken = self.skip(LLower)\r\n let poly = if(self.current().rawIs(\"[\")) {self.parseTypeParameters()} else {Poly([], [])}\r\n self.skip(LColon)\r\n let type = self.parseType()\r\n self.rawSkip(LBracketLeft, \"{\")\r\n let methods = Array.new[DFunction]()\r\n while {!self.current().is(LBracketRight)} {\r\n methods.push(self.parseFunctionDefinition(member = True))\r\n if(!self.current().is(LBracketRight)) {self.skipSeparator(LSemicolon)}\r\n }\r\n self.rawSkip(LBracketRight, \"}\")\r\n if(self.lspHook.trackSymbols) {\r\n mutable name = type.show([])\r\n poly.generics.zip(poly.constraints).each {| Pair(generic, constraint) => \r\n name = name.replace(\"[\" + generic + \"]\", \"[\" + generic + \": \" + constraint.name + \"]\")\r\n name = name.replace(\"[\" + generic + \",\", \"[\" + generic + \": \" + constraint.name + \",\")\r\n name = name.replace(\", \" + generic + \",\", \", \" + generic + \": \" + constraint.name + \",\")\r\n name = name.replace(\", \" + generic + \"]\", \", \" + generic + \": \" + constraint.name + \"]\")\r\n }\r\n self.lspHook.emit(ParseSymbolEnd(\r\n name = name\r\n kind = SExtend\r\n selectionStart = nameToken.at()\r\n selectionEnd = nameToken.end()\r\n start = extendToken.at()\r\n end = self.behind().end()\r\n ))\r\n } \r\n DExtend(\r\n nameToken.at()\r\n nameToken.raw()\r\n poly.generics\r\n poly.constraints\r\n type\r\n methods.toList()\r\n )\r\n }\r\n\r\n parseTraitDefinition(): DTrait {\r\n if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}\r\n let traitToken = self.rawSkip(LKeyword, \"trait\")\r\n let typeParameterToken = self.skip(LUpper)\r\n self.skip(LColon)\r\n let nameToken = self.skip(LUpper)\r\n let poly = if(!self.current().rawIs(\"[\")) {Poly([], [])} else {self.parseTypeParameters()}\r\n let constraints = Array.new[Constraint]()\r\n while {self.current().is(LColon)} {\r\n self.fail(self.current().at(), \"Trait constraints is not yet implemented\")\r\n self.skip(LColon)\r\n let constraint = self.parseConstraint()\r\n constraints.push(constraint.Constraint(generics =\r\n [TConstructor(typeParameterToken.at(), typeParameterToken.raw(), []), ...constraint.generics]\r\n ))\r\n }\r\n let generatorParameters = if(!self.current().rawIs(\"(\")) {[]} else {self.parseFunctionParameters()}\r\n let methodGenerators = Array.new[Pair[String, Lambda]]()\r\n let methodDefaults = Array.new[Pair[String, Lambda]]()\r\n let methodSignatures = if(!self.current().rawIs(\"{\")) {[]} else {\r\n let signatures = Array.new[Signature]()\r\n self.rawSkip(LBracketLeft, \"{\")\r\n while {!self.current().is(LBracketRight)} {\r\n if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}\r\n let signatureNameToken = self.current()\r\n let signature = self.parseSignature(member = True)\r\n if(self.lspHook.trackSymbols) {\r\n self.lspHook.emit(ParseSymbolEnd(\r\n name = signatureNameToken.raw() \r\n kind = STraitFunction\r\n selectionStart = signatureNameToken.at()\r\n selectionEnd = signatureNameToken.end()\r\n start = signatureNameToken.at()\r\n end = self.behind().end()\r\n ))\r\n } \r\n signatures.push(signature)\r\n if(self.current().rawIs(\"{\")) {\r\n let generator = self.ahead().is(LKeyword) && self.ahead().rawIs(\"generate\")\r\n let body = self.parseLambda(signature.parameters.size(), ignoreGenerateKeyword = True)\r\n if(generator) {\r\n methodGenerators.push(Pair(signature.name, body))\r\n } else {\r\n methodDefaults.push(Pair(signature.name, body))\r\n }\r\n }\r\n if(!self.current().is(LBracketRight)) {self.skipSeparator(LSemicolon)}\r\n }\r\n self.rawSkip(LBracketRight, \"}\")\r\n signatures.toList()\r\n }\r\n if(self.lspHook.trackSymbols) {\r\n self.lspHook.emit(ParseSymbolEnd(\r\n name = nameToken.raw() \r\n kind = STrait \r\n selectionStart = nameToken.at()\r\n selectionEnd = nameToken.end()\r\n start = traitToken.at()\r\n end = self.behind().end()\r\n ))\r\n } \r\n DTrait(\r\n nameToken.at()\r\n nameToken.raw()\r\n [typeParameterToken.raw(), ...poly.generics]\r\n [...constraints.toList(), ...poly.constraints]\r\n generatorParameters\r\n methodSignatures\r\n methodDefaults.toList()\r\n methodGenerators.toList()\r\n )\r\n }\r\n\r\n parseInstanceDefinition(): DInstance {\r\n if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}\r\n let instanceToken = self.rawSkip(LKeyword, \"instance\")\r\n let token = self.skip(LUpper)\r\n let poly = if(!self.current().rawIs(\"[\")) {Poly([], [])} else {self.parseTypeParameters()}\r\n let typeArguments = Array.new[Type]()\r\n typeArguments.push(TConstructor(token.at(), token.raw(), poly.generics.map {TConstructor(token.at(), _, [])}))\r\n self.skip(LColon)\r\n let nameToken = self.skip(LUpper)\r\n if(self.current().rawIs(\"[\")) {\r\n self.rawSkip(LBracketLeft, \"[\")\r\n while {!self.current().is(LBracketRight)} {\r\n typeArguments.push(self.parseType())\r\n if(!self.current().is(LBracketRight)) {self.skip(LComma)}\r\n }\r\n self.rawSkip(LBracketRight, \"]\")\r\n }\r\n let generatorArguments = self.parseFunctionArguments(nameToken.at(), False).first\r\n let methods = if(!self.current().rawIs(\"{\")) {[]} else {\r\n let definitions = Array.new[DFunction]()\r\n self.rawSkip(LBracketLeft, \"{\")\r\n while {!self.current().is(LBracketRight)} {\r\n definitions.push(self.parseFunctionDefinition(member = False))\r\n if(!self.current().is(LBracketRight)) {self.skipSeparator(LSemicolon)}\r\n }\r\n self.rawSkip(LBracketRight, \"}\")\r\n definitions.toList()\r\n }\r\n if(self.lspHook.trackSymbols) {\r\n let name = token.raw() + \": \" + nameToken.raw()\r\n self.lspHook.emit(ParseSymbolEnd(\r\n name = name\r\n kind = SInstance \r\n selectionStart = nameToken.at()\r\n selectionEnd = nameToken.end()\r\n start = instanceToken.at()\r\n end = self.behind().end()\r\n ))\r\n } \r\n DInstance(\r\n at = nameToken.at()\r\n generics = poly.generics\r\n constraints = poly.constraints\r\n traitName = nameToken.raw()\r\n typeArguments = typeArguments.toList()\r\n generatorArguments = generatorArguments\r\n methods = methods\r\n derived = False\r\n )\r\n }\r\n\r\n parseTypeDefinition(): DType {\r\n if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}\r\n let newtype = self.current().rawIs(\"newtype\")\r\n let effectParameter = if(self.current().rawIs(\"capability\")) {[\"Q$\"]} else {[]}\r\n let allowMutable = self.current().rawIs2(\"class\", \"capability\")\r\n let kindToken = if(self.current().rawIs(\"newtype\")) {\r\n self.rawSkip(LKeyword, \"newtype\")\r\n } elseIf {self.current().rawIs(\"data\")} {\r\n self.rawSkip(LKeyword, \"data\")\r\n } elseIf {self.current().rawIs(\"class\")} {\r\n self.rawSkip(LKeyword, \"class\")\r\n } else {\r\n self.rawSkip(LKeyword, \"capability\")\r\n }\r\n let nameToken = self.skip(LUpper)\r\n let poly = if(!self.current().rawIs(\"[\")) {Poly([], [])} else {self.parseTypeParameters()}\r\n if(!self.current().rawIs(\"(\") && !self.current().rawIs(\"{\")) {self.rawSkip(LBracketLeft, \"{\")}\r\n let commonFields = if(!self.current().rawIs(\"(\")) {[]} else {self.parseFunctionParameters(allowMutable = True)}\r\n let variants = if(newtype || !self.current().rawIs(\"{\")) {\r\n [Variant(nameToken.at(), nameToken.raw(), [])]\r\n } else {\r\n self.rawSkip(LBracketLeft, \"{\")\r\n let variantsBuilder = Array.new[Variant]()\r\n while {!self.current().is(LBracketRight)} {\r\n if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}\r\n let variantNameToken = self.skip(LUpper)\r\n let variantFields = if(!self.current().rawIs(\"(\")) {[]} else {self.parseFunctionParameters(allowMutable = True)}\r\n if(!allowMutable && variantFields.any {_.mutable}) {\r\n throw(CompileError(variantFields.find {_.mutable}.grab().at\r\n \"Only classes can have mutable fields\"\r\n ))\r\n }\r\n variantsBuilder.push(\r\n Variant(variantNameToken.at(), variantNameToken.raw(), variantFields)\r\n )\r\n if(!self.current().is(LBracketRight)) {self.skipSeparator(LSemicolon)}\r\n if(self.lspHook.trackSymbols) {\r\n self.lspHook.emit(ParseSymbolEnd(\r\n name = variantNameToken.raw()\r\n kind = SVariant\r\n selectionStart = variantNameToken.at()\r\n selectionEnd = variantNameToken.end()\r\n start = variantNameToken.at()\r\n end = self.behind().end()\r\n ))\r\n } \r\n }\r\n self.rawSkip(LBracketRight, \"}\")\r\n variantsBuilder.toList()\r\n }\r\n if(newtype && commonFields.size() != 1) {\r\n Log.show(commonFields)\r\n throw(CompileError(nameToken.at(), \"Newtypes must have exactly one field\"))\r\n }\r\n if(!allowMutable && commonFields.any {_.mutable}) {\r\n throw(CompileError(\r\n commonFields.find {_.mutable}.grab().at\r\n \"Only classes and capabilities can have mutable fields\"\r\n ))\r\n }\r\n let generics = [...effectParameter, ...poly.generics]\r\n let result = DType(nameToken.at(), newtype, !allowMutable, nameToken.raw(), generics, poly.constraints, commonFields, variants)\r\n if(self.lspHook.trackSymbols) {\r\n self.lspHook.emit(ParseSymbolEnd(\r\n name = nameToken.raw()\r\n kind = SType\r\n selectionStart = nameToken.at()\r\n selectionEnd = nameToken.end()\r\n start = kindToken.at()\r\n end = self.behind().end()\r\n ))\r\n } \r\n result\r\n }\r\n\r\n parseImportDefinition(currentPackagePair: PackagePair): DImport {\r\n let importToken = self.rawSkip(LKeyword, \"import\")\r\n let path = Array.new[String]()\r\n while {self.current().is(LLower)} {\r\n path.push(self.parseDashedName())\r\n self.skip(LDot)\r\n }\r\n let fileToken = self.skip(LUpper)\r\n let alias = if(self.current().rawIs(\"as\")) {\r\n self.rawSkip(LKeyword, \"as\")\r\n self.skip(LUpper).raw()\r\n } else {fileToken.raw()}\r\n let packagePair = if(self.current().rawIs(\"from\")) {\r\n self.rawSkip(LKeyword, \"from\")\r\n let userName = self.parseDashedName()\r\n self.skip(LColon)\r\n let packageName = self.parseDashedName()\r\n PackagePair(userName, packageName)\r\n } else {\r\n currentPackagePair\r\n }\r\n DImport(fileToken.at(), alias, ModuleKey(packagePair, path.toList(), fileToken.raw()))\r\n }\r\n\r\n parsePackageDefinition(): DPackage {\r\n let at = self.skip(LKeyword).at()\r\n let user = self.skip(LLower).raw()\r\n self.skip(LColon)\r\n let name = self.skip(LLower).raw()\r\n self.skip(LColon)\r\n let version = self.parseVersion()\r\n let targets = self.parseTargetNames(TargetNames(True, True))\r\n DPackage(\r\n at = at\r\n packagePair = PackagePair(user, name)\r\n version = version\r\n targets = targets\r\n )\r\n }\r\n\r\n parseDependencyDefinition(defaultTargetNames: TargetNames): DDependency {\r\n let at = self.skip(LKeyword).at()\r\n let user = self.skip(LLower).raw()\r\n self.skip(LColon)\r\n let name = self.skip(LLower).raw()\r\n self.skip(LColon)\r\n let version = self.parseVersion()\r\n let safety = (\r\n if(self.current().rawIs(\"trusted\")) {Trusted} else:\r\n if(self.current().rawIs(\"unsafe\")) {Unsafe} else:\r\n Safe\r\n )\r\n let targets = self.parseTargetNames(defaultTargetNames)\r\n DDependency(\r\n at = at\r\n packagePair = PackagePair(user, name)\r\n version = version\r\n safety = safety\r\n targets = targets\r\n )\r\n }\r\n\r\n parseIncludeDefinition(): DInclude {\r\n let at = self.skip(LKeyword).at()\r\n let path = self.skip(LString).raw()\r\n DInclude(\r\n at = at\r\n path = path.dropFirst().dropLast() // TODO: Fix string escaping\r\n )\r\n }\r\n\r\n parseTargetNames(defaultTargets: TargetNames): TargetNames {\r\n mutable targets = TargetNames(False, False)\r\n while {self.current().is2(LKeyword, LLower)} {\r\n let token = if(self.current().is(LLower)) {self.skip(LLower)} else {self.skip(LKeyword)}\r\n token.raw().{\r\n | \"node\" {targets.node} => throw(CompileError(token.at(), \"Duplicate target name\"))\r\n | \"node\" => targets = targets.TargetNames(node = True)\r\n | \"browser\" {targets.browser} => throw(CompileError(token.at(), \"Duplicate target name\"))\r\n | \"browser\" => targets = targets.TargetNames(browser = True)\r\n | t => throw(CompileError(token.at(), \"Unexpected target: \" + t))\r\n }\r\n }\r\n if(!targets.node && !targets.browser) {\r\n defaultTargets\r\n } else {\r\n targets\r\n }\r\n }\r\n\r\n parseVersion(): Version {\r\n if(self.current().is(LFloat)) {\r\n let majorMinor = self.skip(LFloat)\r\n let parts = majorMinor.raw().split('.')\r\n let patch = if(self.current().is(LDot)) {\r\n self.skip(LDot)\r\n self.skip(LInt).raw().grabInt()\r\n } else {0}\r\n Version(majorMinor.at(), parts.grab(0).grabInt(), parts.grab(1).grabInt(), patch)\r\n } else {\r\n let major = self.skip(LInt)\r\n Version(major.at(), major.raw().grabInt(), 0, 0)\r\n }\r\n }\r\n\r\n parseDashedName(): String {\r\n let at = self.current().at()\r\n function readPart(): String {\r\n if(self.current().is(LInt)) {\r\n let prefix = self.skip(LInt).raw()\r\n if(self.current().is(LLower)) {prefix + self.skip(LLower).raw()} else {prefix}\r\n } else {\r\n self.skip(LLower).raw()\r\n }\r\n }\r\n mutable part = readPart()\r\n while {self.current().rawIs(\"-\")} {\r\n self.skip(LOperator)\r\n part = part + \"-\" + readPart()\r\n }\r\n if(part.any {_.isAsciiUpper()}) {\r\n throw(CompileError(at, \"Package names and paths must not contain upper case letters: \" + part))\r\n }\r\n if(part.any {_ == '_'} || part.any {_ == '.'}) {\r\n throw(CompileError(at, \"Package names and paths must not contain underscores or dots: \" + part))\r\n }\r\n part\r\n }\r\n\r\n parseTypeParameters(): Poly {\r\n self.rawSkip(LBracketLeft, \"[\")\r\n let parameters = Array.new[String]()\r\n let constraints = Array.new[Constraint]()\r\n while {!self.current().is(LBracketRight) && !self.current().is(LSemicolon)} {\r\n if(self.ahead().is(LBracketLeft)) {\r\n constraints.push(self.parseConstraint())\r\n } else {\r\n let parameterNameToken = self.skip(LUpper)\r\n parameters.push(parameterNameToken.raw())\r\n while {self.current().is(LColon)} {\r\n self.skip(LColon)\r\n let constraint = self.parseConstraint()\r\n constraints.push(constraint.Constraint(generics =\r\n [TConstructor(parameterNameToken.at(), parameterNameToken.raw(), []), ...constraint.generics]\r\n ))\r\n }\r\n }\r\n if(!self.current().is(LBracketRight)) {self.skip(LComma)}\r\n }\r\n self.rawSkip(LBracketRight, \"]\")\r\n Poly(parameters.toList(), constraints.toList())\r\n }\r\n\r\n parseTypeArguments(parenthesis: Bool = False): List[Type] {\r\n self.rawSkip(LBracketLeft, if(parenthesis) {\"(\"} else {\"[\"})\r\n let types = Array.new[Type]()\r\n while {!self.current().is(LBracketRight)} {\r\n types.push(self.parseType())\r\n if(!self.current().is(LBracketRight)) {self.skip(LComma)}\r\n }\r\n self.rawSkip(LBracketRight, if(parenthesis) {\")\"} else {\"]\"})\r\n types.toList()\r\n }\r\n\r\n parseFunctionParameters(allowMutable: Bool = False): List[Parameter] {\r\n let parameters = Array.new[Parameter]()\r\n self.rawSkip(LBracketLeft, \"(\")\r\n while {!self.current().is(LBracketRight)} {\r\n let lspTrackSymbols = self.lspHook.trackSymbols && allowMutable\r\n if(lspTrackSymbols) {self.lspHook.emit(ParseSymbolBegin)}\r\n let lspFirst = self.current()\r\n let mutable = allowMutable && self.current().is(LKeyword) && self.current().rawIs(\"mutable\")\r\n if(mutable) {self.skip(LKeyword)}\r\n let parameterNameToken = self.skip(LLower)\r\n if(self.lspHook.isEnabled() && !self.current().is(LColon)) {\r\n let t = TConstructor(parameterNameToken.at(), \"ff:core/Nothing.Nothing\", [])\r\n parameters.push(Parameter(parameterNameToken.at(), mutable, parameterNameToken.raw(), t, None))\r\n if(!self.current().is(LBracketRight)) {self.skipSeparator(LComma)}\r\n } else:\r\n self.skip(LColon)\r\n let parameterType = self.parseType()\r\n let default = if(!self.current().is(LAssign)) {None} else {\r\n self.skip(LAssign)\r\n Some(self.parseTerm())\r\n }\r\n parameters.push(Parameter(parameterNameToken.at(), mutable, parameterNameToken.raw(), parameterType, default))\r\n if(lspTrackSymbols) {\r\n self.lspHook.emit(ParseSymbolEnd(\r\n name = parameterNameToken.raw()\r\n kind = SParameter\r\n selectionStart = parameterNameToken.at()\r\n selectionEnd = parameterNameToken.end()\r\n start = lspFirst.at()\r\n end = self.behind().end()\r\n ))\r\n } \r\n if(!self.current().is(LBracketRight)) {self.skipSeparator(LComma)}\r\n }\r\n self.rawSkip(LBracketRight, \")\")\r\n parameters.toList()\r\n }\r\n\r\n parseFunctionArguments(callAt: Location, trailing: Bool): Pair[List[Argument], Bool] {\r\n let arguments = Array.new[Argument]()\r\n if(self.current().rawIs(\"(\")){\r\n self.rawSkip(LBracketLeft, \"(\")\r\n while {!self.current().is(LBracketRight)} {\r\n let argumentToken = self.current()\r\n let nameToken = if(self.current().is(LLower) && self.ahead().is(LAssign)) {\r\n let token = self.skip(LLower)\r\n self.skip(LAssign)\r\n Some(token)\r\n } else {None}\r\n let value = self.parseTerm()\r\n if(self.lspHook.isEnabled() && !self.lspEmittedArgumentHook) {\r\n if(LspHook.strictlyBetween(callAt, self.current().at(), self.lspHook.at, 1)) {\r\n self.lspHook.emit(ParseArgumentHook(callAt, arguments.size(), nameToken.map {_.raw()}))\r\n self.lspEmittedArgumentHook = True\r\n }\r\n }\r\n arguments.push(Argument(argumentToken.at(), nameToken.map {_.raw()}, value))\r\n if(!self.current().is(LBracketRight)) {self.skipSeparator(LComma)}\r\n }\r\n if(self.lspHook.isEnabled() && !self.lspEmittedArgumentHook) {\r\n if(LspHook.strictlyBetween(callAt, self.current().at(), self.lspHook.at, 1)) {\r\n self.lspHook.emit(ParseArgumentHook(callAt, arguments.size(), None))\r\n self.lspEmittedArgumentHook = True\r\n }\r\n }\r\n self.rawSkip(LBracketRight, \")\")\r\n }\r\n mutable lastWasCurly = False\r\n if(trailing) {\r\n if(self.lspHook.isEnabled() &&\r\n (self.current().is3(LLower, LUpper, LString) || self.current().is3(LInt, LChar, LFloat))\r\n ) {\r\n lastWasCurly = True\r\n let term = self.parseTerm()\r\n let temporaryEffect = TConstructor(term.at, \"TemporaryEffect$\", [])\r\n let cases = [MatchCase(term.at, [], [], term)]\r\n if(self.lspHook.isEnabled() && !self.lspEmittedArgumentHook) {\r\n if(LspHook.strictlyBetween(callAt, self.current().at(), self.lspHook.at, 1)) {\r\n self.lspHook.emit(ParseArgumentHook(callAt, arguments.size(), None))\r\n self.lspEmittedArgumentHook = True\r\n }\r\n }\r\n arguments.push(Argument(term.at, None, ELambda(term.at, Lambda(term.at, temporaryEffect, cases))))\r\n } else {\r\n while {self.current().rawIs(\"{\") || self.current().is(LColon)} {\r\n lastWasCurly = self.current().rawIs(\"{\")\r\n let lambda = self.parseLambda(allowColon = True)\r\n if(self.lspHook.isEnabled() && !self.lspEmittedArgumentHook) {\r\n if(LspHook.strictlyBetween(callAt, self.current().at(), self.lspHook.at, 1)) {\r\n self.lspHook.emit(ParseArgumentHook(callAt, arguments.size(), None))\r\n self.lspEmittedArgumentHook = True\r\n }\r\n }\r\n arguments.push(Argument(lambda.at, None, ELambda(lambda.at, lambda)))\r\n }\r\n }\r\n }\r\n Pair(arguments.toList(), lastWasCurly)\r\n }\r\n\r\n parseLambda(\r\n defaultParameterCount: Int = 0\r\n ignoreGenerateKeyword: Bool = False\r\n allowColon: Bool = False\r\n ): Lambda {\r\n let colon = allowColon && self.current().is(LColon)\r\n let token = if(colon) {self.skip(LColon)} else {self.rawSkip(LBracketLeft, \"{\")}\r\n if(ignoreGenerateKeyword && self.current().is(LKeyword) && self.current().rawIs(\"generate\")) {self.skip(LKeyword)}\r\n let result = if(self.current().is(LPipe)) {\r\n let cases = Array.new[MatchCase]()\r\n while {self.current().is(LPipe)} {\r\n cases.push(self.parseCase())\r\n }\r\n cases.toList()\r\n } elseIf {self.current().is2(LLower, LWildcard) && self.ahead().is2(LComma, LArrowThick)} {\r\n let parameters = Array.new[MatchPattern]()\r\n while {!self.current().is(LArrowThick)} {\r\n let isVariable = self.current().is(LLower)\r\n let parameterToken = if(isVariable) {self.skip(LLower)} else {self.skip(LWildcard)}\r\n parameters.push(PVariable(parameterToken.at(), if(isVariable) {Some(parameterToken.raw())} else {None}))\r\n if(!self.current().is(LArrowThick)) {self.skip(LComma)}\r\n }\r\n self.skip(LArrowThick)\r\n let term = self.parseStatements()\r\n [MatchCase(token.at(), parameters.toList(), [], term)]\r\n } else {\r\n let term = self.parseStatements()\r\n let wildcards = Wildcards.new()\r\n let e = wildcards.fixWildcards(term)\r\n let arguments = if(wildcards.seenWildcards != 0) {\r\n List.range(wildcards.seenWildcards).map {i => PVariable(token.at(), Some(\"_w\" + (i + 1)))}\r\n } else {\r\n List.range(defaultParameterCount).map {i => PVariable(token.at(), None)}\r\n }\r\n [MatchCase(token.at(), arguments, [], e)]\r\n }\r\n if(!colon) {self.rawSkip(LBracketRight, \"}\")}\r\n let temporaryEffect = TConstructor(token.at(), \"TemporaryEffect$\", [])\r\n Lambda(token.at(), temporaryEffect, result)\r\n }\r\n\r\n parseCase(): MatchCase {\r\n let token = self.skip(LPipe)\r\n let patterns = Array.new[MatchPattern]()\r\n while {!self.current().is3(LArrowThick, LPipe, LBracketRight) && !self.current().rawIs(\"{\")} {\r\n patterns.push(self.parsePattern())\r\n if(!self.current().is3(LArrowThick, LPipe, LBracketRight) && !self.current().rawIs(\"{\")) {\r\n self.skip(LComma)\r\n }\r\n }\r\n let guards = Array.new[MatchGuard]()\r\n while {self.current().rawIs(\"{\")} {\r\n guards.push(self.parseCaseGuard())\r\n }\r\n if(!self.lspHook.isEnabled() || self.current().is(LArrowThick)) {\r\n self.skip(LArrowThick)\r\n }\r\n let body = self.parseStatements()\r\n MatchCase(token.at(), patterns.toList(), guards.toList(), body)\r\n }\r\n\r\n parseCaseGuard(): MatchGuard {\r\n let guardToken = self.skip(LBracketLeft)\r\n let term = self.parseStatements()\r\n let p = if(!self.current().is(LPipe)) {\r\n PVariant(guardToken.at(), \"True\", [])\r\n } else {\r\n self.skip(LPipe)\r\n self.parsePattern()\r\n }\r\n self.skip(LBracketRight)\r\n MatchGuard(guardToken.at(), term, p)\r\n }\r\n\r\n parsePattern(): MatchPattern {\r\n let pattern = if(self.current().is(LWildcard)) {\r\n let token = self.skip(LWildcard)\r\n PVariable(token.at(), None)\r\n } elseIf {self.current().is(LLower)} {\r\n let token = self.skip(LLower)\r\n PVariable(token.at(), Some(token.raw()))\r\n } elseIf {self.current().rawIs(\"(\")} {\r\n let at = self.current().at()\r\n let pair = self.parseRecordPattern().unzip()\r\n PVariant(at, \"Record$\" + pair.first.join(\"$\"), pair.second)\r\n } elseIf {self.current().rawIs(\"[\")} {\r\n self.parseListPattern()\r\n } elseIf {self.current().is(LString)} {\r\n let token = self.skip(LString)\r\n PString(token.at(), token.raw())\r\n } elseIf {self.current().is(LInt)} {\r\n let token = self.skip(LInt)\r\n PInt(token.at(), token.raw())\r\n } elseIf {self.current().is(LChar)} {\r\n let token = self.skip(LChar)\r\n PChar(token.at(), token.raw())\r\n } else {\r\n let token = self.skip(LUpper)\r\n if(self.current().rawIs(\"(\")) {\r\n let patterns = Array.new[MatchPattern]()\r\n self.rawSkip(LBracketLeft, \"(\")\r\n while {!self.current().is(LBracketRight)} {\r\n let pattern = self.parsePattern()\r\n if(self.lspHook.isEnabled() && !self.lspEmittedArgumentHook) {\r\n if(LspHook.strictlyBetween(token.at(), self.current().at(), self.lspHook.at, 1)) {\r\n self.lspHook.emit(ParseArgumentHook(token.at(), patterns.size(), None))\r\n self.lspEmittedArgumentHook = True\r\n }\r\n }\r\n patterns.push(pattern)\r\n if(!self.current().is(LBracketRight)) {self.skip(LComma)}\r\n }\r\n if(self.lspHook.isEnabled() && !self.lspEmittedArgumentHook) {\r\n if(LspHook.strictlyBetween(token.at(), self.current().at(), self.lspHook.at, 1)) {\r\n self.lspHook.emit(ParseArgumentHook(token.at(), patterns.size(), None))\r\n self.lspEmittedArgumentHook = True\r\n }\r\n }\r\n self.rawSkip(LBracketRight, \")\")\r\n PVariant(token.at(), token.raw(), patterns.toList())\r\n } else {\r\n if(self.current().is(LLower)) {\r\n let asToken = self.skip(LLower)\r\n PVariantAs(token.at(), token.raw(), asToken.at(), Some(asToken.raw()))\r\n } elseIf {self.current().is(LWildcard)} {\r\n let wildcardToken = self.skip(LWildcard)\r\n PVariantAs(token.at(), token.raw(), wildcardToken.at(), None)\r\n } else {\r\n PVariant(token.at(), token.raw(), [])\r\n }\r\n }\r\n }\r\n if(self.current().rawIs(\"@\")) {\r\n let atToken = self.skip(LOperator)\r\n let asToken = self.skip(LLower)\r\n PAlias(asToken.at(), pattern, asToken.raw())\r\n } else {pattern}\r\n }\r\n\r\n parseType(): Type {\r\n let leftTypes = if(self.current().rawIs(\"(\") && self.ahead().is(LLower) && self.aheadAhead().is(LColon)) {\r\n let at = self.current().at()\r\n let pair = self.parseRecordType().unzip()\r\n [TConstructor(at, \"Record$\" + pair.first.join(\"$\"), pair.second)]\r\n } elseIf {self.current().rawIs(\"(\")} {\r\n self.parseTypeArguments(parenthesis = True)\r\n } else {\r\n let namespace = if(self.current().is(LNamespace)) {self.skip(LNamespace).raw()} else {\"\"}\r\n let token = self.skip(LUpper)\r\n let arguments = if(!self.current().rawIs(\"[\")) {[]} else {self.parseTypeArguments()}\r\n [TConstructor(token.at(), namespace + token.raw(), arguments)]\r\n }\r\n if(!self.current().is(LArrowThick) && leftTypes.size() == 1) {leftTypes.grabFirst()} else {\r\n let arrowToken = self.skip(LArrowThick)\r\n let rightType = self.parseType()\r\n TConstructor(arrowToken.at(), \"Function$\" + leftTypes.size(), [...leftTypes, rightType])\r\n }\r\n }\r\n\r\n parseConstraint(): Constraint {\r\n let namespace = if(self.current().is(LNamespace)) {self.skip(LNamespace).raw()} else {\"\"}\r\n let token = self.skip(LUpper)\r\n let arguments = if(!self.current().rawIs(\"[\")) {[]} else {self.parseTypeArguments()}\r\n Constraint(token.at(), namespace + token.raw(), arguments)\r\n }\r\n\r\n parseStatements(): Term {\r\n if(self.current().is2(LBracketRight, LPipe)) {EVariant(self.current().at(), \"Unit\", [], None)} else {\r\n mutable result = self.parseStatement()\r\n while {self.currentIsSeparator(LSemicolon)} {\r\n let token = self.skipSeparator(LSemicolon)\r\n result = ESequential(token.at(), result, self.parseStatement())\r\n }\r\n result\r\n }\r\n }\r\n\r\n parseStatement(): Term {\r\n if(self.current().is(LKeyword) && (self.current().rawIs(\"let\") || self.current().rawIs(\"mutable\"))) {self.parseLet()} else:\r\n if(self.current().is(LKeyword) && self.current().rawIs(\"function\")) {self.parseFunctions()} else:\r\n let term = self.parseTerm()\r\n if(!self.current().is5(\r\n LAssign, LAssignPlus, LAssignMinus, LAssignMultiplication, LAssignDivision\r\n )) {term} else:\r\n let token = do {\r\n if(self.current().is(LAssignPlus)) {self.skip(LAssignPlus)} else:\r\n if(self.current().is(LAssignMinus)) {self.skip(LAssignMinus)} else:\r\n if(self.current().is(LAssignMultiplication)) {self.skip(LAssignMultiplication)} else:\r\n if(self.current().is(LAssignDivision)) {self.skip(LAssignDivision)} else:\r\n self.skip(LAssign)\r\n }\r\n let operator = token.raw().dropLast(1)\r\n let value = self.parseTerm()\r\n term.{\r\n | EVariable(at, name) => EAssign(at, operator, name, value)\r\n | EField e => EAssignField(e.at, operator, e.record, e.field, value)\r\n | _ => throw(CompileError(token.at(), \"Only variables and fields are assignable\"))\r\n }\r\n }\r\n\r\n parseLet(): Term {\r\n if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}\r\n let mutableToken = self.current()\r\n let mutable = mutableToken.rawIs(\"mutable\")\r\n let keywordToken = if(mutable) {self.rawSkip(LKeyword, \"mutable\")} else {self.rawSkip(LKeyword, \"let\")}\r\n let nameToken = self.skip(LLower)\r\n let valueType = if(!self.current().is(LColon)) {self.freshUnificationVariable(nameToken.at())} else {\r\n self.skip(LColon)\r\n self.parseType()\r\n }\r\n if(self.lspHook.isEnabled() && !self.current().is(LAssign)) {\r\n let unit = EVariant(keywordToken.at(), \"Unit\", [], None)\r\n ELet(nameToken.at(), mutable, nameToken.raw(), valueType, unit, unit)\r\n } else:\r\n self.skip(LAssign)\r\n let value = self.parseTerm()\r\n if(self.lspHook.trackSymbols) {\r\n self.lspHook.emit(ParseSymbolEnd(\r\n name = nameToken.raw()\r\n kind = SLet(mutable)\r\n selectionStart = nameToken.at()\r\n selectionEnd = nameToken.end()\r\n start = mutableToken.at()\r\n end = self.behind().end() \r\n ))\r\n }\r\n let body = if(self.currentIsSeparator(LSemicolon)) {\r\n self.skipSeparator(LSemicolon)\r\n self.parseStatements()\r\n } else {\r\n EVariant(keywordToken.at(), \"Unit\", [], None)\r\n }\r\n ELet(nameToken.at(), mutable, nameToken.raw(), valueType, value, body)\r\n }\r\n\r\n parseFunctions(): Term {\r\n let at = self.current().at()\r\n let functions = Array.new[DFunction]()\r\n while {self.current().rawIs(\"function\")} {\r\n if(self.lspHook.trackSymbols) {self.lspHook.emit(ParseSymbolBegin)}\r\n let functionAt = self.rawSkip(LKeyword, \"function\").at()\r\n let signature = self.parseSignature(member = False)\r\n let body = if(self.lspHook.isEnabled() && !self.current().rawIs(\"{\")) {\r\n let temporaryEffect = TConstructor(functionAt, \"TemporaryEffect$\", [])\r\n Lambda(functionAt, temporaryEffect, [])\r\n } else {\r\n self.parseLambda(defaultParameterCount = signature.parameters.size())\r\n }\r\n functions.push(DFunction(signature.at, signature, body))\r\n if(self.lspHook.trackSymbols) {\r\n self.lspHook.emit(ParseSymbolEnd(\r\n name = signature.name\r\n kind = SFunction(member = False)\r\n selectionStart = signature.at\r\n selectionEnd = signature.at.Location(column = signature.at.column + signature.name.size())\r\n start = functionAt\r\n end = self.behind().end() \r\n ))\r\n } \r\n if(self.lspHook.isEnabled() && !self.currentIsSeparator(LSemicolon)) {} else {self.skipSeparator(LSemicolon)}\r\n }\r\n let body = self.parseStatements()\r\n EFunctions(at, functions.toList(), body)\r\n }\r\n\r\n parseTerm(): Term {\r\n self.parseBinary(0)\r\n }\r\n\r\n parseBinary(level: Int): Term {\r\n if(level >= binaryOperators.size()) {\r\n if(self.lspHook.isEnabled() && self.current().is(LBracketRight)) {\r\n EVariable(self.current().at(), \"\")\r\n } else {\r\n self.parseUnary()\r\n }\r\n } else:\r\n let operators = binaryOperators.grab(level)\r\n mutable result = self.parseBinary(level + 1)\r\n if(self.current().is(LOperator)) {\r\n while {operators.any(self.current().rawIs)} {\r\n let token = self.skip(LOperator)\r\n let right = self.parseBinary(level + 1)\r\n let arguments = [Argument(result.at, None, result), Argument(right.at, None, right)]\r\n let effect = self.freshUnificationVariable(token.at())\r\n let target = token.raw().{\r\n | \"==\" => DynamicCall(EVariable(token.at(), \"ff:core/Equal.equals\"), False)\r\n | \"!=\" => DynamicCall(EVariable(token.at(), \"ff:core/Equal.notEquals\"), False)\r\n | \"<\" => DynamicCall(EVariable(token.at(), \"ff:core/Ordering.before\"), False)\r\n | \"<=\" => DynamicCall(EVariable(token.at(), \"ff:core/Ordering.notAfter\"), False)\r\n | \">\" => DynamicCall(EVariable(token.at(), \"ff:core/Ordering.after\"), False)\r\n | \">=\" => DynamicCall(EVariable(token.at(), \"ff:core/Ordering.notBefore\"), False)\r\n | \"===\" => DynamicCall(EVariable(token.at(), \"ff:core/JsValue.JsValue_equals\"), False)\r\n | \"!==\" => DynamicCall(EVariable(token.at(), \"ff:core/JsValue.JsValue_notEquals\"), False)\r\n | o => DynamicCall(EVariable(token.at(), o), False)\r\n }\r\n result = ECall(token.at(), target, effect, [], arguments, [])\r\n }\r\n }\r\n result\r\n }\r\n\r\n parseUnary(): Term {\r\n if(self.current().is2(LUnary, LOperator)) {\r\n let token = if(self.current().is(LUnary)) {self.skip(LUnary)} else {self.skip(LOperator)}\r\n let term = self.parseUnary()\r\n let effect = self.freshUnificationVariable(token.at())\r\n let target = DynamicCall(EVariable(token.at(), token.raw()), False)\r\n ECall(token.at(), target, effect, [], [Argument(term.at, None, term)], [])\r\n } else {\r\n self.parseFieldsAndCalls()\r\n }\r\n }\r\n\r\n parseFieldsAndCalls(): Term {\r\n let tailCall = if(self.current().is(LKeyword) && self.current().rawIs(\"tailcall\")) {\r\n self.skip(LKeyword)\r\n True\r\n } else {False}\r\n mutable result = self.parseAtom()\r\n while {self.current().is5(LBracketLeft, LColon, LDot, LArrowThin, LUnary)} {\r\n if(self.current().is(LDot)) {\r\n self.skip(LDot)\r\n if(self.current().rawIs(\"{\")) {\r\n let term = self.parseAtom()\r\n let effect = self.freshUnificationVariable(term.at)\r\n result = EPipe(term.at, result, effect, term)\r\n } elseIf {self.current().is2(LUpper, LNamespace)} {\r\n result = self.parseCopy(result)\r\n } else {\r\n let token = self.skip(LLower)\r\n result = EField(token.at(), False, result, token.raw())\r\n }\r\n } elseIf {self.current().is(LArrowThin)} {\r\n result = self.parseDynamicMember(result, False)\r\n } elseIf {self.current().is(LUnary)} {\r\n let token = self.skip(LUnary)\r\n let method = if(token.rawIs(\"!\")) {\"ff:core/Js.value\"} else {\"ff:core/Js.fromValue\"}\r\n let target = DynamicCall(EVariable(token.at(), method), False)\r\n let effect = self.freshUnificationVariable(token.at())\r\n result = ECall(token.at(), target, effect, [], [\r\n Argument(result.at, None, result)\r\n ], [])\r\n } else {\r\n let at = self.current().at()\r\n let typeArguments = if(!self.current().rawIs(\"[\")) {[]} else {self.parseTypeArguments()}\r\n let arguments = self.parseFunctionArguments(result.at, True)\r\n let effect = self.freshUnificationVariable(at)\r\n let target = DynamicCall(result, tailCall)\r\n result = ECall(result.at, target, effect, typeArguments, arguments.first, [])\r\n if(arguments.second && self.current().is(LLower)) {\r\n let token = self.skip(LLower)\r\n result = EField(token.at(), False, result, token.raw())\r\n }\r\n }\r\n }\r\n result\r\n }\r\n \r\n parseDynamicMember(record: Term, isModule: Bool): Term {\r\n function recordField(at: Location, name: String): Term {\r\n record.{\r\n | EVariant e {isModule} => EVariable(at, e.name + \".\" + name)\r\n | _ => EField(at, False, record, name)\r\n }\r\n }\r\n let token = self.skip(LArrowThin)\r\n if(self.current().rawIs(\"(\")) {\r\n let arguments = self.parseFunctionArguments(token.at(), trailing = False)\r\n let effect = self.freshUnificationVariable(record.at)\r\n arguments.first.indexWhere {!_.name.isEmpty()}.{\r\n | None =>\r\n let target = DynamicCall(recordField(token.at(), \"new\" + arguments.first.size()), False)\r\n ECall(record.at, target, effect, [], arguments.first, [])\r\n | Some(0) => \r\n let objectTarget = DynamicCall(recordField(token.at(), \"object\"), False)\r\n mutable result = ECall(record.at, objectTarget, effect, [], [], [])\r\n arguments.first.each {argument =>\r\n if(argument.name.isEmpty()) {\r\n throw(CompileError(argument.at, \"Expected a named argument\"))\r\n }\r\n let target = DynamicCall(EField(token.at(), False, result, \"with\"), False)\r\n result = ECall(record.at, target, effect, [], [\r\n Argument(argument.at, None, EString(argument.at, \"\\\"\" + argument.name.grab() + \"\\\"\"))\r\n Argument(argument.value.at, None, argument.value)\r\n ], [])\r\n }\r\n result\r\n | Some(i) => \r\n throw(CompileError(arguments.first.grab(i).at, \"Unexpected named argument\"))\r\n }\r\n } elseIf {self.current().rawIs(\"{\")} {\r\n let lambda = self.parseLambda()\r\n let effect = self.freshUnificationVariable(record.at)\r\n let arguments = lambda.cases.grabFirst().patterns.size()\r\n let target = DynamicCall(recordField(token.at(), \"function\" + arguments), False)\r\n ECall(record.at, target, effect, [], [\r\n Argument(lambda.at, None, ELambda(lambda.at, lambda))\r\n ], [])\r\n } else:\r\n let token = if(self.current().is(LLower)) {\r\n self.skip(LLower)\r\n } elseIf {self.current().is(LUpper)} {\r\n self.skip(LUpper)\r\n } else {\r\n self.skip(LString)\r\n }\r\n let member = EString(token.at(), if(token.is(LString)) {token.raw()} else {\"\\\"\" + token.raw() + \"\\\"\"})\r\n if(self.current().rawIs(\"(\")) {\r\n let arguments = self.parseFunctionArguments(record.at, False)\r\n arguments.first.find {!_.name.isEmpty()}.each {argument =>\r\n throw(CompileError(argument.at, \"Unexpected named argument\"))\r\n }\r\n let effect = self.freshUnificationVariable(record.at)\r\n let target = DynamicCall(recordField(token.at(), \"call\" + arguments.first.size()), False)\r\n ECall(record.at, target, effect, [], [\r\n Argument(member.at, None, member)\r\n ...arguments.first\r\n ], [])\r\n } elseIf {self.current().is5(LAssign, LAssignPlus, LAssignMinus, LAssignMultiplication, LAssignDivision)} {\r\n let method = \r\n if(self.current().is(LAssign)) {\r\n self.skip(LAssign)\r\n \"set\"\r\n } elseIf {self.current().is(LAssignPlus)} {\r\n self.skip(LAssignPlus)\r\n \"increment\"\r\n } elseIf {self.current().is(LAssignMinus)} {\r\n self.skip(LAssignMinus)\r\n \"decrement\"\r\n } elseIf {self.current().is(LAssignMultiplication)} {\r\n self.skip(LAssignMultiplication)\r\n \"multiply\"\r\n } else {\r\n self.skip(LAssignDivision)\r\n \"divide\"\r\n }\r\n let value = self.parseTerm()\r\n let effect = self.freshUnificationVariable(record.at)\r\n let target = DynamicCall(recordField(token.at(), method), False)\r\n ECall(record.at, target, effect, [], [\r\n Argument(member.at, None, member)\r\n Argument(value.at, None, value)\r\n ], [])\r\n } else {\r\n let effect = self.freshUnificationVariable(record.at)\r\n let target = DynamicCall(recordField(token.at(), \"get\"), False)\r\n ECall(record.at, target, effect, [], [\r\n Argument(member.at, None, member)\r\n ], [])\r\n }\r\n }\r\n\r\n parseAtom(): Term {\r\n if(self.current().is(LString)) {\r\n let token = self.skip(LString)\r\n EString(token.at(), token.raw())\r\n } elseIf {self.current().is(LChar)} {\r\n let token = self.skip(LChar)\r\n EChar(token.at(), token.raw())\r\n } elseIf {self.current().is(LInt)} {\r\n let token = self.skip(LInt)\r\n EInt(token.at(), token.raw())\r\n } elseIf {self.current().is(LFloat)} {\r\n let token = self.skip(LFloat)\r\n EFloat(token.at(), token.raw())\r\n } elseIf {self.current().is(LLower)} {\r\n let token = self.skip(LLower)\r\n EVariable(token.at(), token.raw())\r\n } elseIf {self.current().is(LNamespace)} {\r\n let namespaceToken = self.skip(LNamespace)\r\n let extraNamespace = if(!self.current().is(LNamespace)) {None} else {Some(self.skip(LNamespace).raw())}\r\n let prefix = namespaceToken.raw() + extraNamespace.else {\"\"}\r\n if(self.current().is(LLower)) {\r\n let token = self.skip(LLower)\r\n EVariable(token.at(), prefix + token.raw())\r\n } else {\r\n self.parseVariant(prefix)\r\n }\r\n } elseIf {self.current().is(LUpper) && self.ahead().is(LArrowThin)} {\r\n self.parseDynamicMember(self.parseVariant(\"\"), True)\r\n } elseIf {self.current().is(LUpper)} {\r\n self.parseVariant(\"\")\r\n } elseIf {self.current().rawIs(\"{\")} {\r\n let lambda = self.parseLambda()\r\n ELambda(lambda.at, lambda)\r\n } elseIf {self.current().rawIs(\"[\")} {\r\n self.parseList()\r\n } elseIf {self.current().rawIs(\"(\") && self.ahead().is(LLower) && self.aheadAhead().is(LAssign)} {\r\n ERecord(self.current().at(), self.parseRecord(None))\r\n } elseIf {self.current().rawIs(\"(\")} {\r\n self.rawSkip(LBracketLeft, \"(\")\r\n let result = self.parseTerm()\r\n while {self.lspHook.isEnabled() && self.currentIsSeparator(LComma)} {\r\n self.skipSeparator(LComma)\r\n if(!self.current().is(LBracketRight)) {self.parseTerm()}\r\n }\r\n self.rawSkip(LBracketRight, \")\")\r\n result\r\n } elseIf {self.current().is(LWildcard)} {\r\n let token = self.skip(LWildcard)\r\n EWildcard(token.at(), 0)\r\n } else {\r\n throw(CompileError(self.current().at(), \"Expected atom, got \" + self.current().raw()))\r\n }\r\n }\r\n\r\n parseVariant(prefix: String): Term {\r\n let token = self.skip(LUpper)\r\n let name = prefix + token.raw()\r\n let typeArguments = if(!self.current().rawIs(\"[\")) {[]} else {self.parseTypeArguments()}\r\n if(self.current().rawIs(\"?\")) {self.skip(LOperator); EVariantIs(token.at(), name, typeArguments)} else:\r\n let arguments = Some(self.parseFunctionArguments(token.at(), True))\r\n EVariant(token.at(), name, typeArguments, arguments.map {_.first})\r\n }\r\n\r\n parseCopy(record: Term): Term {\r\n let namespace = if(!self.current().is(LNamespace)) {\"\"} else {self.skip(LNamespace).raw()}\r\n let extraNamespace = if(!self.current().is(LNamespace)) {\"\"} else {self.skip(LNamespace).raw()}\r\n let prefix = namespace + extraNamespace\r\n let token = self.skip(LUpper)\r\n let name = prefix + token.raw()\r\n let fields = if(self.lspHook.isEnabled() && !self.current().rawIs(\"(\")) {[]} else {self.parseRecord(Some(token.at()))}\r\n ECopy(token.at(), name, record, fields)\r\n }\r\n\r\n parseRecord(copyAt: Option[Location]): List[Field] {\r\n let fields = Array.new[Field]()\r\n let startBracketAt = self.rawSkip(LBracketLeft, \"(\").at()\r\n let startAt = copyAt.else {startBracketAt}\r\n while {!self.current().is(LBracketRight)} {\r\n let fieldToken = self.skip(LLower)\r\n let field = if(!self.lspHook.isEnabled() || self.current().is(LAssign)) {\r\n self.skip(LAssign)\r\n Field(fieldToken.at(), fieldToken.raw(), self.parseTerm())\r\n } else {\r\n Field(fieldToken.at(), fieldToken.raw(), EVariable(fieldToken.at(), fieldToken.raw()))\r\n }\r\n if(self.lspHook.isEnabled() && !self.lspEmittedArgumentHook) {\r\n if(LspHook.strictlyBetween(startAt, self.current().at(), self.lspHook.at, 1)) {\r\n self.lspHook.emit(ParseArgumentHook(startAt, fields.size(), Some(field.name).filter {_ != \"\"}))\r\n self.lspEmittedArgumentHook = True\r\n }\r\n }\r\n fields.push(field)\r\n if(!self.current().is(LBracketRight)) {self.skipSeparator(LComma)}\r\n }\r\n if(self.lspHook.isEnabled() && !self.lspEmittedArgumentHook) {\r\n if(LspHook.strictlyBetween(startAt, self.current().at(), self.lspHook.at, 1)) {\r\n self.lspHook.emit(ParseArgumentHook(startAt, fields.size(), None))\r\n self.lspEmittedArgumentHook = True\r\n }\r\n }\r\n self.rawSkip(LBracketRight, \")\")\r\n fields.toList()\r\n }\r\n\r\n parseRecordType(): List[Pair[String, Type]] {\r\n let fields = Array.new[Pair[String, Type]]()\r\n self.rawSkip(LBracketLeft, \"(\")\r\n while {!self.current().is(LBracketRight)} {\r\n let fieldToken = self.skip(LLower)\r\n self.skipSeparator(LColon)\r\n fields.push(Pair(fieldToken.raw(), self.parseType()))\r\n if(!self.current().is(LBracketRight)) {self.skipSeparator(LComma)}\r\n }\r\n self.rawSkip(LBracketRight, \")\")\r\n fields.toList().sortBy {_.first}\r\n }\r\n\r\n parseRecordPattern(): List[Pair[String, MatchPattern]] {\r\n let fields = Array.new[Pair[String, MatchPattern]]()\r\n self.rawSkip(LBracketLeft, \"(\")\r\n while {!self.current().is(LBracketRight)} {\r\n let fieldToken = self.skip(LLower)\r\n self.skip(LAssign)\r\n fields.push(Pair(fieldToken.raw(), self.parsePattern()))\r\n if(!self.current().is(LBracketRight)) {self.skipSeparator(LComma)}\r\n }\r\n self.rawSkip(LBracketRight, \")\")\r\n fields.toList().sortBy {_.first}\r\n }\r\n\r\n parseListPattern(): MatchPattern {\r\n function convertListPattern(at: Location, items: List[Pair[MatchPattern, Bool]]): MatchPattern {\r\n | _, [] => PVariant(at, \"List$Empty\", [])\r\n | _, [Pair(p, False), ...ps] =>\r\n PVariant(at, \"List$Link\", [p, convertListPattern(at, ps)])\r\n | _, [Pair(p, True)] => p\r\n | _, [Pair(p, True), ...] =>\r\n throw(CompileError(p.at, \"Invalid pattern: ... is only allowed for the last element in a list\"))\r\n }\r\n let items = Array.new[Pair[MatchPattern, Bool]]()\r\n let at = self.rawSkip(LBracketLeft, \"[\").at()\r\n while {!self.current().rawIs(\"]\")} {\r\n let spread = self.current().is(LDotDotDot)\r\n if(spread) {self.skip(LDotDotDot)}\r\n let pattern = if(spread && self.current().rawIs(\"]\")) {\r\n PVariable(self.current().at(), None)\r\n } else {\r\n self.parsePattern()\r\n }\r\n items.push(Pair(pattern, spread))\r\n if(!self.current().rawIs(\"]\")) {self.skipSeparator(LComma)}\r\n }\r\n self.rawSkip(LBracketRight, \"]\")\r\n convertListPattern(at, items.toList())\r\n }\r\n\r\n parseList(): Term {\r\n let items = Array.new[Pair[Term, Bool]]()\r\n let at = self.rawSkip(LBracketLeft, \"[\").at()\r\n while {!self.current().rawIs(\"]\")} {\r\n let spread = self.current().is(LDotDotDot)\r\n if(spread) {self.skip(LDotDotDot)}\r\n items.push(Pair(self.parseTerm(), spread))\r\n if(!self.current().rawIs(\"]\")) {self.skipSeparator(LComma)}\r\n }\r\n self.rawSkip(LBracketRight, \"]\")\r\n EList(at, self.freshUnificationVariable(at), items.toList())\r\n }\r\n\r\n}\r\n\r\nbinaryOperators = [\r\n [\"||\"]\r\n [\"&&\"]\r\n [\"!=\", \"==\", \"!==\", \"===\"]\r\n [\"<=\", \">=\", \"<\", \">\"]\r\n [\"+\", \"-\"]\r\n [\"*\", \"/\", \"%\"]\r\n [\"^\"]\r\n]\r\n"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": [
4
- "../../../../../compiler/Patterns.ff"
4
+ "../../../../compiler/Patterns.ff"
5
5
  ],
6
6
  "sourcesContent": [
7
7
  "import Syntax\r\n\r\ndata PatternInfo(\r\n variant: String\r\n otherVariants: Set[String]\r\n fields: List[Pair[String, PatternInfo]]\r\n)\r\n\r\ndata PatternCaseInfo(\r\n fields: List[Pair[String, PatternInfo]]\r\n guard: Bool\r\n)\r\n\r\ncheck(\r\n variants: Map[String, Set[String]]\r\n fields: List[Pair[String, PatternInfo]]\r\n cases: List[PatternCaseInfo]\r\n success: Bool\r\n guard: Bool\r\n): Unit {\r\n Pair(fields, cases).{\r\n | Pair([Pair(f, PatternInfo p), ...fs], cs) =>\r\n let vs = variants.get(f).else {p.otherVariants.add(p.variant)}\r\n if(vs.contains(p.variant)) {\r\n let newFields = p.fields.map {_.mapFirst {f + \".\" + p.variant + \"_\" + _}}\r\n if(vs.size() == 1) {\r\n check(variants.add(f, vs), [...newFields, ...fs], cs, True, guard)\r\n } else {\r\n check(variants.add(f, [p.variant].toSet()), [...newFields, ...fs], cs, True, guard)\r\n check(variants.add(f, vs.remove(p.variant)), [], cs, False, guard)\r\n }\r\n } else {\r\n check(variants, [], cs, False, guard)\r\n }\r\n | _ {success && !guard} =>\r\n | Pair([], [PatternCaseInfo(fs, g), ...cs]) =>\r\n check(variants, fs, cs, True, g)\r\n | Pair([], []) =>\r\n let remaining = variants.pairs().filter {_.second.size() != 0}.map {| Pair(f, vs) =>\r\n f + \" could be \" + Show.show(vs.toList())\r\n }\r\n if(remaining.size() != 0) {\r\n panic(\"Unexhaustive match:\\n\" + remaining.join(\"\\n\"))\r\n }\r\n }\r\n}\r\n\r\nconvert(modules: Map[String, Module], cases: List[MatchCase]): List[PatternCaseInfo] {\r\n function unqualifiedName(name: String): String {\r\n name.reverse().takeWhile {_ != '.'}.reverse()\r\n }\r\n function otherVariants(name: String): Set[String] {\r\n if(name == \"List$Empty\") {[\"List$Link\"].toSet()} else:\r\n if(name == \"List$Link\") {[\"List$Empty\"].toSet()} else:\r\n let variantName = unqualifiedName(name)\r\n let moduleName = name.dropLast(variantName.size() + 1)\r\n let variantModule = modules.grab(moduleName)\r\n variantModule.types.collectFirst {definition =>\r\n definition.variants.find {_.name == variantName}.map {variant =>\r\n definition.variants.map {_.name}.filter {_ != variantName}.toSet()\r\n }\r\n }.grab()\r\n }\r\n function convertPattern(pattern: MatchPattern): Option[PatternInfo] {\r\n | PString _ =>\r\n Some(PatternInfo(\"String literal\", [\"Any other String literal\"].toSet(), []))\r\n | PInt _ =>\r\n Some(PatternInfo(\"Int literal\", [\"Any other Int literal\"].toSet(), []))\r\n | PChar _ =>\r\n Some(PatternInfo(\"Char literal\", [\"Any other Char literal\"].toSet(), []))\r\n | PVariable p =>\r\n None\r\n | PVariant p =>\r\n let fields = p.patterns.map(convertPattern).pairs().collect {\r\n | Pair(i, Some(info)) => Some(Pair(\"\" + i, info))\r\n | _ => None\r\n }\r\n Some(PatternInfo(unqualifiedName(p.name), otherVariants(p.name), fields))\r\n | PVariantAs p =>\r\n Some(PatternInfo(unqualifiedName(p.name), otherVariants(p.name), []))\r\n | PAlias p =>\r\n convertPattern(p.pattern)\r\n }\r\n cases.pairs().map {| Pair(caseIndex, case) =>\r\n let fields = case.patterns.map(convertPattern).pairs().collect {\r\n | Pair(i, Some(p)) => Some(Pair(\"\" + i, p))\r\n | _ => None\r\n }\r\n let exhaustiveGuards = case.guards.all {g =>\r\n let guardConverted = convert(modules, [MatchCase(g.at, [g.pattern], [], case.body)])\r\n try {\r\n check([].toMap(), [], guardConverted, False, False)\r\n True\r\n } else {\r\n False\r\n }\r\n }\r\n PatternCaseInfo(fields, !exhaustiveGuards)\r\n }\r\n}\r\n\r\nconvertAndCheck(modules: Map[String, Module], cases: List[MatchCase]): Unit {\r\n let converted = convert(modules, cases)\r\n try {\r\n check([].toMap(), [], converted, False, False)\r\n } else {\r\n throw(CompileError(cases.grab(0).at, \"Unexhaustive match\"))\r\n }\r\n}\r\n\r\nfail[T](at: Location, message: String): T {\r\n panic(message + \" \" + at.show())\r\n}\r\n"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": [
4
- "../../../../../compiler/Resolver.ff"
4
+ "../../../../compiler/Resolver.ff"
5
5
  ],
6
6
  "sourcesContent": [
7
7
  "import Syntax\r\nimport LspHook\r\n\r\nclass Resolver(\r\n variables: Map[String, String]\r\n variableLocations: Map[String, Location]\r\n variants: Map[String, String]\r\n types: Map[String, String]\r\n typeGenerics: Map[String, List[String]]\r\n typeLocations: Map[String, Location]\r\n asyncTypes: Set[String]\r\n typeParameters: Set[String]\r\n traits: Map[String, String]\r\n traitLocations: Map[String, Location]\r\n state: ResolverState\r\n lspHook: LspHook\r\n)\r\n\r\nclass ResolverState(\r\n mutable nextUnificationVariableIndex: Int\r\n)\r\n\r\ndata CaseVariable(\r\n at: Location\r\n name: String\r\n asBound: Option[String]\r\n)\r\n\r\nnew(lspHook: LspHook): Resolver {\r\n Resolver(\r\n variables = [].toMap()\r\n variableLocations = [].toMap()\r\n variants = [].toMap()\r\n types = [].toMap()\r\n typeGenerics = [].toMap()\r\n typeLocations = [].toMap()\r\n asyncTypes = [].toSet()\r\n typeParameters = [].toSet()\r\n traits = [].toMap()\r\n traitLocations = [].toMap()\r\n state = ResolverState(\r\n nextUnificationVariableIndex = 2\r\n ) // To avoid collision with the parser and unification\r\n lspHook = lspHook\r\n )\r\n}\r\n\r\nextend self: Resolver {\r\n\r\n freshUnificationVariable(at: Location): Type {\r\n let result = TVariable(at, self.state.nextUnificationVariableIndex)\r\n self.state.nextUnificationVariableIndex += 3\r\n result\r\n }\r\n\r\n resolveModule(module: Module, otherModules: List[Module]): Module {\r\n let self2 = self.processImports(module.imports, otherModules)\r\n let self3 = self2.processDefinitions(module, None)\r\n \r\n let errors = Array.new()\r\n let module2 = module.Module(\r\n types = Syntax.catchManyInto(errors, module.types) {self3.resolveTypeDefinition(_)}\r\n traits = Syntax.catchManyInto(errors, module.traits) {self3.resolveTraitDefinition(_)}\r\n instances = Syntax.catchManyInto(errors, module.instances) {self3.resolveInstanceDefinition(_)}\r\n extends = Syntax.catchManyInto(errors, module.extends) {self3.resolveExtendDefinition(_)}\r\n lets = Syntax.catchManyInto(errors, module.lets) {self3.resolveLetDefinition(_, True)}\r\n functions = Syntax.catchManyInto(errors, module.functions) {\r\n self3.resolveFunctionDefinition(_, True, False)\r\n }\r\n )\r\n errors.drain().{\r\n | [] =>\r\n | [Pair(_, error)] => error.rethrow()\r\n | allErrors => throw(CompileErrors(allErrors.map {_.first}))\r\n } \r\n checkDuplicates(module2.types) {_.name} {_.at}\r\n checkDuplicates(module2.traits) {_.name} {_.at}\r\n checkDuplicates(module2.lets) {_.name} {_.at}\r\n checkDuplicates(module2.functions) {_.signature.name} {_.at}\r\n let groupedExtendMethods = module2.extends.map {x => \r\n Pair(x.type.show([]).takeWhile {_.isAsciiLetterOrDigit()}, x.methods)\r\n }.group()\r\n groupedExtendMethods.values().map {_.flatten()}.map {methods =>\r\n checkDuplicates(methods) {_.signature.name} {_.at}\r\n }\r\n module2.instances.each {_.typeArguments.each {self3.checkInstanceType(_)}}\r\n module2\r\n }\r\n \r\n checkInstanceType(type: Type) {\r\n type.{\r\n | TConstructor(_, name, typeArguments) =>\r\n if(self.asyncTypes.contains(name)) {\r\n throw(CompileError(type.at, \"Traits must not be instantiated for capability types\"))\r\n }\r\n typeArguments.each {self.checkInstanceType(_)}\r\n | _ =>\r\n }\r\n }\r\n\r\n processImports(imports: List[DImport], modules: List[Module]): Resolver {\r\n mutable resolver = self\r\n imports.each {import =>\r\n modules.find {_.moduleKey == import.moduleKey}.{\r\n | Some(module) =>\r\n resolver = resolver.processDefinitions(module, Some(import.alias))\r\n | None =>\r\n throw(CompileError(import.at, \"No such module: \" + import.moduleKey.importName()))\r\n }\r\n }\r\n resolver\r\n }\r\n\r\n processDefinitions(module: Module, importAlias: Option[String]): Resolver {\r\n function entry(name: String, unqualified: Bool): List[Pair[String, String]] {\r\n let full = module.moduleKey.qualifiedSymbol(name)\r\n importAlias.{\r\n | None => [Pair(name, full), Pair(full, full)]\r\n | Some(alias) {unqualified} => [Pair(alias + \".\" + name, full), Pair(name, full), Pair(full, full)]\r\n | Some(alias) => [Pair(alias + \".\" + name, full), Pair(full, full)]\r\n }\r\n }\r\n let isCore = // TODO: Extend imports to list unqualified symbols instead of this\r\n module.moduleKey.packagePair.group == \"ff\" &&\r\n module.moduleKey.packagePair.name == \"core\" &&\r\n module.moduleKey.folders == [] &&\r\n module.moduleKey.name == \"Core\"\r\n let lets = module.lets.flatMap {entry(_.name, isCore)}.toMap()\r\n let letLocations = module.lets.flatMap {d => entry(d.name, True).map {_.mapSecond {_ => d.at}}}.toMap()\r\n let functions = module.functions.flatMap {entry(_.signature.name, isCore)}.toMap()\r\n let functionLocations = module.functions.flatMap {d => entry(d.signature.name, True).map {_.mapSecond {_ => d.at}} }.toMap()\r\n let traitMethods = module.traits.flatMap {_.methods }.flatMap {entry(_.name, False)}.toMap()\r\n let traitMethodLocations = module.traits.flatMap {_.methods}.flatMap {d => entry(d.name, True).map {_.mapSecond {_ => d.at}}}.toMap()\r\n let traits = module.traits.flatMap {entry(_.name, True) }.toMap()\r\n let traitLocations = module.traits.flatMap {d => entry(d.name, True).map {_.mapSecond {_ => d.at}}}.toMap()\r\n let types = module.types.flatMap {entry(_.name, True) }.toMap()\r\n let typeGenerics = module.types.flatMap {d => entry(d.name, True).map {p => Pair(p.first, d.generics)}}.toMap()\r\n let typeLocations = module.types.flatMap {d => entry(d.name, True).map {_.mapSecond {_ => d.at}}}.toMap()\r\n let asyncTypes = module.types.filter {_.generics.first().any {_ == \"Q$\"}}\r\n .flatMap {entry(_.name, True).map {_.first}}.toSet()\r\n let variants = module.types.flatMap {_.variants }.flatMap {entry(_.name, True)}.toMap()\r\n self.Resolver(\r\n variables = self.variables.addAll(lets).addAll(functions).addAll(traitMethods)\r\n variableLocations = self.variableLocations.addAll(letLocations).addAll(functionLocations).addAll(traitMethodLocations)\r\n variants = self.variants.addAll(variants)\r\n types = self.types.addAll(types)\r\n typeGenerics = self.typeGenerics.addAll(typeGenerics)\r\n typeLocations = self.typeLocations.addAll(typeLocations)\r\n asyncTypes = self.asyncTypes.addAll(asyncTypes)\r\n typeParameters = [].toSet()\r\n traits = self.traits.addAll(traits)\r\n traitLocations = self.traitLocations.addAll(traitLocations)\r\n state = self.state\r\n )\r\n }\r\n\r\n resolveTypeDefinition(definition: DType): DType {\r\n if(self.lspHook.isAt(definition.at)) {\r\n self.lspHook.emit(\r\n ResolveSymbolHook(SymbolHook(definition.name, definition.at, definition.at), None, topLevel = True)\r\n )\r\n }\r\n let generics = definition.generics.map {g => Pair(g, g)}.toMap()\r\n let self2 = self.Resolver(\r\n types = self.types.addAll(generics)\r\n asyncTypes = self.asyncTypes.removeAll(definition.generics.toSet())\r\n typeParameters = self.typeParameters.addAll(definition.generics.toSet())\r\n )\r\n if(!definition.generics.first().any {_ == \"Q$\"}) {\r\n [...definition.commonFields, ...definition.variants.flatMap {_.fields}].each {f =>\r\n if(self2.containsAsyncType(f.valueType)) {\r\n throw(CompileError(f.at, \"Only capabilities can contain fields of concrete capability types\"))\r\n }\r\n }\r\n }\r\n definition.DType(\r\n constraints = definition.constraints.map {self2.resolveConstraint(_, True)}\r\n commonFields = checkDuplicates(definition.commonFields.map {f =>\r\n let valueType = self2.resolveType(f.valueType, True)\r\n if(self.lspHook.isAt(f.at) || self.lspHook.isDefinedAt(f.at)) {\r\n self.lspHook.emit(\r\n ResolveVariantFieldHook(SymbolHook(f.name, f.at, f.at), valueType, commonField = True)\r\n )\r\n }\r\n f.Parameter(\r\n valueType = valueType\r\n default = f.default.map {self2.resolveTerm(_, True)}\r\n )\r\n }) {_.name} {_.at}\r\n variants = checkDuplicates(definition.variants.map {v =>\r\n if(self.lspHook.isAt(v.at)) {\r\n self.lspHook.emit(\r\n ResolveSymbolHook(SymbolHook(v.name, v.at, v.at), None, topLevel = True)\r\n )\r\n }\r\n checkDuplicates([...definition.commonFields, ...v.fields]) {_.name} {_.at}\r\n v.Variant(fields = v.fields.map {f =>\r\n let valueType = self2.resolveType(f.valueType, True)\r\n if(self.lspHook.isAt(f.at) || self.lspHook.isDefinedAt(f.at)) {\r\n self.lspHook.emit(\r\n ResolveVariantFieldHook(SymbolHook(f.name, f.at, f.at), valueType, commonField = False)\r\n )\r\n }\r\n f.Parameter(\r\n valueType = valueType\r\n default = f.default.map {self2.resolveTerm(_, True) }\r\n )\r\n })\r\n }) {_.name} {_.at}\r\n )\r\n }\r\n\r\n resolveTraitDefinition(definition: DTrait): DTrait {\r\n if(self.lspHook.isAt(definition.at) || self.lspHook.isDefinedAt(definition.at)) {\r\n self.lspHook.emit(\r\n ResolveSymbolHook(\r\n SymbolHook(definition.name, definition.at, definition.at), None, topLevel = True\r\n )\r\n )\r\n } \r\n let generics = definition.generics.map {g => Pair(g, g)}.toMap()\r\n let self2 = self.Resolver(\r\n types = self.types.addAll(generics)\r\n asyncTypes = self.asyncTypes.removeAll(definition.generics.toSet())\r\n typeParameters = self.typeParameters.addAll(definition.generics.toSet())\r\n )\r\n definition.DTrait(\r\n constraints = definition.constraints.map {self2.resolveConstraint(_, True)}\r\n methods = checkDuplicates(\r\n definition.methods.map {self2.resolveSignature(_, True, False)}\r\n ) {_.name} {_.at}\r\n methodDefaults = definition.methodDefaults.map {| Pair(name, lambda) =>\r\n let signature = definition.methods.find {_.name == name}.grab()\r\n let function1 = DFunction(signature.at, signature, lambda)\r\n let function2 = self2.resolveFunctionDefinition(function1, True, False)\r\n Pair(name, function2.body)\r\n }\r\n )\r\n }\r\n\r\n resolveInstanceDefinition(definition: DInstance): DInstance {\r\n let traitDefinedAt = self.traitLocations.get(definition.traitName).else {definition.at}\r\n if(self.lspHook.isAt(definition.at) || self.lspHook.isDefinedAt(traitDefinedAt)) {\r\n self.lspHook.emit(\r\n ResolveSymbolHook(\r\n SymbolHook(definition.traitName, definition.at, traitDefinedAt), None, topLevel = True\r\n )\r\n )\r\n }\r\n let generics = definition.generics.map {g => Pair(g, g) }.toMap()\r\n let self2 = self.Resolver(\r\n types = self.types.addAll(generics)\r\n asyncTypes = self.asyncTypes.removeAll(definition.generics.toSet())\r\n typeParameters = self.typeParameters.addAll(definition.generics.toSet())\r\n )\r\n let traitName = self2.traits.get(definition.traitName).else {\r\n throw(CompileError(definition.at, \"No such trait: \" + definition.traitName))\r\n }\r\n definition.DInstance(\r\n constraints = definition.constraints.map { self2.resolveConstraint(_, True) }\r\n traitName = traitName\r\n typeArguments = definition.typeArguments.map { self2.resolveType(_, True) }\r\n methods = definition.methods.map { self2.resolveFunctionDefinition(_, True, True) }\r\n )\r\n }\r\n\r\n resolveExtendDefinition(definition: DExtend): DExtend {\r\n let generics = definition.generics.map {g => Pair(g, g)}.toMap()\r\n let selfWithNoQ = self.Resolver(\r\n types = self.types.addAll(generics)\r\n asyncTypes = self.asyncTypes.removeAll(definition.generics.toSet())\r\n typeParameters = self.typeParameters.addAll(definition.generics.toSet())\r\n variables = self.variables.add(definition.name, definition.name)\r\n variableLocations = self.variableLocations.add(definition.name, definition.at)\r\n )\r\n let selfWithQ = selfWithNoQ.Resolver(\r\n types = selfWithNoQ.types.add(\"Q$\", \"Q$\")\r\n typeParameters = selfWithNoQ.typeParameters.add(\"Q$\")\r\n )\r\n definition.DExtend(\r\n constraints = definition.constraints.map {selfWithQ.resolveConstraint(_, True)}\r\n type = selfWithQ.resolveType(definition.type, True)\r\n methods = definition.methods.map {selfWithNoQ.resolveFunctionDefinition(_, True, False)}\r\n )\r\n }\r\n\r\n resolveLetDefinition(definition: DLet, topLevel: Bool): DLet {\r\n if(self.lspHook.isAt(definition.at) || self.lspHook.isDefinedAt(definition.at)) {\r\n self.lspHook.emit(\r\n ResolveSymbolHook(\r\n SymbolHook(definition.name, definition.at, definition.at), None, topLevel = topLevel\r\n )\r\n )\r\n }\r\n definition.DLet(\r\n variableType = self.resolveType(definition.variableType, topLevel)\r\n value = self.resolveTerm(definition.value, True)\r\n )\r\n }\r\n\r\n resolveTerm(term: Term, topLevel: Bool, inField: Bool = False): Term {\r\n term.{\r\n | EString _ => term\r\n | EChar _ => term\r\n | EInt _ => term\r\n | EFloat _ => term\r\n | EVariable e =>\r\n if(self.lspHook.isEnabled()) {\r\n let at = self.variableLocations.get(e.name).else {e.at}\r\n if(self.lspHook.isAt(e.at) || self.lspHook.isDefinedAt(at)) {\r\n self.lspHook.emit(\r\n ResolveSymbolHook(\r\n SymbolHook(e.name, e.at, at), None, topLevel = True\r\n )\r\n )\r\n }\r\n }\r\n self.variables.get(e.name).map {e.EVariable(name = _)}.else {term}\r\n | EList(at, t, items) =>\r\n EList(at, self.resolveType(t, topLevel), items.map {| Pair(item, spread) =>\r\n Pair(self.resolveTerm(item, topLevel), spread)\r\n })\r\n | EVariant(at, name, typeArguments, arguments) =>\r\n EVariant(\r\n at = at\r\n name = self.variants.get(name).else {name}\r\n typeArguments = typeArguments.map {self.resolveType(_, topLevel)}\r\n arguments = arguments.map {_.map {a => a.Argument(value = self.resolveTerm(a.value, topLevel))}}\r\n )\r\n | EVariantIs(at, name, typeArguments) =>\r\n EVariantIs(\r\n at = at\r\n name = self.variants.get(name).else {throw(CompileError(at, \"No such variant: \" + name))}\r\n typeArguments = typeArguments.map {self.resolveType(_, topLevel)}\r\n )\r\n | ECopy(at, name, record, arguments) =>\r\n ECopy(\r\n at = at\r\n name = self.variants.get(name).else {name}\r\n record = self.resolveTerm(record, topLevel, inField = True)\r\n arguments = arguments.map {f => f.Field(value = self.resolveTerm(f.value, topLevel))}\r\n )\r\n | EField e =>\r\n e.EField(record = self.resolveTerm(e.record, topLevel, inField = True))\r\n | ELambda(at, Lambda(lambdaAt, _, cases)) =>\r\n let effect = self.makeEffectArgument(lambdaAt, topLevel)\r\n ELambda(at, Lambda(lambdaAt, effect, cases.map {self.resolveCase(_, topLevel)}))\r\n | EPipe(at, value, effect, function) =>\r\n EPipe(\r\n at = at\r\n value = self.resolveTerm(value, topLevel)\r\n effect = self.resolveType(effect, topLevel)\r\n function = self.resolveTerm(function, topLevel)\r\n )\r\n | ECall(at, DynamicCall target, effect, typeArguments, arguments, dictionaries) =>\r\n ECall(\r\n at = at\r\n target = target.DynamicCall(function = self.resolveTerm(target.function, topLevel))\r\n effect = self.resolveType(effect, topLevel)\r\n typeArguments = typeArguments.map {self.resolveType(_, topLevel)}\r\n arguments = arguments.map {a => a.Argument(value = self.resolveTerm(a.value, topLevel))}\r\n dictionaries = dictionaries\r\n )\r\n | ECall(at, StaticCall _, _, _, _, _) =>\r\n throw(CompileError(at, \"Internal error: Static calls not expected in the Resolver phase\"))\r\n | ERecord(at, fields) =>\r\n ERecord(\r\n at = at\r\n fields = fields.map {f => f.Field(value = self.resolveTerm(f.value, topLevel))}\r\n )\r\n | EWildcard e =>\r\n if(e.index == 0) {throw(CompileError(e.at, \"Unbound wildcard\"))}\r\n e.EWildcard()\r\n | EFunctions(at, functions, body) =>\r\n let functionMap = functions.map {_.signature.name}.map {name => Pair(name, name)}.toMap()\r\n let locationMap = functions.map {_.signature}.map {s => Pair(s.name, s.at)}.toMap()\r\n let self2 = self.Resolver(\r\n variables = self.variables.addAll(functionMap)\r\n variableLocations = self.variableLocations.addAll(locationMap)\r\n )\r\n EFunctions(\r\n at = at\r\n functions = functions.map {self2.resolveFunctionDefinition(_, topLevel, False)}\r\n body = self2.resolveTerm(body, topLevel)\r\n )\r\n | ELet e =>\r\n let self2 = self.Resolver(\r\n variables = self.variables.add(e.name, e.name)\r\n variableLocations = self.variableLocations.add(e.name, e.at)\r\n )\r\n if(self.lspHook.isEnabled()) {\r\n if(self.lspHook.isAt(e.at) || self.lspHook.isDefinedAt(e.at)) {\r\n self.lspHook.emit(\r\n ResolveSymbolHook(\r\n SymbolHook(e.name, e.at, e.at), None, topLevel = False\r\n )\r\n )\r\n }\r\n }\r\n e.ELet(\r\n valueType = self.resolveType(e.valueType, topLevel)\r\n value = self.resolveTerm(e.value, topLevel)\r\n body = self2.resolveTerm(e.body, topLevel)\r\n )\r\n | ESequential(at, before, after) =>\r\n ESequential(\r\n at = at\r\n before = self.resolveTerm(before, topLevel)\r\n after = self.resolveTerm(after, topLevel)\r\n )\r\n | EAssign(at, operator, variable, value) =>\r\n EAssign(\r\n at = at\r\n operator = operator\r\n variable = self.variables.get(variable).else {\r\n throw(CompileError(at, \"No such variable: \" + variable))\r\n }\r\n value = self.resolveTerm(value, topLevel)\r\n )\r\n | EAssignField(at, operator, record, field, value) =>\r\n EAssignField(\r\n at = at\r\n operator = operator\r\n record = self.resolveTerm(record, topLevel)\r\n field = field\r\n value = self.resolveTerm(value, topLevel)\r\n )\r\n }\r\n }\r\n\r\n resolveType(type: Type, topLevel: Bool): Type {\r\n | TVariable _, _ =>\r\n type\r\n | TConstructor constructor, _ =>\r\n if(self.lspHook.isEnabled()) {\r\n let at = self.typeLocations.get(constructor.name).else {type.at}\r\n if(self.lspHook.isAt(type.at) || self.lspHook.isDefinedAt(at)) {\r\n self.lspHook.emit(\r\n ResolveTypeHook(\r\n self.types, self.typeGenerics\r\n SymbolHook(constructor.name, type.at, at), type\r\n )\r\n )\r\n }\r\n }\r\n let name = if(constructor.name.contains(\"$\")) {\r\n constructor.name\r\n } else {\r\n self.types.get(constructor.name).else {\r\n if(!self.lspHook.isEnabled()) {\r\n throw(CompileError(constructor.at, \"No such type: \" + constructor.name))\r\n } else {\r\n constructor.name\r\n }\r\n }\r\n }\r\n let isFunctionType = name.startsWith(\"Function$\")\r\n let effect = if(isFunctionType || self.asyncTypes.contains(constructor.name)) {\r\n [self.makeEffectArgument(constructor.at, topLevel)]\r\n } else {[]}\r\n let generics = constructor.generics.map {self.resolveType(_, topLevel)}\r\n if(isFunctionType) {\r\n let arguments = generics.dropLast()\r\n let returnType = generics.grabLast()\r\n constructor.TConstructor(\r\n name = name\r\n generics = [...effect, ...arguments, returnType]\r\n )\r\n } else {\r\n constructor.TConstructor(\r\n name = name\r\n generics = [...effect, ...generics]\r\n )\r\n }\r\n }\r\n\r\n makeEffectArgument(at: Location, topLevel: Bool): Type {\r\n if(topLevel) {\r\n if(!self.typeParameters.contains(\"Q$\")) {\r\n TConstructor(at, \"ff:core/Nothing.Nothing\", []) // Temporary workaround for top-level let\r\n } else {\r\n TConstructor(at, \"Q$\", [])\r\n }\r\n } else {\r\n self.freshUnificationVariable(at)\r\n }\r\n }\r\n\r\n resolveConstraint(constraint: Constraint, topLevel: Bool): Constraint {\r\n let traitDefinedAt = self.traitLocations.get(constraint.name).else {constraint.at}\r\n if(self.lspHook.isAt(constraint.at) || self.lspHook.isDefinedAt(traitDefinedAt)) {\r\n self.lspHook.emit(\r\n ResolveConstraintHook(SymbolHook(constraint.name, constraint.at, traitDefinedAt), constraint)\r\n )\r\n }\r\n let name =\r\n self.traits.get(constraint.name).else {\r\n throw(CompileError(constraint.at, \"No such trait: \" + constraint.name))\r\n }\r\n constraint.Constraint(\r\n name = name\r\n generics = constraint.generics.map {self.resolveType(_, topLevel)}\r\n )\r\n }\r\n\r\n resolveFunctionDefinition(definition: DFunction, topLevel: Bool, isInstanceMethod: Bool): DFunction {\r\n let signature = self.resolveSignature(definition.signature, topLevel, isInstanceMethod)\r\n let self2 = self.withSignature(signature)\r\n let body = definition.body.Lambda(\r\n effect = signature.effect\r\n cases = definition.body.cases.map {self2.resolveCase(_, False)}\r\n )\r\n DFunction(definition.at, signature, body)\r\n }\r\n\r\n resolveSignature(signature: Signature, topLevel: Bool, isInstanceMethod: Bool): Signature {\r\n if(self.lspHook.isAt(signature.at) || self.lspHook.isDefinedAt(signature.at)) {\r\n self.lspHook.emit(\r\n ResolveSignatureHook(signature, isInstanceMethod, topLevel = topLevel)\r\n )\r\n }\r\n let newSignature = if(topLevel) {\r\n signature.Signature(\r\n generics = [\"Q$\", ...signature.generics]\r\n effect = TConstructor(signature.at, \"Q$\", [])\r\n )\r\n } else {\r\n signature.Signature(\r\n effect = self.freshUnificationVariable(signature.at)\r\n )\r\n }\r\n newSignature.generics.find {name => self.typeParameters.contains(name)}.each {name =>\r\n throw(CompileError(signature.at, \"Type parameter \" + name + \" is already in scope\"))\r\n }\r\n let self2 = self.withSignature(newSignature)\r\n newSignature.Signature(\r\n constraints = newSignature.constraints.map {self2.resolveConstraint(_, topLevel)}\r\n parameters = newSignature.parameters.map {p =>\r\n p.Parameter(\r\n valueType = self2.resolveType(p.valueType, topLevel)\r\n default = p.default.map {self2.resolveTerm(_, topLevel)}\r\n )\r\n }\r\n returnType = self2.resolveType(newSignature.returnType, topLevel)\r\n )\r\n }\r\n\r\n withSignature(signature: Signature): Resolver {\r\n let variableMap = signature.parameters.map {_.name}.map {name => Pair(name, name)}.toMap()\r\n let variableLocationMap = signature.parameters.map {p => Pair(p.name, p.at)}.toMap()\r\n let typeMap = signature.generics.map {name => Pair(name, name)}.toMap()\r\n self.Resolver(\r\n variables = self.variables.addAll(variableMap)\r\n variableLocations = self.variableLocations.addAll(variableLocationMap)\r\n typeParameters = self.typeParameters.addAll(signature.generics.toSet())\r\n types = self.types.addAll(typeMap)\r\n asyncTypes = self.asyncTypes.removeAll(signature.generics.toSet())\r\n )\r\n }\r\n\r\n resolveCase(case: MatchCase, topLevel: Bool): MatchCase {\r\n function findVariables(pattern: MatchPattern): Map[String, CaseVariable] {\r\n | PString _ =>\r\n Map.new()\r\n | PInt _ =>\r\n Map.new()\r\n | PChar _ =>\r\n Map.new()\r\n | PVariable(at, Some(name)) =>\r\n [Pair(name, CaseVariable(at, name, None))].toMap()\r\n | PVariable(_, None) =>\r\n Map.new()\r\n | PVariant(_, _, patterns) =>\r\n patterns.map(findVariables).foldLeft(Map.new()) {_.addAll(_)}\r\n | PVariantAs(at, variant, variableAt, variable) =>\r\n variable.toList().map {x => Pair(x, CaseVariable(variableAt, x, Some(variant)))}.toMap()\r\n | PAlias(at, pattern, variable) =>\r\n [Pair(variable, CaseVariable(at, variable, None))].toMap().addAll(findVariables(pattern))\r\n }\r\n let variableMap = case.patterns.map(findVariables).foldLeft(Map.new()) {_.addAll(_)}\r\n mutable guards = []\r\n let variableMap2 = case.guards.foldLeft(variableMap) {variableMap1, g =>\r\n let self2 = self.Resolver(\r\n variables = self.variables.addAll(variableMap1.mapValues {_, p => p.name})\r\n variableLocations = self.variableLocations.addAll(variableMap1.mapValues {_, p => p.at})\r\n )\r\n let guard = g.MatchGuard(\r\n term = self2.resolveTerm(g.term, topLevel)\r\n pattern = self2.resolvePattern(g.pattern)\r\n )\r\n guards = [guard, ...guards]\r\n variableMap1.addAll(findVariables(guard.pattern))\r\n }\r\n let self3 = self.Resolver(\r\n variables = self.variables.addAll(variableMap2.mapValues {_, p => p.name})\r\n variableLocations = self.variableLocations.addAll(variableMap2.mapValues {_, p => p.at})\r\n )\r\n MatchCase(\r\n at = case.at\r\n patterns = case.patterns.map {self.resolvePattern(_)}\r\n guards = guards.reverse()\r\n body = self3.resolveTerm(case.body, topLevel)\r\n )\r\n }\r\n\r\n resolvePattern(pattern: MatchPattern): MatchPattern {\r\n | PString _ =>\r\n pattern\r\n | PInt _ =>\r\n pattern\r\n | PChar _ =>\r\n pattern\r\n | PVariable _ =>\r\n pattern\r\n | PVariant(at, name, patterns) =>\r\n let newName = self.variants.get(name).else {name}\r\n let newPatterns = patterns.map {self.resolvePattern(_)}\r\n PVariant(at, newName, newPatterns)\r\n | PVariantAs(at, name, variableAt, variable) =>\r\n let newName = self.variants.get(name).else {name}\r\n PVariantAs(at, newName, variableAt, variable)\r\n | PAlias(at, pattern, variable) =>\r\n let newPattern = self.resolvePattern(pattern)\r\n PAlias(at, newPattern, variable)\r\n }\r\n\r\n containsAsyncType(type: Type): Bool {\r\n | TVariable _ =>\r\n False\r\n | TConstructor constructor =>\r\n let name = if(constructor.name.contains(\"$\")) {\r\n constructor.name\r\n } else {\r\n self.types.get(constructor.name).else {\r\n if(self.lspHook.isEnabled()) {constructor.name} else:\r\n throw(CompileError(constructor.at, \"No such type: \" + constructor.name))\r\n }\r\n }\r\n let isFunctionType = name.startsWith(\"Function$\")\r\n isFunctionType || self.asyncTypes.contains(constructor.name) ||\r\n constructor.generics.any {self.containsAsyncType(_)}\r\n }\r\n\r\n}\r\n\r\ncheckDuplicates[T](items: List[T], name: T => String, at: T => Location): List[T] {\r\n mutable seen = Map.new()\r\n items.map {item =>\r\n let n = name(item)\r\n if(seen.contains(n)) {\r\n throw(CompileError(at(item), \"Duplicate definition: \" + n))\r\n }\r\n seen = seen.add(n, item)\r\n }\r\n items\r\n}\r\n"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": [
4
- "../../../../../compiler/SourceMap.ff"
4
+ "../../../../compiler/SourceMap.ff"
5
5
  ],
6
6
  "sourcesContent": [
7
7
  "makeOutputAndSourceMap(\r\n fireflyFile: String\r\n fireflySource: Option[String]\r\n writtenStrings: Array[Array[String]]\r\n writtenSegments: Array[Array[List[Int]]]\r\n writtenAnchors: IntMap[List[String]]\r\n writtenNames: StringMap[Int]\r\n): Pair[String, Json] {\r\n let lines = Array.new()\r\n let output = Array.new()\r\n mutable index = 0\r\n mutable lastSource = 0\r\n mutable lastLine = 0\r\n mutable lastColumn = 0\r\n mutable lastName = 0\r\n writtenStrings.drain().zip(writtenSegments.drain()).each {| Pair(strings, segments) =>\r\n writtenAnchors.get(index).each {anchorLines =>\r\n anchorLines.each {l =>\r\n lines.push([])\r\n output.push(l)\r\n output.push(\"\\n\")\r\n }\r\n }\r\n mutable lastOutputColumn = 0\r\n let line = Array.new()\r\n segments.each {segment =>\r\n let relative = Array.new()\r\n let newOutputColumn = segment.grab(0)\r\n relative.push(newOutputColumn - lastOutputColumn)\r\n lastOutputColumn = newOutputColumn\r\n if(segment.size() > 1) {\r\n let newSource = segment.grab(1)\r\n relative.push(newSource - lastSource)\r\n lastSource = newSource\r\n let newLine = segment.grab(2)\r\n relative.push(newLine - lastLine)\r\n lastLine = newLine\r\n let newColumn = segment.grab(3)\r\n relative.push(newColumn - lastColumn)\r\n lastColumn = newColumn\r\n if(segment.size() == 5) {\r\n let newName = segment.grab(4)\r\n relative.push(newName - lastName)\r\n lastName = newName\r\n }\r\n }\r\n line.push(relative.drain())\r\n }\r\n lines.push(line.drain())\r\n strings.each {output.push(_)}\r\n output.push(\"\\n\")\r\n index += 1\r\n }\r\n let sourceMap = sourceMap([fireflyFile], [fireflySource], writtenNames.keys(), lines.drain())\r\n Pair(output.join(), sourceMap)\r\n}\r\n\r\nmakeOutput(\r\n writtenStrings: Array[Array[String]]\r\n writtenAnchors: IntMap[List[String]]\r\n): String {\r\n let output = Array.new()\r\n writtenStrings.drain().pairs().each {| Pair(index, strings) =>\r\n writtenAnchors.get(index).each {anchorLines =>\r\n anchorLines.each {l =>\r\n output.push(l)\r\n }\r\n }\r\n output.push(strings.join())\r\n }\r\n output.join(\"\\n\")\r\n}\r\n\r\nsourceMap(\r\n sources: List[String]\r\n contents: List[Option[String]]\r\n names: List[String]\r\n lines: List[List[List[Int]]]\r\n): Json {\r\n Json->(\r\n version = 3\r\n sources = sources\r\n sourcesContent = contents.map {_.map {Json.string(_)}.else {Json.null()}}\r\n names = names\r\n mappings = toMappings(lines)\r\n )\r\n}\r\n\r\ntoMappings(lines: List[List[List[Int]]]): String {\r\n let vlq = Array.new()\r\n mutable firstLine = True\r\n lines.each {line =>\r\n if(firstLine) {\r\n firstLine = False\r\n } else {\r\n vlq.push(semicolonIndex)\r\n }\r\n mutable firstSegment = True\r\n line.each {segment =>\r\n if(firstSegment) {\r\n firstSegment = False\r\n } else {\r\n vlq.push(commaIndex)\r\n }\r\n segment.each {field =>\r\n internalToVlq(vlq, field)\r\n }\r\n }\r\n }\r\n toBase64Vlq(vlq.drain())\r\n}\r\n\r\ntoBase64Vlq(vlq: List[Int]): String {\r\n let result = Buffer.new(vlq.size())\r\n\r\n 0.until(vlq.size()).each {i =>\r\n result.setUint8(i, base64Characters.grab(vlq.grab(i)).codeUnit)\r\n }\r\n\r\n result.toString()\r\n}\r\n\r\ninternalToVlq(vlq: Array[Int], value: Int) {\r\n mutable digit = 0\r\n mutable v = value\r\n\r\n if(v < 0) {\r\n v = v.abs().bitLeft(1).bitOr(1)\r\n } else {\r\n v = v.bitLeft(1)\r\n }\r\n\r\n doWhile {\r\n digit = v.bitAnd(vlqBaseMask)\r\n v = v.bitRightUnsigned(vlqBaseShift)\r\n if(v > 0) {\r\n digit = digit.bitOr(vlqContinuationBit)\r\n }\r\n vlq.push(digit)\r\n v > 0\r\n }\r\n}\r\n\r\nvlqBaseShift = 5\r\nvlqBaseMask = 1.bitLeft(vlqBaseShift) - 1\r\nvlqContinuationBit = 1.bitLeft(vlqBaseShift)\r\nbase64Characters = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/;,\"\r\nsemicolonIndex = base64Characters.indexOf(\";\").grab()\r\ncommaIndex = base64Characters.indexOf(\",\").grab()\r\n"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": [
4
- "../../../../../compiler/Substitution.ff"
4
+ "../../../../compiler/Substitution.ff"
5
5
  ],
6
6
  "sourcesContent": [
7
7
  "import Syntax\r\n\r\nclass Substitution(mutable substitution: Map[Int, Type])\r\n\r\ncore(name: String): String {\r\n \"ff:core/\" + name + \".\" + name\r\n}\r\n\r\nextend self: Substitution {\r\n\r\n substituteModule(module: Module): Module {\r\n let lets = module.lets.map { self.substituteLetDefinition(_) }\r\n let functions = module.functions.map { self.substituteFunctionDefinition(_) }\r\n let extends = module.extends.map { self.substituteExtendDefinition(_) }\r\n //let traits = module.traits.map { self.substituteTraitDefinition(_) }\r\n let instances = module.instances.map { self.substituteInstanceDefinition(_) }\r\n module.Module(\r\n //traits = traits,\r\n instances = instances\r\n extends = extends\r\n lets = lets\r\n functions = functions\r\n )\r\n }\r\n\r\n substituteLetDefinition(definition: DLet): DLet {\r\n definition.DLet(\r\n variableType = self.substituteType(definition.variableType)\r\n value = self.substituteTerm(definition.value)\r\n )\r\n }\r\n\r\n substituteExtendDefinition(definition: DExtend): DExtend {\r\n definition.DExtend(\r\n methods = definition.methods.map { self.substituteFunctionDefinition(_) }\r\n )\r\n }\r\n\r\n substituteFunctionDefinition(definition: DFunction): DFunction {\r\n definition.DFunction(\r\n signature = self.substituteSignature(definition.signature)\r\n body = self.substituteLambda(definition.body)\r\n )\r\n }\r\n\r\n substituteSignature(signature: Signature): Signature {\r\n signature.Signature(\r\n constraints = signature.constraints.map {self.substituteConstraint(_)}\r\n parameters = signature.parameters.map {self.substituteParameter(_)}\r\n returnType = self.substituteType(signature.returnType)\r\n effect = self.substituteType(signature.effect)\r\n )\r\n }\r\n\r\n substituteConstraint(constraint: Constraint): Constraint {\r\n constraint.Constraint(\r\n generics = constraint.generics.map {self.substituteType(_)}\r\n )\r\n }\r\n\r\n substituteParameter(parameter: Parameter): Parameter {\r\n parameter.Parameter(\r\n valueType = self.substituteType(parameter.valueType)\r\n default = parameter.default.map {self.substituteTerm(_)}\r\n )\r\n }\r\n\r\n substituteInstanceDefinition(definition: DInstance): DInstance {\r\n definition.DInstance(\r\n methods = definition.methods.map { self.substituteFunctionDefinition(_) }\r\n )\r\n }\r\n\r\n substituteLambda(definition: Lambda): Lambda {\r\n definition.Lambda(\r\n effect = self.substituteType(definition.effect)\r\n cases = definition.cases.map { case =>\r\n case.MatchCase(\r\n guards = case.guards.map { g => g.MatchGuard(term = self.substituteTerm(g.term)) }\r\n body = self.substituteTerm(case.body)\r\n )\r\n }\r\n )\r\n }\r\n\r\n substituteTerm(term: Term): Term {\r\n term.{\r\n | EString _ => term\r\n | EChar _ => term\r\n | EInt _ => term\r\n | EFloat _ => term\r\n | EVariable _ => term\r\n | EField e => e.EField(record = self.substituteTerm(e.record))\r\n | EWildcard e => term\r\n | EList e => e.EList(\r\n elementType = self.substituteType(e.elementType)\r\n items = e.items.map {| Pair(item, b) => Pair(self.substituteTerm(item), b) }\r\n )\r\n | ESequential e => e.ESequential(\r\n before = self.substituteTerm(e.before)\r\n after = self.substituteTerm(e.after)\r\n )\r\n | ELet e => e.ELet(\r\n valueType = self.substituteType(e.valueType)\r\n value = self.substituteTerm(e.value)\r\n body = self.substituteTerm(e.body)\r\n )\r\n | ELambda e => e.ELambda(lambda = self.substituteLambda(e.lambda))\r\n | EVariant e => e.EVariant(\r\n typeArguments = e.typeArguments.map {self.substituteType(_)}\r\n arguments = e.arguments.map { _.map {self.substituteArgument(_)} }\r\n )\r\n | EVariantIs e => e.EVariantIs(\r\n typeArguments = e.typeArguments.map {self.substituteType(_)}\r\n )\r\n | ECopy e => e.ECopy(\r\n record = self.substituteTerm(e.record)\r\n arguments = e.arguments.map {self.substituteField(_)}\r\n )\r\n | EPipe e => e.EPipe(\r\n value = self.substituteTerm(e.value)\r\n effect = self.substituteType(e.effect)\r\n function = self.substituteTerm(e.function)\r\n )\r\n | ECall e => e.ECall(\r\n target = e.target.{\r\n | DynamicCall call => call.DynamicCall(function = self.substituteTerm(call.function))\r\n | StaticCall _ => e.target\r\n }\r\n effect = self.substituteType(e.effect)\r\n typeArguments = e.typeArguments.map {self.substituteType(_)}\r\n arguments = e.arguments.map {self.substituteArgument(_)}\r\n )\r\n | ERecord e => e.ERecord(fields = e.fields.map {self.substituteField(_)})\r\n | EFunctions e => e.EFunctions(\r\n functions = e.functions.map {self.substituteFunctionDefinition(_)}\r\n body = self.substituteTerm(e.body)\r\n )\r\n | EAssign e => e.EAssign(value = self.substituteTerm(e.value))\r\n | EAssignField e => e.EAssignField(\r\n record = self.substituteTerm(e.record)\r\n value = self.substituteTerm(e.value)\r\n )\r\n }\r\n }\r\n\r\n substituteArgument(argument: Argument): Argument {\r\n argument.Argument(value = self.substituteTerm(argument.value))\r\n }\r\n\r\n substituteField(field: Field): Field {\r\n field.Field(value = self.substituteTerm(field.value))\r\n }\r\n\r\n substituteType(type: Type): Type {\r\n | TVariable(at, i) =>\r\n if(self.has(i)) {self.substituteType(self.get(i))} else {TConstructor(at, core(\"Nothing\"), [])}\r\n | TConstructor t =>\r\n t.TConstructor(generics = t.generics.map {g => self.substituteType(g)})\r\n }\r\n\r\n get(index: Int): Type {\r\n self.substitution.grab(index).{\r\n | TVariable(_, i) { self.has(i) } =>\r\n let t = self.get(i)\r\n self.substitution = self.substitution.add(index, t)\r\n t\r\n | TVariable(at, _) =>\r\n TConstructor(at, core(\"Nothing\"), [])\r\n | t => t\r\n }\r\n }\r\n\r\n has(index: Int): Bool {\r\n self.substitution.contains(index)\r\n }\r\n\r\n}\r\n"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": [
4
- "../../../../../compiler/Syntax.ff"
4
+ "../../../../compiler/Syntax.ff"
5
5
  ],
6
6
  "sourcesContent": [
7
7
  "data Location(file: String, line: Int, column: Int)\r\n\r\nextend self: Location {\r\n show(): String {\r\n \"in \" + self.file + \" \" +\r\n \"at line \" + self.line +\r\n \", column \" + self.column\r\n }\r\n}\r\n\r\ndata CompileError(at: Location, message: String)\r\ndata CompileErrors(errors: List[CompileError])\r\n\r\ndata ModuleWithPackageInfo(\r\n packageInfo: Option[PackageInfo]\r\n module: Module\r\n)\r\n\r\ndata PackageInfo(\r\n package: DPackage\r\n dependencies: List[DDependency]\r\n includes: List[DInclude]\r\n)\r\n\r\n// TODO rename to PackageKey\r\ndata PackagePair(\r\n group: String\r\n name: String\r\n)\r\n\r\nextend self: PackagePair {\r\n groupName(delimiter: String = \":\"): String {\r\n self.group + delimiter + self.name\r\n }\r\n isCore(): Bool {\r\n self.group == \"ff\" &&\r\n self.name == \"core\"\r\n }\r\n moduleKey(packageRoot: Path, modulePath: Path): Option[ModuleKey] {\r\n let parts = modulePath.relativeListTo(packageRoot)\r\n let folders = parts.dropLast()\r\n parts.last().flatMap {_.removeLast(\".ff\")}.filter {_ =>\r\n folders.all {_.first().any {_.isAsciiLower()}} &&\r\n folders.all {_.all {c => c.isAsciiLower() || c.isAsciiDigit()}}\r\n }.map: name =>\r\n ModuleKey(self, folders, name)\r\n }\r\n}\r\n\r\nscriptPackagePair: PackagePair = PackagePair(\"script\", \"script\")\r\n\r\ndata ModuleKey(\r\n packagePair: PackagePair\r\n folders: List[String]\r\n name: String\r\n)\r\n\r\nextend self: ModuleKey {\r\n // \"folder/Module\" as in: import folder/Module from group:package\r\n importName(): String {\r\n self.folders.map {_ + \"/\"}.join() + self.name\r\n }\r\n // \"C:\\myProject\\folder\\Module.ff\"\r\n path(packageRoot: Path): Path {\r\n let parent = self.folders.foldLeft(packageRoot) {p, f => p.slash(f)}\r\n parent.slash(self.name + \".ff\")\r\n }\r\n // \"group:package/folder/Module\"\r\n qualifiedName(): String {\r\n self.packagePair.groupName() + \"/\" + self.importName()\r\n }\r\n // \"ff:core/List.List_map\"\r\n qualifiedSymbol(symbol: String): String {\r\n self.qualifiedName() + \".\" + symbol\r\n }\r\n}\r\n\r\ndata Module(\r\n moduleKey: ModuleKey\r\n imports: List[DImport]\r\n types: List[DType]\r\n traits: List[DTrait]\r\n instances: List[DInstance]\r\n extends: List[DExtend]\r\n lets: List[DLet]\r\n functions: List[DFunction]\r\n)\r\n\r\ndata DPackage(\r\n at: Location\r\n packagePair: PackagePair\r\n version: Version\r\n targets: TargetNames\r\n)\r\ndata DDependency(\r\n at: Location\r\n packagePair: PackagePair\r\n version: Version\r\n safety: Safety\r\n targets: TargetNames\r\n)\r\ndata DInclude(\r\n at: Location\r\n path: String\r\n)\r\ndata TargetNames(\r\n node: Bool\r\n browser: Bool\r\n)\r\ndata DImport(\r\n at: Location\r\n alias: String\r\n moduleKey: ModuleKey\r\n)\r\ndata DFunction(\r\n at: Location\r\n signature: Signature\r\n body: Lambda\r\n)\r\ndata DLet(\r\n at: Location\r\n name: String\r\n variableType: Type\r\n value: Term\r\n)\r\ndata DExtend(\r\n at: Location\r\n name: String\r\n generics: List[String]\r\n constraints: List[Constraint]\r\n type: Type\r\n methods: List[DFunction]\r\n)\r\ndata DType(\r\n at: Location\r\n newtype: Bool\r\n data: Bool\r\n name: String\r\n generics: List[String]\r\n constraints: List[Constraint]\r\n commonFields: List[Parameter]\r\n variants: List[Variant]\r\n)\r\ndata DTrait(\r\n at: Location\r\n name: String\r\n generics: List[String]\r\n constraints: List[Constraint]\r\n generatorParameters: List[Parameter]\r\n methods: List[Signature]\r\n methodDefaults: List[Pair[String, Lambda]]\r\n methodGenerators: List[Pair[String, Lambda]]\r\n)\r\ndata DInstance(\r\n at: Location\r\n generics: List[String]\r\n constraints: List[Constraint]\r\n traitName: String\r\n typeArguments: List[Type]\r\n generatorArguments: List[Argument]\r\n methods: List[DFunction]\r\n derived: Bool\r\n)\r\n\r\ndata Term(at: Location) {\r\n EString(value: String)\r\n EChar(value: String)\r\n EInt(value: String)\r\n EFloat(value: String)\r\n EVariable(name: String)\r\n ELambda(lambda: Lambda)\r\n EFunctions(functions: List[DFunction], body: Term)\r\n ELet(mutable: Bool, name: String, valueType: Type, value: Term, body: Term)\r\n ESequential(before: Term, after: Term)\r\n EAssign(operator: String, variable: String, value: Term)\r\n EAssignField(operator: String, record: Term, field: String, value: Term)\r\n EPipe(value: Term, effect: Type, function: Term)\r\n ECall(\r\n target: CallTarget\r\n effect: Type\r\n typeArguments: List[Type]\r\n arguments: List[Argument]\r\n dictionaries: List[Dictionary]\r\n )\r\n EList(elementType: Type, items: List[Pair[Term, Bool]])\r\n ECopy(name: String, record: Term, arguments: List[Field])\r\n EVariant(name: String, typeArguments: List[Type], arguments: Option[List[Argument]])\r\n EVariantIs(name: String, typeArguments: List[Type])\r\n ERecord(fields: List[Field])\r\n EField(newtype: Bool, record: Term, field: String)\r\n EWildcard(index: Int)\r\n}\r\n\r\ndata CallTarget {\r\n DynamicCall(function: Term, tailCall: Bool)\r\n StaticCall(name: String, tailCall: Bool, instanceCall: Bool)\r\n}\r\n\r\ndata MatchCase(\r\n at: Location\r\n patterns: List[MatchPattern]\r\n guards: List[MatchGuard]\r\n body: Term\r\n)\r\n\r\ndata MatchPattern(at: Location) {\r\n PString(value: String)\r\n PInt(value: String)\r\n PChar(value: String)\r\n PVariable(name: Option[String])\r\n PVariant(name: String, patterns: List[MatchPattern])\r\n PVariantAs(name: String, variableAt: Location, variable: Option[String])\r\n PAlias(pattern: MatchPattern, variable: String)\r\n}\r\n\r\ndata MatchGuard(\r\n at: Location\r\n term: Term\r\n pattern: MatchPattern\r\n)\r\n\r\ndata Dictionary(\r\n moduleKey: ModuleKey\r\n traitName: String\r\n typeName: String\r\n dictionaries: List[Dictionary]\r\n)\r\n\r\ndata Signature(\r\n at: Location\r\n name: String\r\n member: Bool\r\n generics: List[String]\r\n constraints: List[Constraint]\r\n parameters: List[Parameter]\r\n returnType: Type\r\n effect: Type\r\n)\r\n\r\ndata Lambda(at: Location, effect: Type, cases: List[MatchCase])\r\n\r\ndata Variant(at: Location, name: String, fields: List[Parameter])\r\n\r\ndata Parameter(at: Location, mutable: Bool, name: String, valueType: Type, default: Option[Term])\r\n\r\ndata Argument(at: Location, name: Option[String], value: Term)\r\n\r\ndata Field(at: Location, name: String, value: Term)\r\n\r\ndata Constraint(at: Location, name: String, generics: List[Type])\r\n\r\ndata Type(at: Location) {\r\n TConstructor(name: String, generics: List[Type])\r\n TVariable(index: Int)\r\n}\r\n\r\ndata Safety {\r\n Safe\r\n Unsafe\r\n Trusted\r\n}\r\n\r\ndata Version(at: Location, major: Int, minor: Int, patch: Int)\r\n\r\nextend self: Type {\r\n show(shownTypes: List[Type]): String {\r\n mutable seenTypes = Map.new()\r\n let typeNames = 'a'.codeUnit.to('z'.codeUnit).map {Char(_).toString()}.toStream()\r\n function shortenType(qualified: String): String {\r\n qualified.reverse().takeWhile {_ != '.'}.reverse()\r\n }\r\n function shortenTypes(types: List[Type]) {\r\n types.each {\r\n | TConstructor(_, name, typeArguments) =>\r\n let shortenedName = shortenType(name)\r\n seenTypes.get(shortenedName).{\r\n | None => \r\n seenTypes = seenTypes.add(shortenedName, name)\r\n | Some(qualified) => \r\n if(name != qualified) {\r\n seenTypes = seenTypes.add(shortenedName, \"\")\r\n }\r\n }\r\n shortenTypes(typeArguments)\r\n | TVariable(_, index) =>\r\n if(!seenTypes.contains(\"$\" + index)) {\r\n seenTypes = seenTypes.add(\"$\" + index, typeNames.next().else {\"$\" + index})\r\n }\r\n }\r\n }\r\n shortenTypes([...shownTypes, self])\r\n function go(type: Type): String {\r\n type.{\r\n | TConstructor(at, name, [_, r]) {name.startsWith(\"Function$\")} =>\r\n \"() => \" + go(r)\r\n | TConstructor(at, name, [_, a, r]) {name.startsWith(\"Function$\")} =>\r\n go(a) + \" => \" + go(r)\r\n | TConstructor(at, name, [_, ...generics]) {name.startsWith(\"Function$\")} =>\r\n \"(\" + generics.dropLast().map {go(_)}.join(\", \") + \") => \" + go(generics.grabLast())\r\n | TConstructor(at, name, generics) {name.startsWith(\"Record$\")} =>\r\n let as = name.split('$').dropFirst().zip(generics)\r\n \"(\" + as.map {| Pair(label, t) => label + \": \" + go(t)}.join(\", \") + \")\"\r\n | TConstructor(at, name, generics) =>\r\n let shortenedName = shortenType(name)\r\n let chosenName = seenTypes.grab(shortenedName).{\r\n | \"\" => name\r\n | _ => shortenedName\r\n }\r\n let filteredGenerics = generics.filter {\r\n // Hack to hide the effect, only works when the effect is Q$\r\n | TConstructor(_, \"Q$\", _) => False\r\n | _ => True\r\n }\r\n if(filteredGenerics.isEmpty()) {chosenName} else {\r\n chosenName + \"[\" + filteredGenerics.map {go(_)}.join(\", \") + \"]\"\r\n }\r\n | TVariable(at, index) =>\r\n seenTypes.grab(\"$\" + index)\r\n }\r\n }\r\n go(self)\r\n }\r\n}\r\n\r\ncatchMany[T](list: List[T], body: T => T): List[T] {\r\n let errors = Array.new()\r\n let result = catchManyInto(errors, list, body)\r\n errors.drain().{\r\n | [] => result\r\n | [Pair(_, error)] => error.rethrow()\r\n | allErrors => throw(CompileErrors(allErrors.map {_.first}))\r\n }\r\n}\r\n\r\ncatchManyInto[T](errors: Array[Pair[CompileError, Error]], list: List[T], body: T => T): List[T] {\r\n let result = list.map {x =>\r\n try {\r\n body(x)\r\n } tryCatch {| CompileError(at, message), error =>\r\n errors.push(Pair(CompileError(at, message), error))\r\n x\r\n } catch {| CompileErrors(compileErrors), error =>\r\n compileErrors.each {compileError => \r\n errors.push(Pair(compileError, error))\r\n }\r\n x\r\n }\r\n }\r\n if(errors.isEmpty()) {result} else {[]}\r\n}\r\n"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": [
4
- "../../../../../compiler/Token.ff"
4
+ "../../../../compiler/Token.ff"
5
5
  ],
6
6
  "sourcesContent": [
7
7
  "import Syntax\r\n\r\ndata Token(\r\n file: String\r\n code: String\r\n kind: TokenKind\r\n startLine: Int\r\n startLineOffset: Int\r\n startOffset: Int\r\n stopLine: Int\r\n stopLineOffset: Int\r\n stopOffset: Int\r\n)\r\n\r\nextend token: Token {\r\n\r\n at(): Location {\r\n Location(token.file, token.startLine, (token.startOffset - token.startLineOffset) + 1)\r\n }\r\n\r\n end(): Location {\r\n Location(token.file, token.startLine, (token.stopOffset - token.startLineOffset) + 1)\r\n }\r\n\r\n raw(): String {\r\n token.code.slice(token.startOffset, token.stopOffset)\r\n }\r\n\r\n is(kind1: TokenKind): Bool {\r\n token.kind == kind1\r\n }\r\n\r\n is2(kind1: TokenKind, kind2: TokenKind): Bool {\r\n token.kind == kind1 || token.kind == kind2\r\n }\r\n\r\n is3(kind1: TokenKind, kind2: TokenKind, kind3: TokenKind): Bool {\r\n token.kind == kind1 || token.kind == kind2 || token.kind == kind3\r\n }\r\n\r\n is4(kind1: TokenKind, kind2: TokenKind, kind3: TokenKind, kind4: TokenKind): Bool {\r\n token.kind == kind1 || token.kind == kind2 || token.kind == kind3 || token.kind == kind4\r\n }\r\n\r\n is5(kind1: TokenKind, kind2: TokenKind, kind3: TokenKind, kind4: TokenKind, kind5: TokenKind): Bool {\r\n token.kind == kind1 || token.kind == kind2 || token.kind == kind3 || token.kind == kind4 || token.kind == kind5\r\n }\r\n\r\n rawIs(value: String): Bool {\r\n token.stopOffset - token.startOffset == value.size() &&\r\n token.code.startsWith(value, token.startOffset)\r\n }\r\n\r\n rawIs2(value1: String, value2: String): Bool {\r\n token.rawIs(value1) || token.rawIs(value2)\r\n }\r\n\r\n rawIs3(value1: String, value2: String, value3: String): Bool {\r\n token.rawIs(value1) || token.rawIs(value2) || token.rawIs(value3)\r\n }\r\n\r\n rawIs4(value1: String, value2: String, value3: String, value4: String): Bool {\r\n token.rawIs(value1) || token.rawIs(value2) || token.rawIs(value3) || token.rawIs(value4)\r\n }\r\n\r\n}\r\n\r\ndata TokenKind {\r\n LEnd\r\n LString\r\n LChar\r\n LInt\r\n LFloat\r\n LKeyword\r\n LNamespace\r\n LLower\r\n LUpper\r\n LWildcard\r\n LBracketLeft\r\n LBracketRight\r\n LOperator\r\n LUnary\r\n LComma\r\n LSeparator\r\n LDot\r\n LSemicolon\r\n LPipe\r\n LColon\r\n LDotDotDot\r\n LArrowThin\r\n LArrowThick\r\n LAssign\r\n LAssignPlus\r\n LAssignMinus\r\n LAssignMultiplication\r\n LAssignDivision\r\n}\r\n\r\nextend self: TokenKind {\r\n\r\n beforeSeparator(): Bool {\r\n self.{\r\n | LEnd => False\r\n | LString => True\r\n | LChar => True\r\n | LInt => True\r\n | LFloat => True\r\n | LKeyword => True\r\n | LNamespace => False\r\n | LLower => True\r\n | LUpper => True\r\n | LWildcard => True\r\n | LBracketLeft => False\r\n | LBracketRight => True\r\n | LUnary => True\r\n | LOperator => False\r\n | LComma => False\r\n | LSeparator => False\r\n | LDot => False\r\n | LSemicolon => False\r\n | LPipe => False\r\n | LColon => False\r\n | LDotDotDot => False\r\n | LArrowThin => False\r\n | LArrowThick => False\r\n | LAssign => False\r\n | LAssignPlus => False\r\n | LAssignMinus => False\r\n | LAssignMultiplication => False\r\n | LAssignDivision => False\r\n \r\n }\r\n }\r\n\r\n afterSeparator(): Bool {\r\n self.{\r\n | LEnd => False\r\n | LString => True\r\n | LChar => True\r\n | LInt => True\r\n | LFloat => True\r\n | LKeyword => True\r\n | LNamespace => True\r\n | LLower => True\r\n | LUpper => True\r\n | LWildcard => True\r\n | LBracketLeft => True\r\n | LBracketRight => False\r\n | LUnary => True\r\n | LOperator => False\r\n | LComma => False\r\n | LSeparator => False\r\n | LDot => False\r\n | LSemicolon => False\r\n | LPipe => False\r\n | LColon => False\r\n | LDotDotDot => True\r\n | LArrowThin => False\r\n | LArrowThick => False\r\n | LAssign => False\r\n | LAssignPlus => False\r\n | LAssignMinus => False\r\n | LAssignMultiplication => False\r\n | LAssignDivision => False\r\n }\r\n }\r\n\r\n afterKeyword(): Bool {\r\n self.{\r\n | LEnd => False\r\n | LString => True\r\n | LChar => True\r\n | LInt => True\r\n | LFloat => True\r\n | LKeyword => True\r\n | LNamespace => True\r\n | LLower => True\r\n | LUpper => True\r\n | LWildcard => True\r\n | LBracketLeft => False\r\n | LBracketRight => False\r\n | LUnary => False\r\n | LOperator => False\r\n | LComma => False\r\n | LSeparator => False\r\n | LDot => False\r\n | LSemicolon => False\r\n | LPipe => False\r\n | LColon => False\r\n | LDotDotDot => False\r\n | LArrowThin => False\r\n | LArrowThick => False\r\n | LAssign => False\r\n | LAssignPlus => False\r\n | LAssignMinus => False\r\n | LAssignMultiplication => False\r\n | LAssignDivision => False\r\n }\r\n }\r\n\r\n}\r\n"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": [
4
- "../../../../../compiler/Tokenizer.ff"
4
+ "../../../../compiler/Tokenizer.ff"
5
5
  ],
6
6
  "sourcesContent": [
7
7
  "import Token\r\nimport Syntax\r\nimport LspHook\r\n\r\ntokenize(file: String, code: String, completionAt: Option[Location], attemptFixes: Bool): List[Token] {\r\n\r\n let completionLine = completionAt.filter {_.file == file}.map {_.line}.else {-1}\r\n let completionColumn = completionAt.filter {_.file == file}.map {_.column}.else {-1}\r\n\r\n let tokens = Array.new[Token]()\r\n mutable line = 1\r\n mutable lineOffset = 0\r\n\r\n mutable startLine = line\r\n mutable startLineOffset = lineOffset\r\n\r\n let operatorCharactersString = \"!@#$%&/=?+|^~*<>.:-;\"\r\n mutable operatorCharacters = Set.new[Char]()\r\n List.range(operatorCharactersString.size()).map {j =>\r\n operatorCharacters = operatorCharacters.add(operatorCharactersString.grab(j))\r\n }\r\n\r\n function emitToken(kind: TokenKind, startOffset: Int, stopOffset: Int): Unit {\r\n if(!tokens.isEmpty()) {\r\n let last = tokens.grabLast()\r\n if(last.stopLine == startLine && last.kind == LLower && kind.afterKeyword()) {\r\n if(\r\n completionLine == last.startLine && \r\n completionColumn >= 1 + last.startOffset - last.startLineOffset &&\r\n completionColumn <= 1 + last.stopOffset - last.stopLineOffset\r\n ) {\r\n tokens.push(Token(\r\n file, code, LSeparator\r\n startLine, startLineOffset, startLineOffset\r\n startLine, startLineOffset, startLineOffset\r\n ))\r\n } else {\r\n tokens.modify(tokens.size() - 1) {_.Token(kind = LKeyword)}\r\n }\r\n }\r\n if(last.stopLine != startLine && last.kind.beforeSeparator() && kind.afterSeparator()) {\r\n tokens.push(Token(\r\n file, code, LSeparator\r\n startLine, startLineOffset, startLineOffset\r\n startLine, startLineOffset, startLineOffset\r\n ))\r\n }\r\n }\r\n tokens.push(Token(\r\n file, code, kind\r\n startLine, startLineOffset, startOffset\r\n line, lineOffset, stopOffset\r\n ))\r\n }\r\n\r\n mutable i = 0\r\n\r\n function throwError(message: String) {\r\n let column = (i - startLineOffset) + 1\r\n throw(CompileError(\r\n Location(file, line, column)\r\n message\r\n ))\r\n }\r\n\r\n try {\r\n while {i < code.size()} {\r\n\r\n startLine = line\r\n startLineOffset = lineOffset\r\n\r\n if(completionLine == line) {\r\n while {i < code.size() && (code.grab(i) == ' ' || code.grab(i) == '\\t' || code.grab(i) == '\\r')} {\r\n if(completionColumn == 1 + i - lineOffset) {\r\n emitToken(LLower, i, i)\r\n }\r\n i += 1\r\n }\r\n if(i < code.size() && completionColumn == 1 + i - lineOffset) {\r\n let c = code.grab(i)\r\n if(!c.isAsciiLetterOrDigit() && c != '_' && c != '\\'' && c != '\"') {\r\n emitToken(LLower, i, i)\r\n if(i + 1 < code.size() && code.grab(i) == '_') {i += 1}\r\n }\r\n }\r\n } else {\r\n while {i < code.size() && (code.grab(i) == ' ' || code.grab(i) == '\\t' || code.grab(i) == '\\r')} {i += 1}\r\n }\r\n \r\n if(i < code.size()):\r\n\r\n let start = i\r\n\r\n if(code.grab(i) == '\\n') {\r\n\r\n i += 1\r\n line += 1\r\n lineOffset = i\r\n\r\n } elseIf {code.grab(i) == '/' && code.grab(i + 1) == '/'} {\r\n\r\n i += 2\r\n while {i < code.size() && code.grab(i) != '\\n'} {i += 1}\r\n\r\n } elseIf {code.grab(i) == '/' && code.grab(i + 1) == '*'} {\r\n\r\n i += 2\r\n while {i < code.size() && (code.grab(i) != '*' || code.grab(i + 1) != '/')} {\r\n if(i >= code.size()) {\r\n throwError(\r\n \"Expected end of comment started on line \" + startLine + \", got end of file.\"\r\n )\r\n }\r\n if(code.grab(i) == '\\n') {\r\n line += 1\r\n lineOffset = i + 1\r\n }\r\n i += 1\r\n }\r\n i += 2\r\n\r\n } elseIf {code.grab(i) == '\"' || code.grab(i) == '\\''} {\r\n\r\n let endSign = code.grab(i)\r\n\r\n mutable multiLine = i + 2 < code.size() &&\r\n code.grab(i) == '\"' && code.grab(i + 1) == '\"' && code.grab(i + 2) == '\"'\r\n\r\n i += if(multiLine) {3} else {1}\r\n while {i < code.size() && (multiLine || code.grab(i) != endSign)} {\r\n if(code.grab(i) == '\\n') {\r\n if(multiLine) {\r\n line += 1\r\n lineOffset = i + 1\r\n } else {\r\n throwError(\r\n \"Unexpected end of line in string.\"\r\n )\r\n }\r\n }\r\n if(i >= code.size()) {\r\n throwError(\r\n \"Expected end of string started on line \" + startLine + \", got end of file.\"\r\n )\r\n }\r\n if(code.grab(i) == '\\\\' && code.grab(i + 1) != '\\n') {i += 1}\r\n if(multiLine &&\r\n i + 2 < code.size() && (i + 3 >= code.size() || code.grab(i + 3) != '\"') &&\r\n code.grab(i) == '\"' && code.grab(i + 1) == '\"' && code.grab(i + 2) == '\"'\r\n ) {\r\n multiLine = False\r\n i += 2\r\n } else {\r\n i += 1\r\n }\r\n }\r\n i += 1\r\n emitToken(if(endSign == '\"') {LString} else {LChar}, start, i)\r\n\r\n } elseIf {code.grab(i).isAsciiLetter()} {\r\n\r\n let kind = if(code.grab(i) >= 'a') {LLower} else {LUpper}\r\n i += 1\r\n while {i < code.size() && code.grab(i).isAsciiLetterOrDigit()} {i += 1}\r\n if(i < code.size() && kind == LUpper && code.grab(i) == '.' && (\r\n tokens.isEmpty() || tokens.grabLast().kind != LArrowThin\r\n )) {\r\n i += 1\r\n emitToken(LNamespace, start, i)\r\n } else {\r\n emitToken(kind, start, i)\r\n }\r\n\r\n } elseIf {code.grab(i).isAsciiDigit()} {\r\n\r\n if(i + 2 < code.size() && code.grab(i) == '0' && (\r\n code.grab(i + 1) == 'x' || code.grab(i + 1) == 'X'\r\n )) {\r\n i += 2\r\n while {i < code.size() && (code.grab(i).isAsciiDigit() || (\r\n code.grab(i) >= 'a' && code.grab(i) <= 'f'\r\n ) || (\r\n code.grab(i) >= 'A' && code.grab(i) <= 'F'\r\n ))} {\r\n i += 1\r\n }\r\n if(start == i - 2) {\r\n throwError(\"Unexpected character: \" + Show.show(code.grab(start + 2)))\r\n }\r\n emitToken(LInt, start, i)\r\n } else:\r\n\r\n mutable dot = False\r\n mutable exponent = False\r\n while {i < code.size() && code.grab(i).isAsciiDigit()} {\r\n i += 1\r\n if((code.grab(i) == 'e' || code.grab(i) == 'E') && !exponent) {\r\n i += 1\r\n dot = True\r\n exponent = True\r\n if(code.grab(i) == '+' || code.grab(i) == '-') {i += 1}\r\n }\r\n if(\r\n i + 1 < code.size() && code.grab(i) == '.' &&\r\n code.grab(i + 1).isAsciiDigit() &&\r\n !dot && !exponent\r\n ) {\r\n i += 1\r\n dot = True\r\n }\r\n }\r\n emitToken(if(dot || exponent) {LFloat} else {LInt}, start, i)\r\n\r\n } elseIf {code.grab(i) == '_'} {\r\n\r\n i += 1\r\n emitToken(LWildcard, start, i)\r\n\r\n } elseIf {code.grab(i) == ','} {\r\n\r\n i += 1\r\n emitToken(LComma, start, i)\r\n\r\n } elseIf {\r\n code.grab(i) == '?' || \r\n (code.grab(i) == '!' && (i + 1 >= code.size() || code.grab(i + 1) != '='))\r\n } {\r\n \r\n i += 1\r\n emitToken(LUnary, start, i)\r\n \r\n } elseIf {operatorCharacters.contains(code.grab(i))} {\r\n\r\n i += 1\r\n \r\n if(code.grab(i - 1) == '.' && i + 1 < code.size() && code.grab(i) == '.' && code.grab(i + 1) != '.') {\r\n emitToken(LDot, start, i)\r\n let newStart = i\r\n if(!completionAt.isEmpty()) {emitToken(LLower, newStart, newStart)}\r\n i += 1\r\n emitToken(LDot, newStart, i)\r\n } else:\r\n\r\n while {i < code.size() && operatorCharacters.contains(code.grab(i))} {i += 1}\r\n let o =\r\n if(i - start == 1 && code.grab(i - 1) == '.') {\r\n LDot\r\n } elseIf {i - start == 1 && code.grab(i - 1) == ';'} {\r\n LSemicolon\r\n } elseIf {i - start == 1 && code.grab(i - 1) == '|'} {\r\n LPipe\r\n } elseIf {i - start == 1 && code.grab(i - 1) == ':'} {\r\n LColon\r\n } elseIf {i - start == 3 && code.grab(i - 3) == '.' && code.grab(i - 2) == '.' && code.grab(i - 1) == '.'} {\r\n LDotDotDot\r\n } elseIf {i - start == 2 && code.grab(i - 2) == '-' && code.grab(i - 1) == '>'} {\r\n LArrowThin\r\n } elseIf {i - start == 2 && code.grab(i - 2) == '=' && code.grab(i - 1) == '>'} {\r\n LArrowThick\r\n } elseIf {i - start == 1 && code.grab(i - 1) == '='} {\r\n LAssign\r\n } elseIf {i - start == 2 && code.grab(i - 2) == '+' && code.grab(i - 1) == '='} {\r\n LAssignPlus\r\n } elseIf {i - start == 2 && code.grab(i - 2) == '-' && code.grab(i - 1) == '='} {\r\n LAssignMinus\r\n } elseIf {i - start == 2 && code.grab(i - 2) == '*' && code.grab(i - 1) == '='} {\r\n LAssignMultiplication\r\n } elseIf {i - start == 2 && code.grab(i - 2) == '/' && code.grab(i - 1) == '='} {\r\n LAssignDivision\r\n } else {\r\n LOperator\r\n }\r\n\r\n emitToken(o, start, i)\r\n\r\n } elseIf {\r\n code.grab(i) == '(' || code.grab(i) == '[' || code.grab(i) == '{'\r\n } {\r\n\r\n i += 1\r\n emitToken(LBracketLeft, start, i)\r\n\r\n } elseIf {\r\n code.grab(i) == ')' || code.grab(i) == ']' || code.grab(i) == '}'\r\n } {\r\n\r\n i += 1\r\n emitToken(LBracketRight, start, i)\r\n\r\n } elseIf {\r\n i < code.size()\r\n } {\r\n\r\n if(attemptFixes) {i += 1} else:\r\n throwError(\"Unexpected character: \" + Show.show(code.grab(i)))\r\n\r\n }\r\n\r\n }\r\n } catch {| GrabException e, error =>\r\n throw(CompileError(Location(file, line, i - lineOffset), \"Unexpected end of file\"))\r\n }\r\n\r\n List.range(5).each {_ => emitToken(LEnd, i, i) }\r\n\r\n tokens.drain()\r\n\r\n}\r\n"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": [
4
- "../../../../../compiler/Unification.ff"
4
+ "../../../../compiler/Unification.ff"
5
5
  ],
6
6
  "sourcesContent": [
7
7
  "import Syntax\r\nimport Inference\r\n\r\nclass Unification(\r\n mutable substitution: Map[Int, Type]\r\n mutable constraints: Map[Int, Map[String, ConstraintGenerics]]\r\n mutable nextUnificationVariableIndex: Int\r\n mutable instances: Map[InstanceKey, InstanceValue]\r\n mutable affects: Map[Int, Set[Int]]\r\n attemptFixes: Bool\r\n)\r\n\r\ndata ConstraintGenerics(at: Location, generics: List[Type])\r\n\r\ndata InstanceKey(traitName: String, typeName: String)\r\n\r\ndata InstanceValue(\r\n generics: List[String]\r\n constraints: List[Constraint]\r\n moduleKey: ModuleKey\r\n traitName: String\r\n typeArguments: List[Type]\r\n)\r\n\r\nfail[T](at: Location, message: String): T {\r\n throw(CompileError(at, message))\r\n}\r\n\r\nnew(modules: List[Module], attemptFixes: Bool): Unification {\r\n\r\n Unification(\r\n Map.new()\r\n Map.new()\r\n 3 // To avoid collision with the parser and resolver\r\n modules.flatMap {module =>\r\n module.instances.map {definition =>\r\n let typeName = definition.typeArguments.grabFirst().{\r\n | TConstructor(_, name, _) => name\r\n | TVariable(_, i) => fail(definition.at, \"Unexpected unification variable: $\" + i)\r\n }\r\n Pair(\r\n InstanceKey(definition.traitName, typeName)\r\n InstanceValue(\r\n generics = definition.generics\r\n constraints = definition.constraints\r\n moduleKey = module.moduleKey\r\n traitName = definition.traitName\r\n typeArguments = definition.typeArguments\r\n )\r\n )\r\n }\r\n }.toMap()\r\n [].toMap()\r\n attemptFixes\r\n )\r\n}\r\n\r\nextend self: Unification {\r\n\r\n withLocalInstances[T](instances: Map[InstanceKey, InstanceValue], body: () => T): T {\r\n let oldInstances = self.instances\r\n self.instances = self.instances.addAll(instances)\r\n try {\r\n body()\r\n } finally {\r\n self.instances = oldInstances\r\n }\r\n }\r\n\r\n freshUnificationVariable(at: Location): Type {\r\n let result = TVariable(at, self.nextUnificationVariableIndex)\r\n self.nextUnificationVariableIndex += 3\r\n result\r\n }\r\n\r\n instantiate(instantiation: Map[String, Type], type: Type): Type {\r\n | _, TConstructor(at, name, []) =>\r\n instantiation.get(name).{\r\n | Some(t) => t\r\n | None => type\r\n }\r\n | _, TConstructor(at, name, generics) =>\r\n TConstructor(at, name, generics.map {self.instantiate(instantiation, _)})\r\n | _, TVariable(_, i) {self.get(i) | Some(t)} =>\r\n self.instantiate(instantiation, t)\r\n | _, TVariable(_, i) =>\r\n type\r\n }\r\n \r\n instantiateConstraint(instantiation: Map[String, Type], constraint: Constraint): Constraint {\r\n | _, Constraint(at, name, generics) =>\r\n Constraint(at, name, generics.map {self.instantiate(instantiation, _)})\r\n }\r\n\r\n constrain(at: Location, type: Type, constraintName: String, generics: List[Type]): Unit {\r\n type.{\r\n | TVariable(_, i) {self.get(i) | Some(t)} =>\r\n self.constrain(at, t, constraintName, generics)\r\n | TVariable(_, i) =>\r\n self.constraints.get(i).{\r\n | None =>\r\n self.constraints = self.constraints.add(\r\n i, [Pair(constraintName, ConstraintGenerics(at, generics))].toMap()\r\n )\r\n | Some(map) =>\r\n map.get(constraintName).{\r\n | None =>\r\n let newMap = map.add(constraintName, ConstraintGenerics(at, generics))\r\n self.constraints = self.constraints.add(i, newMap)\r\n | Some(ConstraintGenerics(_, generics2)) =>\r\n generics.zip(generics2).each {| Pair(t1, t2) => self.unify(at, t1, t2) }\r\n }\r\n }\r\n | TConstructor(_, name, generics2) =>\r\n self.instances.get(InstanceKey(constraintName, name)).{\r\n | None =>\r\n let g1 = if(generics.isEmpty()) {\"\"} else {\"[...]\"}\r\n let g2 = if(generics2.isEmpty()) {\"\"} else {\"[...]\"}\r\n if(!self.attemptFixes) {\r\n throw(CompileError(at, \"No such instance: \" + name + g2 + \": \" + constraintName + g1))\r\n }\r\n | Some(definition) =>\r\n let unificationVariables = definition.generics.map {_ => self.freshUnificationVariable(at) }\r\n let instantiation = definition.generics.zip(unificationVariables).toMap()\r\n let traitType1 = self.instantiate(instantiation,\r\n TConstructor(at, definition.traitName, definition.typeArguments)\r\n )\r\n let traitType2 = TConstructor(at, constraintName, [type, ...generics])\r\n self.unify(at, traitType1, traitType2)\r\n definition.constraints.each {constraint =>\r\n self.instantiateConstraint(instantiation, constraint).{\r\n | Constraint(_, constraintName, newGenerics) =>\r\n self.constrain(at, newGenerics.grabFirst(), constraintName, newGenerics.dropFirst())\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n get(index: Int): Option[Type] {\r\n self.substitution.get(index).map {\r\n | TVariable(_, i) {self.substitution.get(i) | Some(t)} =>\r\n self.substitution = self.substitution.add(index, t)\r\n t\r\n | t => t\r\n }\r\n }\r\n\r\n substitute(type: Type): Type {\r\n | TVariable(_, i) {self.get(i) | Some(t)} => self.substitute(t)\r\n | TVariable(_, _) => type\r\n | TConstructor t => t.TConstructor(generics = t.generics.map {g => self.substitute(g)})\r\n }\r\n\r\n unify(at: Location, t1: Type, t2: Type): Unit {\r\n | _, TVariable(_, i1), TVariable(_, i2) {i1 == i2} =>\r\n | _, TVariable(_, i), _ {self.get(i) | Some(t)} => self.unify(at, t, t2)\r\n | _, _, TVariable(_, i) {self.get(i) | Some(t)} => self.unify(at, t1, t)\r\n | _, TVariable(_, i), _ => self.bind(at, i, t2)\r\n | _, _, TVariable(_, i) => self.bind(at, i, t1)\r\n | _, TConstructor(_, name1, generics1), TConstructor(_, name2, generics2) =>\r\n if(name1 != name2 || generics1.size() != generics2.size()) {\r\n if(!self.attemptFixes) {\r\n let t3 = self.substitute(t1)\r\n let t4 = self.substitute(t2)\r\n throw(CompileError(at\r\n \"Type mismatch: \" + t3.show([t3, t4]) + \" vs. \" + t4.show([t3, t4])\r\n ))\r\n } elseIf {name1.startsWith(\"Function$\") && name2.startsWith(\"Function$\")} {\r\n generics1.dropLast().zip(generics2.dropLast()).each {| Pair(t3, t4) => self.unify(at, t3, t4)}\r\n generics1.takeLast().zip(generics2.takeLast()).each {| Pair(t3, t4) => self.unify(at, t3, t4)}\r\n }\r\n } else {\r\n generics1.zip(generics2).each {| Pair(t1, t2) => self.unify(at, t1, t2) }\r\n }\r\n }\r\n\r\n bind(at: Location, index: Int, type: Type): Unit {\r\n if(self.occursIn(index, type)) {\r\n let t = self.substitute(type)\r\n throw(CompileError(at, \"Infinite type: \" + TVariable(at, index).show([t]) + \" = \" + t.show([])))\r\n }\r\n self.substitution = self.substitution.add(index, type)\r\n self.constraints.get(index).each {map =>\r\n self.constraints = self.constraints.remove(index)\r\n map.pairs().each {| Pair(name, ConstraintGenerics(at2, generics)) =>\r\n self.constrain(at2, type, name, generics)\r\n }\r\n }\r\n self.affects.get(index).each {affected =>\r\n self.affects.remove(index)\r\n affected.each {i =>\r\n self.affect(at, type, TVariable(at, i))\r\n }\r\n }\r\n }\r\n\r\n affect(at: Location, source: Type, target: Type): Unit {\r\n Pair(self.substitute(source), self.substitute(target)).{\r\n | Pair(TVariable(_, i1), TVariable(_, i2)) =>\r\n let is = self.affects.get(i1).else([].toSet)\r\n self.affects = self.affects.add(i1, is.add(i2))\r\n | Pair(_, TConstructor(_, \"Q$\", _)) =>\r\n | Pair(TConstructor(_, \"ff:core/Nothing.Nothing\", _), _) =>\r\n | Pair(t1, t2) =>\r\n self.unify(at, t1, t2)\r\n }\r\n }\r\n\r\n occursIn(index: Int, t: Type): Bool {\r\n | _, TVariable(_, i) {self.get(i) | Some(type)} => self.occursIn(index, type)\r\n | _, TVariable(_, i) => i == index\r\n | _, TConstructor(_, _, generics) => generics.any {t => self.occursIn(index, t)}\r\n }\r\n \r\n}\r\n"