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
@@ -0,0 +1,162 @@
1
+ import Tcp
2
+
3
+ capability TcpServer(
4
+ system: NodeSystem
5
+ jsValue: JsValue
6
+ host: Option[String]
7
+ port: Option[Int]
8
+ path: Option[String]
9
+ backlog: Int
10
+ exclusive: Bool
11
+ ipv6Only: Bool
12
+ reusePort: Bool
13
+ readableAll: Bool
14
+ writeableAll: Bool
15
+ )
16
+
17
+ capability TcpSocket(system: NodeSystem, jsValue: JsValue)
18
+
19
+ new(
20
+ system: NodeSystem
21
+ port: Int // TODO
22
+ ): TcpSocket {
23
+ let net = Js.import("node:net")
24
+ let jsValue = net->createConnection(Js->(
25
+ port = port
26
+ ))
27
+ TcpSocket(system, jsValue)
28
+ }
29
+
30
+ newServer(
31
+ system: NodeSystem
32
+ host: Option[String] = None
33
+ port: Option[Int] = None
34
+ path: Option[String] = None
35
+ exclusive: Bool = False
36
+ allowHalfOpen: Bool = False
37
+ highWaterMark: Int = 65536
38
+ keepAlive: Bool = False
39
+ noDelay: Bool = False
40
+ backlog: Int = 511
41
+ ipv6Only: Bool = False
42
+ reusePort: Bool = False
43
+ readableAll: Bool = False
44
+ writeableAll: Bool = False
45
+ ): TcpServer {
46
+ let net = Js.import("node:net")
47
+ let jsValue = net->createServer(Js->(
48
+ allowHalfOpen = allowHalfOpen
49
+ highWaterMark = highWaterMark
50
+ keepAlive = keepAlive
51
+ noDelay = noDelay
52
+ ))
53
+ TcpServer(system, jsValue, host, port, path, backlog, exclusive, ipv6Only, reusePort, readableAll, writeableAll)
54
+ }
55
+
56
+ extend self: TcpServer {
57
+
58
+ listen(body: TcpSocket => Unit) {
59
+ Js.withSignal {signal =>
60
+ self.jsValue->listen(Js->(
61
+ host = Js.orUndefined(self.host)
62
+ port = Js.orUndefined(self.port)
63
+ path = Js.orUndefined(self.path)
64
+ backlog = self.backlog
65
+ exclusive = self.exclusive
66
+ ipv6Only = self.ipv6Only
67
+ reusePort = self.reusePort
68
+ readableAll = self.readableAll
69
+ writeableAll = self.writeableAll
70
+ signal = signal
71
+ ))
72
+ Js.awaitCancellablePromise {resolve, reject, cleanup =>
73
+ self.jsValue->on("connection", Js->{jsSocket =>
74
+ jsSocket->on("error", Js->{jsError =>
75
+ jsSocket->destroySoon()
76
+ reject(jsError?)
77
+ })
78
+ try {
79
+ body(TcpSocket(self.system, jsSocket))
80
+ } tryFinally {
81
+ jsSocket->destroySoon()
82
+ } catchAny {error =>
83
+ reject(error)
84
+ }
85
+ })
86
+ self.jsValue->on("close", Js->{
87
+ resolve(Unit)
88
+ })
89
+ self.jsValue->on("error", Js->{jsError =>
90
+ reject(jsError?)
91
+ })
92
+ }
93
+ }
94
+ }
95
+
96
+ close() {
97
+ Js.await(self.jsValue->close())
98
+ }
99
+
100
+ }
101
+
102
+ extend self: TcpSocket {
103
+
104
+ readStream(): Stream[Buffer] {
105
+ Path.internalReadStream({self.jsValue}, close = False)
106
+ }
107
+
108
+ writeStream(stream: Stream[Buffer]) {
109
+ stream.each {self.writeBuffer(_)}
110
+ }
111
+
112
+ writeBuffer(buffer: Buffer): Unit {
113
+ if(!self.jsValue->write(Js->Uint8Array->(buffer!->buffer, buffer!->byteOffset, buffer!->byteLength))?) {
114
+ Js.withSignal {signal =>
115
+ Js.await(Js->Promise->(Js->{resolve, reject =>
116
+ let jsDoReject = Js->{_ => reject->callValue1(signal->reason?)}
117
+ signal->addEventListener("abort", jsDoReject)
118
+ self.jsValue->once("drain", Js->{
119
+ signal->removeEventListener("abort", jsDoReject)
120
+ resolve.callValue0()
121
+ })
122
+ }))
123
+ }
124
+ }
125
+ }
126
+
127
+ writeText(text: String): Unit {
128
+ self.writeBuffer(text.toBuffer())
129
+ }
130
+
131
+ writeLine(text: String): Unit {
132
+ self.writeText(text + "\n")
133
+ }
134
+
135
+ }
136
+
137
+ nodeMain(system: NodeSystem) {
138
+ let targetSocket = Tcp.new(system, 8080)
139
+ Tcp.newServer(system, port = Some(8081)).listen {socket =>
140
+ system.writeLine("Connected!")
141
+ system.mainTask().all([
142
+ {
143
+ try {
144
+ targetSocket.writeStream(socket.readStream())
145
+ } catchAny {error =>
146
+
147
+ }
148
+ }
149
+ {
150
+ try {
151
+ socket.writeStream(targetSocket.readStream())
152
+ } catchAny {error =>
153
+
154
+ }
155
+ }
156
+ ])
157
+ system.writeLine("Disconnected!")
158
+ }
159
+ system.writeLine("Done!")
160
+ }
161
+
162
+
@@ -0,0 +1,18 @@
1
+ nodeMain(system: NodeSystem) {
2
+ let lines = system.readStream().toString().lines()
3
+ lines.{
4
+ | [line, ""] {line.split(' ') | [digits, times]} =>
5
+ mutable result = digits.repeat(times.grabInt()).grabInt()
6
+ while {result >= 10} {
7
+ let newDigits = "" + result
8
+ result = 0
9
+ newDigits.each {digit =>
10
+ result += digit.toString().grabInt()
11
+ }
12
+ }
13
+ system.writeLine(Show.show(result))
14
+ | _ =>
15
+ system.writeErrorLine("Unexpected input: " + Show.show(lines))
16
+ }
17
+ }
18
+
@@ -0,0 +1,40 @@
1
+ dependency ff:webserver:0.0.0
2
+ import WebServer from ff:webserver
3
+ import Terrain2
4
+
5
+ browserMain(system: BrowserSystem): Unit {
6
+ let document = system.js()->document
7
+ let canvas = document->createElement("canvas")
8
+ canvas->width = "256"
9
+ canvas->height = "256"
10
+ canvas->style->scale = "3"
11
+ canvas->style->position = "absolute"
12
+ canvas->style->top = "calc(50% - 256px / 2)"
13
+ canvas->style->left = "calc(50% - 256px / 2)"
14
+ canvas->style->"image-rendering" = "pixelated"
15
+ document->body->appendChild(canvas)
16
+ document->body->parentElement->style->background = "#000000"
17
+ let context = canvas->getContext("2d")
18
+ Terrain2.generateAndDraw(system, context)
19
+ }
20
+
21
+ nodeMain(system: NodeSystem): Unit {
22
+ WebServer.new(system, "localhost", 8080).listen {request =>
23
+ if(request.readPath() == "/") {
24
+ request.writeHeader("Content-Type", "text/html; charset=UTF-8")
25
+ request.writeText("<!doctype html>")
26
+ request.writeText("<script type='module' src='/js/script/script/Main.run.mjs'></script>")
27
+ } elseIf {request.readPath().startsWith("/js/") && !request.readPath().contains("..")} {
28
+ request.writeHeader("Content-Type", "text/javascript; charset=UTF-8")
29
+ request.writeText(system.assets().readText(request.readPath()))
30
+ } else {
31
+ request.writeStatus("404 Not found")
32
+ }
33
+ }
34
+ }
35
+
36
+ buildMain(system: BuildSystem) {
37
+ let browserAssets = system.compileForBrowser(["Main.ff"])
38
+ let assets = AssetSystem.create().addAssets("/js", browserAssets)
39
+ system.setAssets(assets)
40
+ }
@@ -0,0 +1,97 @@
1
+ generateAndDraw(context: JsValue) {
2
+ let imageData = context->createImageData(width, height)
3
+ generate(imageData->data, 123, 1000)
4
+ render(imageData->data)
5
+ context->putImageData(imageData, 0, 0)
6
+ }
7
+
8
+ generate(data: JsValue, seed: Int, iterations: Int) {
9
+ initialize(data)
10
+ let directionsX = [-1, -1, -1, 1, 1, 1, 0, 0]
11
+ let directionsY = [-1, 0, 1, -1, 0, 1, -1, 1]
12
+ let random = Random.newFromInt(seed)
13
+ 0.until(iterations).each {iteration =>
14
+ mutable i = 0
15
+ 0.until(height).each {y =>
16
+ 0.until(width).each {x =>
17
+ mutable bestDirection = random.nextInt(0, 8)
18
+ mutable bestDifference = 0
19
+ 0.until(8).each {direction =>
20
+ let myWater: Int = data.get(i + 2)?
21
+ let myGround: Int = data.get(i + 1)?
22
+ let myZ = myGround + myWater
23
+ let theirX = (width + x + directionsX.grab(direction)) % width
24
+ let theirY = (height + y + directionsY.grab(direction)) % height
25
+ let theirI = 4 * (theirX + width * theirY)
26
+ let theirWater: Int = data.get(theirI + 2)?
27
+ let theirGround: Int = data.get(theirI + 1)?
28
+ let theirZ = theirGround + theirWater
29
+ if(myZ - theirZ > bestDifference) {
30
+ bestDifference = myZ - theirZ
31
+ bestDirection = direction
32
+ }
33
+ }
34
+ let myWater: Int = data.get(i + 2)?
35
+ let myGround: Int = data.get(i + 1)?
36
+ let myZ = myGround + myWater
37
+ let theirX = (width + x + directionsX.grab(bestDirection)) % width
38
+ let theirY = (height + y + directionsY.grab(bestDirection)) % height
39
+ let theirI = 4 * (theirX + width * theirY)
40
+ let theirWater: Int = data.get(theirI + 2)?
41
+ let theirGround: Int = data.get(theirI + 1)?
42
+ let theirZ = theirGround + theirWater
43
+ if(myZ > theirZ) {
44
+ let w = (myZ - theirZ).max(0).min(myWater).div(2)
45
+ let g = (myGround - theirGround).div(4)
46
+ data.set(i + 1, myGround - g)
47
+ data.set(i + 2, myWater - w)
48
+ data.set(theirI + 2, theirWater + w)
49
+ }
50
+ i += 4
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ initialize(data: JsValue) {
57
+ let random = Random.newFromInt(12345)
58
+ mutable i = 0
59
+ 0.until(height).each {y =>
60
+ 0.until(width).each {x =>
61
+ //data.set(i, random.nextInt(0, 5) * random.nextInt(0, 5) * random.nextInt(0, 5) * random.nextInt(0, 4))
62
+ i += 1
63
+ data.set(i, if(x < 100 || y < 100) {0} else {random.nextInt(200, 255)})
64
+ i += 1
65
+ data.set(i, if(x < 100 || y < 100) {0} else {255})
66
+ i += 1
67
+ data.set(i, 255)
68
+ i += 1
69
+ }
70
+ }
71
+ }
72
+
73
+ render(data: JsValue) {
74
+ mutable i = 0
75
+ 0.until(height).each {y =>
76
+ mutable light = 0
77
+ 0.until(width).each {x =>
78
+ let sea: Int = data.get(i + 0)?
79
+ let ground: Int = data.get(i + 1)?
80
+ let water: Int = data.get(i + 2)?
81
+ if(ground > light) {light = ground} else {light -= 2}
82
+ //data.set(i, if(water < 100) {100 - (water - 100) * 15} else {0})
83
+ data.set(i, 0)
84
+ i += 1
85
+ data.set(i, ground) // if(ground < waterLevel) {0} else {ground})
86
+ i += 1
87
+ data.set(i, 0)
88
+ i += 1
89
+ let l = if(ground >= light) {255} else {255 - (light - ground) * 10}
90
+ //data.set(i, l)
91
+ i += 1
92
+ }
93
+ }
94
+ }
95
+
96
+ width: Int = 256
97
+ height: Int = 256
@@ -0,0 +1,109 @@
1
+ generateAndDraw(system: BrowserSystem, context: JsValue) {
2
+ let imageData = context->createImageData(width, height)
3
+ let renderData = context->createImageData(width, height)
4
+ initialize(imageData->data)
5
+ let random = Random.newFromInt(123)
6
+ 0.until(10).each {_ =>
7
+ 0.until(10).each {_ =>
8
+ generate(imageData->data, random)
9
+ }
10
+ render(renderData->data, imageData->data)
11
+ context->putImageData(imageData, 0, 0)
12
+ system.mainTask().sleep(Duration(0.0))
13
+ }
14
+ }
15
+
16
+ generate(data: JsValue, random: Random) {
17
+ let directionsX = [-1, -1, -1, 1, 1, 1, 0, 0]
18
+ let directionsY = [-1, 0, 1, -1, 0, 1, -1, 1]
19
+ mutable i = 0
20
+ 0.until(height).each {y =>
21
+ 0.until(width).each {x =>
22
+ mutable bestDirection = random.nextInt(0, 8)
23
+ mutable bestDelta = 0
24
+ 0.until(8).each {direction =>
25
+ let myGround: Int = data.get(i + 1)?
26
+ let myWater: Int = data.get(i + 2)?
27
+ let myZ = myGround + myWater
28
+ let theirX = (width + x + directionsX.grab(direction)) % width
29
+ let theirY = (height + y + directionsY.grab(direction)) % height
30
+ let theirI = 4 * (theirX + width * theirY)
31
+ let theirGround: Int = data.get(theirI + 1)?
32
+ let theirWater: Int = data.get(theirI + 2)?
33
+ let theirZ = theirGround + theirWater
34
+ let delta = myZ - theirZ
35
+ if(delta > bestDelta) {
36
+ bestDelta = delta
37
+ bestDirection = direction
38
+ }
39
+ if(myGround > theirGround + 10) {
40
+ data.set(i + 1, myGround - 1)
41
+ data.set(theirI + 1, theirGround + 1)
42
+ }
43
+ }
44
+ let myGround: Int = data.get(i + 1)?
45
+ let myWater: Int = data.get(i + 2)?
46
+ let theirX = (width + x + directionsX.grab(bestDirection)) % width
47
+ let theirY = (height + y + directionsY.grab(bestDirection)) % height
48
+ let theirI = 4 * (theirX + width * theirY)
49
+ let theirGround: Int = data.get(theirI + 1)?
50
+ let theirWater: Int = data.get(theirI + 2)?
51
+ if(bestDelta != 0 && myWater > 0) {
52
+ if(bestDelta <= 2 && random.nextBool()) {
53
+ data.set(i + 1, myGround - 1)
54
+ data.set(theirI + 1, theirGround - 1)
55
+ }
56
+ data.set(i + 2, myWater - 1)
57
+ data.set(theirI + 2, theirWater + 1)
58
+ }
59
+ if(random.nextBool()) {
60
+ data.set(i + 2, data.get(i + 2)? + 1)
61
+ }
62
+ i += 4
63
+ }
64
+ }
65
+ }
66
+
67
+ initialize(data: JsValue) {
68
+ let random = Random.newFromInt(12345)
69
+ mutable i = 0
70
+ 0.until(height).each {y =>
71
+ 0.until(width).each {x =>
72
+ let cx = x - width.div(2)
73
+ let cy = y - height.div(2)
74
+ let m = 255 - (cx * cx + cy * cy).toFloat().sqrt().toInt()
75
+ data.set(i, 0)
76
+ i += 1
77
+ data.set(i, m + random.nextInt(0, 8))
78
+ i += 1
79
+ data.set(i, 0)
80
+ i += 1
81
+ data.set(i, 255)
82
+ i += 1
83
+ }
84
+ }
85
+ }
86
+
87
+ render(target: JsValue, data: JsValue) {
88
+ mutable i = 0
89
+ 0.until(height).each {y =>
90
+ mutable light = 0
91
+ 0.until(width).each {x =>
92
+ let ground: Int = data.get(i + 1)?
93
+ let water: Int = data.get(i + 2)?
94
+ if(ground > light) {light = ground} else {light -= 1}
95
+ target.set(i, ground + ground - 128)
96
+ i += 1
97
+ target.set(i, ground)
98
+ i += 1
99
+ target.set(i, if(water > 70) {water + 100} else {water})
100
+ i += 1
101
+ let l = if(ground >= light) {255} else {255 - (light - ground) * 5}
102
+ target.set(i, l)
103
+ i += 1
104
+ }
105
+ }
106
+ }
107
+
108
+ width: Int = 256
109
+ height: Int = 256
@@ -18,7 +18,6 @@ nodeMain(system: NodeSystem): Unit {
18
18
  let handlers = WebRouteHandler(Array.new())
19
19
  Router.handlers(handlers)
20
20
  let cacheSalt = system.crypto().randomBuffer(16)
21
- system.writeLine("Listening on " + host + ":" + port)
22
21
  WebServer.new(system, host, port).listen {request =>
23
22
  let path = request.readPath()
24
23
  let segments = path.split('/').filter {s => s != "" && s != "." && s != ".."}
@@ -6,7 +6,7 @@ When `;` is the last token on a line, it can be omitted.
6
6
 
7
7
  A statement is either a [local function definition](functions-and-methods), a local variable definition, an assignment or an expression.
8
8
 
9
- Field assignments were covered in [user defined types](user-defined types).
9
+ Field assignments were covered in [user defined types](user-defined-types).
10
10
 
11
11
 
12
12
  # Local variables
@@ -861,12 +861,12 @@ toplevelCompletion(lspHook: LspHook): List[CompletionInfo] {
861
861
  "import WebServer from ff:webserver"
862
862
  ""
863
863
  "browserMain(system: BrowserSystem): Unit {"
864
- " let message = system.httpClient().get(\"http://localhost:8080/hello\", []) {_.readText()}"
864
+ " let message = system.httpClient().get(\"/hello\", []) {_.readText()}"
865
865
  " system.js()->alert(message)"
866
866
  "}"
867
867
  ""
868
868
  "nodeMain(system: NodeSystem): Unit {"
869
- " WebServer.make(system, \"localhost\", 8080).listen {request =>"
869
+ " WebServer.new(system, \"localhost\", 8080).listen {request =>"
870
870
  " if(request.readPath() == \"/\") {"
871
871
  " request.writeHeader(\"Content-Type\", \"text/html; charset=UTF-8\")"
872
872
  " request.writeText(\"<!doctype html>\")"
@@ -121,42 +121,28 @@ export function PackageFiles(root_, packageFile_, files_) {
121
121
  return {root_, packageFile_, files_};
122
122
  }
123
123
 
124
- export function build_(system_, emitTarget_, mainModules_, resolvedDependencies_, compilerModulePath_, tempPath_, jsOutputPath_, printMeasurements_, moduleCache_) {
125
- if(ff_core_Path.Path_exists(tempPath_, false, false, false)) {
126
- ff_core_Path.Path_delete(tempPath_, 0, 100)
127
- };
128
- ff_core_Path.Path_createDirectory(tempPath_, false);
129
- const jsPathFile_ = ff_core_Path.Path_slash(tempPath_, "js");
130
- ff_core_Path.Path_createDirectory(jsPathFile_, true);
131
- const success_ = ff_core_Core.do_((() => {
132
- const compiler_ = ff_compiler_Compiler.new_(emitTarget_, ff_core_NodeSystem.NodeSystem_mainTask(system_), compilerModulePath_, jsPathFile_, resolvedDependencies_, ff_core_Map.new_(), moduleCache_, ff_compiler_LspHook.disabled_());
124
+ export function build_(system_, emitTarget_, mainModules_, resolvedDependencies_, compilerModulePath_, jsOutputPath_, printMeasurements_, moduleCache_) {
125
+ ff_core_Path.Path_createDirectory(jsOutputPath_, true);
126
+ const compiler_ = ff_compiler_Compiler.new_(emitTarget_, ff_core_NodeSystem.NodeSystem_mainTask(system_), compilerModulePath_, jsOutputPath_, resolvedDependencies_, ff_core_Map.new_(), moduleCache_, ff_compiler_LspHook.disabled_());
133
127
  for(let for_a = mainModules_, for_i = 0, for_l = for_a.length; for_i < for_l; for_i++) {
134
128
  const moduleKey_ = for_a[for_i];
135
129
  ff_compiler_Compiler.Compiler_emit(compiler_, moduleKey_, true)
136
130
  };
137
131
  if(printMeasurements_) {
138
- ff_compiler_Compiler.Compiler_printMeasurements(compiler_)
132
+ ff_compiler_Compiler.Compiler_printMeasurementsPerPhase(compiler_)
139
133
  };
140
134
  ff_core_Map.Map_each(resolvedDependencies_.packagePaths_, ((packagePair_, packagePath_) => {
141
135
  {
142
136
  const if_o = ff_core_Map.Map_get(resolvedDependencies_.packages_, packagePair_, ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair)
143
137
  if(if_o.Some) {
144
138
  const packageInfo_ = if_o.value_;
145
- ff_compiler_Builder.processNodeModules_(system_, jsPathFile_, packagePath_, packageInfo_);
139
+ ff_compiler_Builder.processNodeModules_(system_, jsOutputPath_, packagePath_, packageInfo_);
146
140
  if(ff_core_Equal.notEquals_(emitTarget_, ff_compiler_JsEmitter.EmitBrowser(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget)) {
147
- ff_compiler_Builder.processIncludes_(jsPathFile_, packagePath_, packageInfo_)
141
+ ff_compiler_Builder.processIncludes_(jsOutputPath_, packagePath_, packageInfo_)
148
142
  }
149
143
  }
150
144
  }
151
- }), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair);
152
- return true
153
- }));
154
- if(success_) {
155
- if(ff_core_Path.Path_exists(jsOutputPath_, false, false, false)) {
156
- ff_core_Path.Path_delete(jsOutputPath_, 0, 100)
157
- };
158
- ff_core_Path.Path_renameTo(jsPathFile_, jsOutputPath_)
159
- }
145
+ }), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair)
160
146
  }
161
147
 
162
148
  export function processIncludes_(jsPathFile_, packagePath_, info_) {
@@ -164,9 +150,11 @@ for(let for_a = info_.includes_, for_i = 0, for_l = for_a.length; for_i < for_l;
164
150
  const include_ = for_a[for_i];
165
151
  const fromPath_ = ff_core_Path.Path_slash(ff_core_Path.Path_slash(ff_core_Path.Path_slash(packagePath_, ".firefly"), "include"), include_.path_);
166
152
  const toPath_ = ff_core_Path.Path_slash(ff_core_Path.Path_slash(jsPathFile_, ff_compiler_Syntax.PackagePair_groupName(info_.package_.packagePair_, "/")), include_.path_);
153
+ if((!ff_core_Path.Path_exists(toPath_, false, false, false))) {
167
154
  ff_core_Path.Path_createSymlinkTo(toPath_, fromPath_, true)
168
155
  }
169
156
  }
157
+ }
170
158
 
171
159
  export function processNodeModules_(system_, jsPathFile_, packagePath_, info_) {
172
160
  if(ff_core_List.List_any(info_.includes_, ((_w1) => {
@@ -177,7 +165,7 @@ const nodeModules_ = ff_core_Path.Path_slash(includePath_, "node_modules");
177
165
  const packageJson_ = ff_core_Path.Path_slash(includePath_, "package.json");
178
166
  if(((!ff_core_Path.Path_exists(nodeModules_, false, false, false)) && ff_core_Path.Path_exists(packageJson_, false, false, false))) {
179
167
  ff_core_NodeSystem.NodeSystem_writeErrorLine(system_, ("Running npm install --no-bin-links in " + ff_core_Path.Path_absolute(includePath_)));
180
- const result_ = ff_core_NodeSystem.NodeSystem_execute(system_, "npm", ["install", "--no-bin-links"], ff_core_Buffer.new_(0, false), ff_core_Option.Some(includePath_), ff_core_Option.None(), 16777216, 9, true);
168
+ const result_ = ff_core_NodeSystem.NodeSystem_execute(system_, "npm", ["install", "--no-bin-links"], ff_core_Buffer.new_(0, false), ff_core_Option.Some(includePath_), ff_core_Option.None(), 16777216, 9, true, ff_core_Option.None());
181
169
  if((result_.exitCode_ !== 0)) {
182
170
  ff_core_NodeSystem.NodeSystem_writeErrorLine(system_, (("Running npm failed with exit code " + result_.exitCode_) + ":"));
183
171
  ff_core_NodeSystem.NodeSystem_writeErrorBuffer(system_, result_.standardOut_);
@@ -187,7 +175,7 @@ ff_core_NodeSystem.NodeSystem_writeErrorBuffer(system_, result_.standardError_)
187
175
  }
188
176
  }
189
177
 
190
- export function buildViaBuildSystem_(system_, fireflyPath_, mainFiles_, target_) {
178
+ export function buildViaBuildSystem_(system_, fireflyPath_, mainFiles_, target_, moduleCache_ = ff_compiler_ModuleCache.new_(0), printMeasurements_ = false) {
191
179
  const resolvedDependencies_ = ff_compiler_Dependencies.process_(ff_core_NodeSystem.NodeSystem_httpClient(system_), ff_compiler_DependencyLock.new_(ff_core_NodeSystem.NodeSystem_mainTask(system_)), ff_core_List.List_grabFirst(mainFiles_));
192
180
  const fixedPackagePaths_ = (ff_core_Map.Map_contains(resolvedDependencies_.packagePaths_, ff_compiler_Syntax.PackagePair("ff", "core"), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair)
193
181
  ? resolvedDependencies_.packagePaths_
@@ -203,7 +191,7 @@ ff_core_Core.panic_("buildViaBuildSystem is currently limited to browser target
203
191
  };
204
192
  ff_compiler_Builder.build_(system_, ff_compiler_JsEmitter.EmitBrowser(), mainModuleKeys_, (((_c) => {
205
193
  return ff_compiler_Dependencies.ResolvedDependencies(_c.mainPackagePair_, _c.packages_, fixedPackagePaths_, _c.singleFilePackages_)
206
- }))(resolvedDependencies_), ff_core_Option.None(), ff_core_NodeSystem.NodeSystem_path(system_, ".firefly/temporary"), ff_core_Path.Path_slash(ff_core_NodeSystem.NodeSystem_path(system_, ".firefly/output"), target_), false, ff_compiler_ModuleCache.new_(0))
194
+ }))(resolvedDependencies_), ff_core_Option.None(), ff_core_Path.Path_slash(ff_core_NodeSystem.NodeSystem_path(system_, ".firefly/output"), target_), printMeasurements_, moduleCache_)
207
195
  }
208
196
 
209
197
  export function check_(system_, fireflyPath_, path_, mustContain_, skipFiles_, virtualFiles_, cache_, dependencyLock_, newVersion_, lspHook_, infer_) {
@@ -387,42 +375,28 @@ const pkg_ = null;
387
375
  pkg_.exec([packageFile_.absolutePath_, "--out-path", outputPath_.absolutePath_, "--target", ff_core_List.List_join(targets_, ",")])
388
376
  }
389
377
 
390
- export async function build_$(system_, emitTarget_, mainModules_, resolvedDependencies_, compilerModulePath_, tempPath_, jsOutputPath_, printMeasurements_, moduleCache_, $task) {
391
- if((await ff_core_Path.Path_exists$(tempPath_, false, false, false, $task))) {
392
- (await ff_core_Path.Path_delete$(tempPath_, 0, 100, $task))
393
- };
394
- (await ff_core_Path.Path_createDirectory$(tempPath_, false, $task));
395
- const jsPathFile_ = (await ff_core_Path.Path_slash$(tempPath_, "js", $task));
396
- (await ff_core_Path.Path_createDirectory$(jsPathFile_, true, $task));
397
- const success_ = (await ff_core_Core.do_$((async ($task) => {
398
- const compiler_ = (await ff_compiler_Compiler.new_$(emitTarget_, (await ff_core_NodeSystem.NodeSystem_mainTask$(system_, $task)), compilerModulePath_, jsPathFile_, resolvedDependencies_, ff_core_Map.new_(), moduleCache_, ff_compiler_LspHook.disabled_(), $task));
378
+ export async function build_$(system_, emitTarget_, mainModules_, resolvedDependencies_, compilerModulePath_, jsOutputPath_, printMeasurements_, moduleCache_, $task) {
379
+ (await ff_core_Path.Path_createDirectory$(jsOutputPath_, true, $task));
380
+ const compiler_ = (await ff_compiler_Compiler.new_$(emitTarget_, (await ff_core_NodeSystem.NodeSystem_mainTask$(system_, $task)), compilerModulePath_, jsOutputPath_, resolvedDependencies_, ff_core_Map.new_(), moduleCache_, ff_compiler_LspHook.disabled_(), $task));
399
381
  for(let for_a = mainModules_, for_i = 0, for_l = for_a.length; for_i < for_l; for_i++) {
400
382
  const moduleKey_ = for_a[for_i];
401
383
  (await ff_compiler_Compiler.Compiler_emit$(compiler_, moduleKey_, true, $task))
402
384
  };
403
385
  if(printMeasurements_) {
404
- (await ff_compiler_Compiler.Compiler_printMeasurements$(compiler_, $task))
386
+ (await ff_compiler_Compiler.Compiler_printMeasurementsPerPhase$(compiler_, $task))
405
387
  };
406
388
  (await ff_core_Map.Map_each$(resolvedDependencies_.packagePaths_, (async (packagePair_, packagePath_, $task) => {
407
389
  {
408
390
  const if_o = ff_core_Map.Map_get(resolvedDependencies_.packages_, packagePair_, ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair)
409
391
  if(if_o.Some) {
410
392
  const packageInfo_ = if_o.value_;
411
- (await ff_compiler_Builder.processNodeModules_$(system_, jsPathFile_, packagePath_, packageInfo_, $task));
393
+ (await ff_compiler_Builder.processNodeModules_$(system_, jsOutputPath_, packagePath_, packageInfo_, $task));
412
394
  if(ff_core_Equal.notEquals_(emitTarget_, ff_compiler_JsEmitter.EmitBrowser(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget)) {
413
- (await ff_compiler_Builder.processIncludes_$(jsPathFile_, packagePath_, packageInfo_, $task))
395
+ (await ff_compiler_Builder.processIncludes_$(jsOutputPath_, packagePath_, packageInfo_, $task))
414
396
  }
415
397
  }
416
398
  }
417
- }), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair, $task));
418
- return true
419
- }), $task));
420
- if(success_) {
421
- if((await ff_core_Path.Path_exists$(jsOutputPath_, false, false, false, $task))) {
422
- (await ff_core_Path.Path_delete$(jsOutputPath_, 0, 100, $task))
423
- };
424
- (await ff_core_Path.Path_renameTo$(jsPathFile_, jsOutputPath_, $task))
425
- }
399
+ }), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair, $task))
426
400
  }
427
401
 
428
402
  export async function processIncludes_$(jsPathFile_, packagePath_, info_, $task) {
@@ -430,9 +404,11 @@ for(let for_a = info_.includes_, for_i = 0, for_l = for_a.length; for_i < for_l;
430
404
  const include_ = for_a[for_i];
431
405
  const fromPath_ = (await ff_core_Path.Path_slash$((await ff_core_Path.Path_slash$((await ff_core_Path.Path_slash$(packagePath_, ".firefly", $task)), "include", $task)), include_.path_, $task));
432
406
  const toPath_ = (await ff_core_Path.Path_slash$((await ff_core_Path.Path_slash$(jsPathFile_, ff_compiler_Syntax.PackagePair_groupName(info_.package_.packagePair_, "/"), $task)), include_.path_, $task));
407
+ if((!(await ff_core_Path.Path_exists$(toPath_, false, false, false, $task)))) {
433
408
  (await ff_core_Path.Path_createSymlinkTo$(toPath_, fromPath_, true, $task))
434
409
  }
435
410
  }
411
+ }
436
412
 
437
413
  export async function processNodeModules_$(system_, jsPathFile_, packagePath_, info_, $task) {
438
414
  if(ff_core_List.List_any(info_.includes_, ((_w1) => {
@@ -443,7 +419,7 @@ const nodeModules_ = (await ff_core_Path.Path_slash$(includePath_, "node_modules
443
419
  const packageJson_ = (await ff_core_Path.Path_slash$(includePath_, "package.json", $task));
444
420
  if(((!(await ff_core_Path.Path_exists$(nodeModules_, false, false, false, $task))) && (await ff_core_Path.Path_exists$(packageJson_, false, false, false, $task)))) {
445
421
  (await ff_core_NodeSystem.NodeSystem_writeErrorLine$(system_, ("Running npm install --no-bin-links in " + (await ff_core_Path.Path_absolute$(includePath_, $task))), $task));
446
- const result_ = (await ff_core_NodeSystem.NodeSystem_execute$(system_, "npm", ["install", "--no-bin-links"], ff_core_Buffer.new_(0, false), ff_core_Option.Some(includePath_), ff_core_Option.None(), 16777216, 9, true, $task));
422
+ const result_ = (await ff_core_NodeSystem.NodeSystem_execute$(system_, "npm", ["install", "--no-bin-links"], ff_core_Buffer.new_(0, false), ff_core_Option.Some(includePath_), ff_core_Option.None(), 16777216, 9, true, ff_core_Option.None(), $task));
447
423
  if((result_.exitCode_ !== 0)) {
448
424
  (await ff_core_NodeSystem.NodeSystem_writeErrorLine$(system_, (("Running npm failed with exit code " + result_.exitCode_) + ":"), $task));
449
425
  (await ff_core_NodeSystem.NodeSystem_writeErrorBuffer$(system_, result_.standardOut_, $task));
@@ -453,7 +429,7 @@ if((result_.exitCode_ !== 0)) {
453
429
  }
454
430
  }
455
431
 
456
- export async function buildViaBuildSystem_$(system_, fireflyPath_, mainFiles_, target_, $task) {
432
+ export async function buildViaBuildSystem_$(system_, fireflyPath_, mainFiles_, target_, moduleCache_ = ff_compiler_ModuleCache.new_(0), printMeasurements_ = false, $task) {
457
433
  const resolvedDependencies_ = (await ff_compiler_Dependencies.process_$((await ff_core_NodeSystem.NodeSystem_httpClient$(system_, $task)), (await ff_compiler_DependencyLock.new_$((await ff_core_NodeSystem.NodeSystem_mainTask$(system_, $task)), $task)), ff_core_List.List_grabFirst(mainFiles_), $task));
458
434
  const fixedPackagePaths_ = (ff_core_Map.Map_contains(resolvedDependencies_.packagePaths_, ff_compiler_Syntax.PackagePair("ff", "core"), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair)
459
435
  ? resolvedDependencies_.packagePaths_
@@ -469,7 +445,7 @@ ff_core_Core.panic_("buildViaBuildSystem is currently limited to browser target
469
445
  };
470
446
  (await ff_compiler_Builder.build_$(system_, ff_compiler_JsEmitter.EmitBrowser(), mainModuleKeys_, (((_c) => {
471
447
  return ff_compiler_Dependencies.ResolvedDependencies(_c.mainPackagePair_, _c.packages_, fixedPackagePaths_, _c.singleFilePackages_)
472
- }))(resolvedDependencies_), ff_core_Option.None(), (await ff_core_NodeSystem.NodeSystem_path$(system_, ".firefly/temporary", $task)), (await ff_core_Path.Path_slash$((await ff_core_NodeSystem.NodeSystem_path$(system_, ".firefly/output", $task)), target_, $task)), false, ff_compiler_ModuleCache.new_(0), $task))
448
+ }))(resolvedDependencies_), ff_core_Option.None(), (await ff_core_Path.Path_slash$((await ff_core_NodeSystem.NodeSystem_path$(system_, ".firefly/output", $task)), target_, $task)), printMeasurements_, moduleCache_, $task))
473
449
  }
474
450
 
475
451
  export async function check_$(system_, fireflyPath_, path_, mustContain_, skipFiles_, virtualFiles_, cache_, dependencyLock_, newVersion_, lspHook_, infer_, $task) {