firefly-compiler 0.4.31 → 0.4.33

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 (91) hide show
  1. package/bin/Release.ff +6 -0
  2. package/compiler/Builder.ff +15 -7
  3. package/compiler/Compiler.ff +13 -8
  4. package/compiler/Dependencies.ff +24 -17
  5. package/compiler/DependencyLock.ff +17 -0
  6. package/compiler/Deriver.ff +2 -1
  7. package/compiler/Dictionaries.ff +4 -4
  8. package/compiler/Environment.ff +3 -3
  9. package/compiler/Inference.ff +7 -7
  10. package/compiler/JsEmitter.ff +2 -2
  11. package/compiler/JsImporter.ff +2 -2
  12. package/compiler/LspHook.ff +2 -2
  13. package/compiler/Main.ff +22 -8
  14. package/compiler/ModuleCache.ff +6 -6
  15. package/compiler/Parser.ff +36 -36
  16. package/compiler/Resolver.ff +7 -7
  17. package/compiler/Syntax.ff +1 -1
  18. package/compiler/Tokenizer.ff +2 -2
  19. package/compiler/Unification.ff +3 -3
  20. package/compiler/Wildcards.ff +1 -1
  21. package/core/.firefly/include/package-lock.json +96 -96
  22. package/core/.firefly/include/package.json +1 -1
  23. package/core/Array.ff +2 -2
  24. package/core/Atomic.ff +1 -1
  25. package/core/Buffer.ff +1 -1
  26. package/core/Int.ff +2 -2
  27. package/core/IntMap.ff +4 -4
  28. package/core/Json.ff +5 -5
  29. package/core/List.ff +15 -15
  30. package/core/Map.ff +1 -1
  31. package/core/NodeSystem.ff +89 -0
  32. package/core/Option.ff +10 -3
  33. package/core/Random.ff +1 -1
  34. package/core/RbMap.ff +1 -1
  35. package/core/Serializable.ff +2 -2
  36. package/core/Set.ff +2 -2
  37. package/core/Stream.ff +4 -4
  38. package/core/StringMap.ff +4 -4
  39. package/experimental/random/Index.ff +53 -0
  40. package/experimental/random/MapTest.ff +2 -2
  41. package/experimental/random/Process.ff +120 -0
  42. package/experimental/random/RunLength.ff +2 -2
  43. package/experimental/random/Symbols.ff +2 -2
  44. package/lsp/CompletionHandler.ff +3 -6
  45. package/lsp/Handler.ff +45 -24
  46. package/lsp/LanguageServer.ff +13 -3
  47. package/lsp/SymbolHandler.ff +2 -2
  48. package/lsp/TestReferences.ff +2 -2
  49. package/lux/Lux.ff +6 -6
  50. package/output/js/ff/compiler/Builder.mjs +40 -28
  51. package/output/js/ff/compiler/Compiler.mjs +38 -14
  52. package/output/js/ff/compiler/Dependencies.mjs +30 -16
  53. package/output/js/ff/compiler/DependencyLock.mjs +128 -0
  54. package/output/js/ff/compiler/Deriver.mjs +4 -4
  55. package/output/js/ff/compiler/Dictionaries.mjs +8 -8
  56. package/output/js/ff/compiler/Environment.mjs +6 -6
  57. package/output/js/ff/compiler/Inference.mjs +12 -12
  58. package/output/js/ff/compiler/JsEmitter.mjs +4 -4
  59. package/output/js/ff/compiler/JsImporter.mjs +4 -4
  60. package/output/js/ff/compiler/LspHook.mjs +4 -4
  61. package/output/js/ff/compiler/Main.mjs +14 -12
  62. package/output/js/ff/compiler/ModuleCache.mjs +4 -4
  63. package/output/js/ff/compiler/Parser.mjs +72 -72
  64. package/output/js/ff/compiler/Resolver.mjs +14 -14
  65. package/output/js/ff/compiler/Syntax.mjs +2 -2
  66. package/output/js/ff/compiler/Tokenizer.mjs +4 -4
  67. package/output/js/ff/compiler/Unification.mjs +4 -4
  68. package/output/js/ff/compiler/Wildcards.mjs +2 -2
  69. package/output/js/ff/core/Array.mjs +5 -5
  70. package/output/js/ff/core/Atomic.mjs +3 -3
  71. package/output/js/ff/core/Buffer.mjs +3 -3
  72. package/output/js/ff/core/Int.mjs +4 -4
  73. package/output/js/ff/core/IntMap.mjs +9 -9
  74. package/output/js/ff/core/Json.mjs +10 -10
  75. package/output/js/ff/core/List.mjs +31 -31
  76. package/output/js/ff/core/Map.mjs +2 -2
  77. package/output/js/ff/core/NodeSystem.mjs +115 -0
  78. package/output/js/ff/core/Option.mjs +28 -2
  79. package/output/js/ff/core/Random.mjs +2 -2
  80. package/output/js/ff/core/RbMap.mjs +2 -2
  81. package/output/js/ff/core/Serializable.mjs +4 -4
  82. package/output/js/ff/core/Set.mjs +4 -4
  83. package/output/js/ff/core/Stream.mjs +8 -8
  84. package/output/js/ff/core/StringMap.mjs +9 -9
  85. package/package.json +1 -1
  86. package/postgresql/Pg.ff +2 -2
  87. package/rpc/Rpc.ff +3 -3
  88. package/vscode/package.json +1 -1
  89. package/webserver/WebServer.ff +2 -2
  90. package/httpserver/.firefly/package.ff +0 -1
  91. package/httpserver/HttpServer.ff +0 -184
@@ -1,5 +1,8 @@
1
1
  capability NodeSystem {}
2
2
 
3
+ class ProcessResult(exitCode: Int, standardOut: Buffer, standardError: Buffer)
4
+ data ProcessException(problem: String)
5
+
3
6
  extend self: NodeSystem {
4
7
 
5
8
  arguments(): List[String]
@@ -82,6 +85,84 @@ extend self: NodeSystem {
82
85
  writeErrorLine(text: String): Unit {
83
86
  self.writeErrorText(text + "\n")
84
87
  }
88
+
89
+ environment(): Map[String, String]
90
+ target node async """
91
+ const result = [];
92
+ for(const key in process.env) {
93
+ result.push(ff_core_Pair.Pair(key, process.env[key]));
94
+ }
95
+ return ff_core_List.List_toMap(result, ff_core_Ordering.ff_core_Ordering_Order$ff_core_String_String);
96
+ """
97
+
98
+ execute(
99
+ command: String
100
+ arguments: List[String]
101
+ standardIn: Buffer = Buffer.new(0)
102
+ workingDirectory: Option[Path] = None
103
+ environment: Option[Map[String, String]] = None
104
+ maxBuffer: Int = 16777216
105
+ killSignal: Int = 9
106
+ ): ProcessResult
107
+ target node async """
108
+ import * as childProcess from 'node:child_process';
109
+ const environment = environment_.value_ !== void 0 ? {} : process.env;
110
+ if(environment_.value_ !== void 0) {
111
+ ff_core_Map.Map_each(
112
+ environment_.value_,
113
+ (k, v) => environment[k] = v,
114
+ ff_core_Ordering.ff_core_Ordering_Order$ff_core_String_String
115
+ );
116
+ }
117
+ const newProcess = childProcess.spawn(command_, arguments_, {
118
+ cwd: workingDirectory_.value_,
119
+ windowsHide: true,
120
+ signal: $task.controller.signal,
121
+ killSignal: killSignal_,
122
+ env: environment,
123
+ });
124
+
125
+ let size = 0;
126
+ const out = [];
127
+ const err = [];
128
+
129
+ newProcess.stdout.on('data', (data) => {
130
+ if(size > maxBuffer_) return;
131
+ size += data.byteLength;
132
+ if(size > maxBuffer_) newProcess.kill(killSignal_);
133
+ else out.push(data);
134
+ });
135
+
136
+ newProcess.stderr.on('data', (data) => {
137
+ if(size > maxBuffer_) return;
138
+ size += data.byteLength;
139
+ if(size > maxBuffer_) newProcess.kill(killSignal_);
140
+ else err.push(data);
141
+ });
142
+
143
+ return await new Promise((resolve, reject) => {
144
+ if(standardIn_.byteLength !== 0) {
145
+ newProcess.stdin.write(standardIn_);
146
+ }
147
+ newProcess.stdin.end();
148
+ newProcess.on('error', error => {
149
+ if(size > maxBuffer_) {
150
+ reject(internalProcessError_("maxBuffer exceeded"));
151
+ } else {
152
+ reject(internalProcessError_(error.message));
153
+ }
154
+ });
155
+ newProcess.on('close', code => {
156
+ const o = Buffer.concat(out);
157
+ const e = Buffer.concat(err);
158
+ resolve(ProcessResult(
159
+ size > maxBuffer_ ? -1 : code,
160
+ new DataView(o.buffer, o.byteOffset, o.byteLength),
161
+ new DataView(e.buffer, e.byteOffset, e.byteLength),
162
+ ));
163
+ });
164
+ });
165
+ """
85
166
 
86
167
  }
87
168
 
@@ -95,3 +176,11 @@ internalListDirectoryWithoutOpendir(system: NodeSystem, path: Path): List[Path]
95
176
  let files = await fsPromises.readdir(path_)
96
177
  return files.map(file => path.join(path_, file))
97
178
  """
179
+
180
+ internalProcessError(problem: String): Error {
181
+ try {
182
+ throw(ProcessException(problem))
183
+ } catchAny {error =>
184
+ error
185
+ } grab()
186
+ }
package/core/Option.ff CHANGED
@@ -4,7 +4,7 @@ data Option[T] {
4
4
  }
5
5
 
6
6
  extend self[T]: Option[T] {
7
-
7
+
8
8
  else(body: () => T): T {
9
9
  self.{
10
10
  | None => body()
@@ -30,6 +30,13 @@ extend self[T]: Option[T] {
30
30
  }
31
31
  }
32
32
 
33
+ or[R](noneBody: () => R, someBody: T => R): R {
34
+ self.{
35
+ | None => noneBody()
36
+ | Some(value) => someBody(value)
37
+ }
38
+ }
39
+
33
40
  isEmpty(): Bool {
34
41
  self.{
35
42
  | None => True
@@ -50,7 +57,7 @@ extend self[T]: Option[T] {
50
57
 
51
58
  toStream(cycle: Bool = False): Stream[T] {
52
59
  mutable next = self
53
- Stream.make {
60
+ Stream.new {
54
61
  let result = next
55
62
  if(!cycle) {next = None}
56
63
  result
@@ -63,7 +70,7 @@ extend self[T]: Option[T] {
63
70
  | _ => None
64
71
  }
65
72
  }
66
-
73
+
67
74
  map[R](body: T => R): Option[R] {
68
75
  self.{
69
76
  | None => None
package/core/Random.ff CHANGED
@@ -8,7 +8,7 @@ seedInt(seed: Int): Random {
8
8
  }
9
9
 
10
10
  seedFloat(seed: Float): Random {
11
- let buffer = Buffer.make(8)
11
+ let buffer = Buffer.new(8)
12
12
  buffer.setFloat64(0, seed)
13
13
  seedBuffer(buffer)
14
14
  }
package/core/RbMap.ff CHANGED
@@ -161,7 +161,7 @@ extend self[K: Order, V]: RB[K, V] {
161
161
  tailcall next()
162
162
  }
163
163
  }
164
- Stream.make(next)
164
+ Stream.new(next)
165
165
  }
166
166
 
167
167
  each(body: (K, V) => Unit): Unit {
@@ -1,7 +1,7 @@
1
1
  data DeserializationChecksumException()
2
2
 
3
3
  serialize[T: Serializable](value: T, initialBufferSize: Int = 1024): Buffer {
4
- let serialization = Serialization(Buffer.make(initialBufferSize), 0, 0)
4
+ let serialization = Serialization(Buffer.new(initialBufferSize), 0, 0)
5
5
  serializeUsing(serialization, value)
6
6
  serialization.autoResize(4)
7
7
  serialization.buffer.setInt32(serialization.offset, serialization.checksum)
@@ -34,7 +34,7 @@ extend self: Serialization {
34
34
  autoResize(minSpareCapacity: Int) {
35
35
  if(self.offset + minSpareCapacity > self.buffer.size()) {
36
36
  let minSize = self.buffer.size() + minSpareCapacity
37
- let newBuffer = Buffer.make((self.buffer.size() * 2).max(minSize))
37
+ let newBuffer = Buffer.new((self.buffer.size() * 2).max(minSize))
38
38
  newBuffer.setAll(0, self.buffer)
39
39
  self.buffer = newBuffer
40
40
  }
package/core/Set.ff CHANGED
@@ -1,7 +1,7 @@
1
1
  newtype Set[T](map: Map[T, Unit])
2
2
 
3
- empty[T](): Set[T] {
4
- Set(Map.empty())
3
+ new[T](): Set[T] {
4
+ Set(Map.new())
5
5
  }
6
6
 
7
7
  extend self[T: Order]: Set[T] {
package/core/Stream.ff CHANGED
@@ -3,7 +3,7 @@ capability Stream[T](
3
3
  close: () => Unit
4
4
  )
5
5
 
6
- make[T](next: () => Option[T], close: () => Unit = {}): Stream[T] {
6
+ new[T](next: () => Option[T], close: () => Unit = {}): Stream[T] {
7
7
  Stream(next, close)
8
8
  }
9
9
 
@@ -338,7 +338,7 @@ extend self[T]: Stream[T] {
338
338
  }
339
339
 
340
340
  toArray(): Array[T] {
341
- let array = Array.make()
341
+ let array = Array.new()
342
342
  self.each {array.push(_)}
343
343
  array
344
344
  }
@@ -370,7 +370,7 @@ extend self[K: Order, V]: Stream[Pair[K, V]] {
370
370
  extend self: Stream[Buffer] {
371
371
 
372
372
  toBuffer(): Buffer {
373
- let builder = Array.make()
373
+ let builder = Array.new()
374
374
  self.each {builder.push(_)}
375
375
  Buffer.fromBufferArray(builder.drain())
376
376
  }
@@ -381,7 +381,7 @@ extend self: Stream[Buffer] {
381
381
 
382
382
  readBytes(bytes: Int): Pair[List[Buffer], Stream[Buffer]] {
383
383
  if(bytes <= 0) {Pair([], self)} else:
384
- let buffers = Array.make()
384
+ let buffers = Array.new()
385
385
  mutable buffer = self.next().grab()
386
386
  mutable taken = 0
387
387
  mutable remainder = None
package/core/StringMap.ff CHANGED
@@ -1,6 +1,6 @@
1
1
  class StringMap[V] {}
2
2
 
3
- make[V](): StringMap[V]
3
+ new[V](): StringMap[V]
4
4
  target js sync "return new Map()"
5
5
 
6
6
  extend self[V]: StringMap[V] {
@@ -41,7 +41,7 @@ extend self[V]: StringMap[V] {
41
41
  target js async "for(const [k, v] of self_) if(!await body_(k, v)) break"
42
42
 
43
43
  toArray(): Array[Pair[String, V]] {
44
- let array = Array.make()
44
+ let array = Array.new()
45
45
  self.each {k, v => array.push(Pair(k, v))}
46
46
  array
47
47
  }
@@ -59,13 +59,13 @@ extend self[V]: StringMap[V] {
59
59
  }
60
60
 
61
61
  keys(): List[String] {
62
- let array = Array.make()
62
+ let array = Array.new()
63
63
  self.each {k, v => array.push(k)}
64
64
  array.toList()
65
65
  }
66
66
 
67
67
  values(): List[V] {
68
- let array = Array.make()
68
+ let array = Array.new()
69
69
  self.each {k, v => array.push(v)}
70
70
  array.toList()
71
71
  }
@@ -0,0 +1,53 @@
1
+ data Index[K, R]()
2
+
3
+ extend self[K, R]: Index[K, R] {
4
+
5
+ get(key: K): Option[R] {
6
+ panic("Oops")
7
+ }
8
+
9
+ getUnique(key: K): Option[R] {
10
+ panic("Oops")
11
+ }
12
+
13
+ getOnly(): Option[R] {
14
+ panic("Oops")
15
+ }
16
+
17
+ grab(key: K): R {
18
+ panic("Oops")
19
+ }
20
+
21
+ grabUnique(key: K): R {
22
+ panic("Oops")
23
+ }
24
+
25
+ grabOnly(key: K): R {
26
+ panic("Oops")
27
+ }
28
+
29
+ getAll(key: K): List[R] {
30
+ panic("Oops")
31
+ }
32
+
33
+ range(from: K, until: K): Index[K, R] {
34
+ panic("Oops")
35
+ }
36
+
37
+ join[R1](that: Index[K, R1]): Index[K, Pair[R, R1]] {
38
+ panic("Oops")
39
+ }
40
+
41
+ keep(only: Set[K]): Index[K, R] {
42
+ panic("Oops")
43
+ }
44
+
45
+ filter(body: (K, R) => Bool): Index[K, R] {
46
+ panic("Oops")
47
+ }
48
+
49
+ withKeys[K1](body: (K, R) => K1): Index[K1, R] {
50
+ panic("Oops")
51
+ }
52
+
53
+ }
@@ -8,7 +8,7 @@ main(system: NodeSystem): Unit {
8
8
 
9
9
  testStringMap(system: NodeSystem) {
10
10
  let measurement = system.time().measure {
11
- let map = StringMap.make()
11
+ let map = StringMap.new()
12
12
  mutable i = 0
13
13
  while {i < 1000000} {
14
14
  map.set("" + i, i)
@@ -20,7 +20,7 @@ testStringMap(system: NodeSystem) {
20
20
 
21
21
  testIntMap(system: NodeSystem) {
22
22
  let measurement = system.time().measure {
23
- let map = IntMap.make()
23
+ let map = IntMap.new()
24
24
  mutable i = 0
25
25
  while {i < 1000000} {
26
26
  map.set(i, i)
@@ -0,0 +1,120 @@
1
+ capability Process {}
2
+
3
+ data ProcessException(exitCode: Int)
4
+
5
+ extend self: Process {
6
+
7
+ readStream(): Stream[Buffer] {
8
+
9
+ }
10
+
11
+ readErrorStream(): Stream[Buffer] {
12
+
13
+ }
14
+
15
+ readBothStreams(): Stream[Pair[Bool, Buffer]] {
16
+
17
+ }
18
+
19
+ readBuffer(): Buffer {
20
+
21
+ }
22
+
23
+ readErrorBuffer(): Buffer {
24
+
25
+ }
26
+
27
+ readBothBuffers(): Pair[Buffer, Buffer] {
28
+
29
+ }
30
+
31
+ readText(): String {
32
+
33
+ }
34
+
35
+ readErrorText(): String {
36
+
37
+ }
38
+
39
+ readBothTexts(): Pair[String, String] {
40
+
41
+ }
42
+
43
+ writeStream(stream: Stream[Buffer]) {
44
+
45
+ }
46
+
47
+ writeBuffer(buffer: Buffer) {
48
+
49
+ }
50
+
51
+ writeText(text: String) {
52
+
53
+ }
54
+
55
+ writeLine(text: String) {
56
+
57
+ }
58
+
59
+ closeStandardIn() {
60
+
61
+ }
62
+
63
+ running(): Bool {
64
+
65
+ }
66
+
67
+ exitCode(): Int {
68
+
69
+ }
70
+
71
+ setEnvironment(environment: Map[String, String]) {
72
+
73
+ }
74
+
75
+ setEnvironmentVariable(name: String, value: String) {
76
+
77
+ }
78
+
79
+ setWorkingDirectory(path: Path) {
80
+
81
+ }
82
+
83
+ setArgumentZero(commandName: String) {
84
+
85
+ }
86
+
87
+ setRedirection(in: Bool = False, out: Bool = False, error: Bool = False) {
88
+
89
+ }
90
+
91
+ setCloseAfterWrite(close: Bool) {
92
+
93
+ }
94
+
95
+ }
96
+
97
+ internalExecute[T](system: NodeSystem, command: String, arguments: List[String], body: Process => T): T {
98
+ throw(GrabException) // TODO
99
+ }
100
+
101
+ main(system: NodeSystem) {
102
+ let initialize = ""
103
+ let hoverRequest = ""
104
+ function parseInitializeResponse(stream: Stream[Buffer]) {
105
+
106
+ }
107
+ function parseHoverResponse(stream: Stream[Buffer]) {
108
+
109
+ }
110
+
111
+ system.execute("my-lsp", []) {process =>
112
+ process.setCloseAfterWrite(False)
113
+ let stream = process.readStream()
114
+ process.writeText(initialize)
115
+ let config = parseInitializeResponse(stream)
116
+ process.writeText(hoverRequest)
117
+ let hover = parseHoverResponse(stream)
118
+ // ...
119
+ }
120
+ }
@@ -18,13 +18,13 @@ printRunLength(outStream: Stream[Buffer]) {
18
18
  }
19
19
 
20
20
  toRunLength(stream: Stream[Buffer], bufferSize: Int = 65536): Stream[Buffer] {
21
- mutable outBuffer = Buffer.make(bufferSize)
21
+ mutable outBuffer = Buffer.new(bufferSize)
22
22
  mutable outOffset = 0
23
23
  let outBuffers = Stack.make()
24
24
  function writeByte(byte: Int): Unit {
25
25
  if(outOffset >= outBuffer.size()) {
26
26
  outBuffers.push(outBuffer)
27
- outBuffer = Buffer.make(bufferSize)
27
+ outBuffer = Buffer.new(bufferSize)
28
28
  outOffset = 0
29
29
  }
30
30
  outBuffer.setUint8(outOffset, byte)
@@ -33,9 +33,9 @@ test(symbols: List[String], query: String) {
33
33
  }
34
34
 
35
35
  matchSymbol(symbolWords: List[String], query: String, lower: Bool): Bool {
36
- let memo: IntMap[IntMap[Bool]] = IntMap.make()
36
+ let memo: IntMap[IntMap[Bool]] = IntMap.new()
37
37
  function go(wordIndex: Int, queryOffset: Int): Bool {
38
- memo.getOrSet(wordIndex) {IntMap.make()}.getOrSet(queryOffset):
38
+ memo.getOrSet(wordIndex) {IntMap.new()}.getOrSet(queryOffset):
39
39
  if(queryOffset >= query.size()) {True} else:
40
40
  if(wordIndex >= symbolWords.size()) {False} else:
41
41
  prefixes(query.dropFirst(queryOffset)).any {prefix =>
@@ -228,7 +228,7 @@ completion(
228
228
 
229
229
  let member = prefix.contains("_")
230
230
 
231
- let members = Array.make()
231
+ let members = Array.new()
232
232
 
233
233
  let symbols = if(prefix == "") {
234
234
  environment.symbols.toList().collect {
@@ -762,7 +762,7 @@ toplevelCompletion(lspHook: LspHook): List[CompletionInfo] {
762
762
  " if(request.readPath() == \"/\") {"
763
763
  " request.writeHeader(\"Content-Type\", \"text/html; charset=UTF-8\")"
764
764
  " request.writeText(\"<!doctype html>\")"
765
- " request.writeText(\"<script type='module' src='/js/script/script/WebApp.mjs'></script>\")"
765
+ " request.writeText(\"<script type='module' src='/js/script/script/$TM_FILENAME_BASE.mjs'></script>\")"
766
766
  " } elseIf {request.readPath() == \"/hello\"} {"
767
767
  " request.writeHeader(\"Content-Type\", \"text/plain; charset=UTF-8\")"
768
768
  " request.writeText(\"Hello from server!\")"
@@ -776,13 +776,10 @@ toplevelCompletion(lspHook: LspHook): List[CompletionInfo] {
776
776
  "}"
777
777
  ""
778
778
  "buildMain(system: BuildSystem) {"
779
- " let browser = system.compileForBrowser(\"WebApp.ff\")"
779
+ " let browser = system.compileForBrowser(\"$TM_FILENAME_BASE.ff\")"
780
780
  " let assets = AssetSystem.create().addAssets(\"/js\", browser.assets())"
781
781
  " system.setAssets(assets)"
782
782
  "}"
783
- ""
784
- "// To run this, name your file WebApp.ff and type:"
785
- "// firefly WebApp.ff"
786
783
  ].join("\n"),
787
784
  member = False,
788
785
  type = TConstructor(lspHook.at, "", []),