firefly-compiler 0.5.50 → 0.5.51

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 (132) hide show
  1. package/bin/Release.ff +3 -3
  2. package/bin/firefly.mjs +1 -1
  3. package/compiler/Builder.ff +11 -5
  4. package/compiler/Compiler.ff +14 -3
  5. package/compiler/JsEmitter.ff +6 -11
  6. package/compiler/Main.ff +10 -15
  7. package/compiler/ModuleCache.ff +2 -1
  8. package/core/Buffer.ff +26 -4
  9. package/core/BuildSystem.ff +49 -46
  10. package/core/JsValue.ff +5 -0
  11. package/experimental/date/Date.ff +604 -0
  12. package/experimental/date/Main.ff +51 -0
  13. package/experimental/random/AsciiBuffer.ff +15 -0
  14. package/experimental/rhymeapp/Main.ff +2 -3
  15. package/experimental/site/Main.ff +2 -2
  16. package/experimental/site2/Main.ff +2 -2
  17. package/firefly.sh +1 -1
  18. package/fireflysite/CommunityOverview.ff +3 -3
  19. package/fireflysite/CountingButtonDemo.ff +3 -3
  20. package/fireflysite/ExamplesOverview.ff +3 -12
  21. package/fireflysite/FrontPage.ff +3 -3
  22. package/fireflysite/GettingStarted.ff +3 -3
  23. package/fireflysite/Guide.ff +7 -187
  24. package/fireflysite/Html.ff +66 -0
  25. package/fireflysite/Main.ff +13 -77
  26. package/fireflysite/MatchingPasswordsDemo.ff +3 -3
  27. package/fireflysite/Menu.ff +59 -0
  28. package/fireflysite/PackagesOverview.ff +3 -3
  29. package/fireflysite/PostgresqlDemo.ff +3 -3
  30. package/fireflysite/RouteFront.ff +30 -0
  31. package/fireflysite/RouteNonMarkdown.ff +48 -0
  32. package/fireflysite/RouteReference.ff +40 -0
  33. package/fireflysite/Router.ff +33 -0
  34. package/fireflysite/Website.ff +133 -0
  35. package/fireflysite/assets/markdown/reference/{FunctionsAndMethods.md → functions-and-methods.md} +1 -1
  36. package/fireflysite/assets/markdown/reference/{StatementsAndExpressions.md → statements-and-expressions.md} +0 -1
  37. package/fireflysite/assets/markdown/reference/{StructuredConcurrency.md → structured-concurrency.md} +0 -1
  38. package/fireflysite/assets/markdown/reference.md +3 -0
  39. package/graph/.firefly/package.ff +1 -0
  40. package/graph/Graph.ff +79 -0
  41. package/lsp/CompletionHandler.ff +2 -2
  42. package/lux/CssTest.ff +2 -2
  43. package/lux/Main.ff +2 -2
  44. package/lux/Main2.ff +2 -2
  45. package/output/js/ff/compiler/Builder.mjs +44 -12
  46. package/output/js/ff/compiler/Compiler.mjs +28 -10
  47. package/output/js/ff/compiler/Dependencies.mjs +0 -2
  48. package/output/js/ff/compiler/DependencyLock.mjs +0 -2
  49. package/output/js/ff/compiler/Deriver.mjs +0 -2
  50. package/output/js/ff/compiler/Dictionaries.mjs +0 -2
  51. package/output/js/ff/compiler/Environment.mjs +0 -2
  52. package/output/js/ff/compiler/Inference.mjs +0 -2
  53. package/output/js/ff/compiler/JsEmitter.mjs +12 -30
  54. package/output/js/ff/compiler/JsImporter.mjs +0 -2
  55. package/output/js/ff/compiler/LspHook.mjs +0 -2
  56. package/output/js/ff/compiler/Main.mjs +24 -47
  57. package/output/js/ff/compiler/Main.run.mjs +25 -0
  58. package/output/js/ff/compiler/ModuleCache.mjs +4 -6
  59. package/output/js/ff/compiler/Parser.mjs +0 -2
  60. package/output/js/ff/compiler/Patterns.mjs +0 -2
  61. package/output/js/ff/compiler/Resolver.mjs +0 -2
  62. package/output/js/ff/compiler/Substitution.mjs +0 -2
  63. package/output/js/ff/compiler/Syntax.mjs +0 -2
  64. package/output/js/ff/compiler/Token.mjs +0 -2
  65. package/output/js/ff/compiler/Tokenizer.mjs +0 -2
  66. package/output/js/ff/compiler/Unification.mjs +0 -2
  67. package/output/js/ff/compiler/Wildcards.mjs +0 -2
  68. package/output/js/ff/compiler/Workspace.mjs +0 -2
  69. package/output/js/ff/core/Any.mjs +0 -2
  70. package/output/js/ff/core/Array.mjs +0 -2
  71. package/output/js/ff/core/AssetSystem.mjs +0 -2
  72. package/output/js/ff/core/Atomic.mjs +0 -2
  73. package/output/js/ff/core/Bool.mjs +0 -2
  74. package/output/js/ff/core/BrowserSystem.mjs +0 -2
  75. package/output/js/ff/core/Buffer.mjs +50 -10
  76. package/output/js/ff/core/BuildSystem.mjs +92 -72
  77. package/output/js/ff/core/Channel.mjs +0 -2
  78. package/output/js/ff/core/Char.mjs +0 -2
  79. package/output/js/ff/core/Core.mjs +0 -2
  80. package/output/js/ff/core/Crypto.mjs +0 -2
  81. package/output/js/ff/core/Date.mjs +0 -2
  82. package/output/js/ff/core/Duration.mjs +0 -2
  83. package/output/js/ff/core/Equal.mjs +0 -2
  84. package/output/js/ff/core/Error.mjs +0 -2
  85. package/output/js/ff/core/FileHandle.mjs +0 -2
  86. package/output/js/ff/core/Float.mjs +0 -2
  87. package/output/js/ff/core/HttpClient.mjs +0 -2
  88. package/output/js/ff/core/Int.mjs +0 -2
  89. package/output/js/ff/core/IntMap.mjs +0 -2
  90. package/output/js/ff/core/Js.mjs +0 -2
  91. package/output/js/ff/core/JsSystem.mjs +0 -2
  92. package/output/js/ff/core/JsValue.mjs +8 -2
  93. package/output/js/ff/core/Json.mjs +0 -2
  94. package/output/js/ff/core/List.mjs +0 -2
  95. package/output/js/ff/core/Lock.mjs +0 -2
  96. package/output/js/ff/core/Log.mjs +0 -2
  97. package/output/js/ff/core/Map.mjs +0 -2
  98. package/output/js/ff/core/NodeSystem.mjs +0 -2
  99. package/output/js/ff/core/Nothing.mjs +0 -2
  100. package/output/js/ff/core/Option.mjs +0 -2
  101. package/output/js/ff/core/Ordering.mjs +0 -2
  102. package/output/js/ff/core/Pair.mjs +0 -2
  103. package/output/js/ff/core/Path.mjs +0 -2
  104. package/output/js/ff/core/Queue.mjs +0 -2
  105. package/output/js/ff/core/Random.mjs +0 -2
  106. package/output/js/ff/core/RbMap.mjs +0 -2
  107. package/output/js/ff/core/Serializable.mjs +0 -2
  108. package/output/js/ff/core/Set.mjs +0 -2
  109. package/output/js/ff/core/Show.mjs +0 -2
  110. package/output/js/ff/core/SourceLocation.mjs +0 -2
  111. package/output/js/ff/core/Stream.mjs +0 -2
  112. package/output/js/ff/core/String.mjs +0 -2
  113. package/output/js/ff/core/StringMap.mjs +0 -2
  114. package/output/js/ff/core/Task.mjs +0 -2
  115. package/output/js/ff/core/Try.mjs +0 -2
  116. package/output/js/ff/core/Unit.mjs +0 -2
  117. package/package.json +1 -1
  118. package/vscode/client/src/extension.ts +1 -1
  119. package/vscode/package.json +1 -1
  120. package/vscode/snippets.json +2 -2
  121. package/webserver/WebRoute.ff +51 -14
  122. package/fireflysite/ReferenceAll.ff +0 -18
  123. /package/fireflysite/assets/markdown/reference/{BaseTypes.md → base-types.md} +0 -0
  124. /package/fireflysite/assets/markdown/reference/{EmittedJavascript.md → emitted-javascript.md} +0 -0
  125. /package/fireflysite/assets/markdown/reference/{Exceptions.md → exceptions.md} +0 -0
  126. /package/fireflysite/assets/markdown/reference/{JavascriptInterop.md → javascript-interop.md} +0 -0
  127. /package/fireflysite/assets/markdown/reference/{ModulesAndPackages.md → modules-and-packages.md} +0 -0
  128. /package/fireflysite/assets/markdown/reference/{PatternMatching.md → pattern-matching.md} +0 -0
  129. /package/fireflysite/assets/markdown/reference/{TraitsAndInstances.md → traits-and-instances.md} +0 -0
  130. /package/fireflysite/assets/markdown/reference/{UserDefinedTypes.md → user-defined-types.md} +0 -0
  131. /package/fireflysite/assets/markdown/scratch/{ControlFlow.md → control-flow.md} +0 -0
  132. /package/fireflysite/assets/markdown/{reference/OldStructuredConcurrency.md → scratch/old-structured-concurrency.md} +0 -0
@@ -0,0 +1,30 @@
1
+ import Lux from ff:lux
2
+ import WebServer from ff:webserver
3
+ import Router
4
+ import Guide
5
+ import ExamplesOverview
6
+ import FrontPage
7
+ import Html
8
+ import Website
9
+ import Menu
10
+
11
+ routeModule = SourceLocation.here().module()
12
+
13
+ data PageData(sections: List[Section])
14
+
15
+ handle(request: WebRequest[WebResponse], context: RouteContext) {
16
+ let pageData = PageData(FrontPage.sections())
17
+ let title = "Firefly"
18
+ Html.renderAndServe(context.system, routeModule, pageData, title, request, {render(_, pageData)})
19
+ }
20
+
21
+ browserMain(system: BrowserSystem) {
22
+ Html.renderToMain(system, {render(_, _)})
23
+ }
24
+
25
+ render(lux: Lux, data: PageData) {
26
+ let next = None // TODO MenuItem(["getting-started"], Menu.menu.grabFirst().name, None)
27
+ Website.renderContentWithNext(lux, [], next) {lux =>
28
+ Guide.renderSections(lux, data.sections, ExamplesOverview.demos())
29
+ }
30
+ }
@@ -0,0 +1,48 @@
1
+ import Lux from ff:lux
2
+ import WebServer from ff:webserver
3
+ import Router
4
+ import Guide
5
+ import ExamplesOverview
6
+ import GettingStarted
7
+ import CountingButtonDemo
8
+ import MatchingPasswordsDemo
9
+ import PostgresqlDemo
10
+ import Html
11
+ import Website
12
+ import Menu
13
+ import PackagesOverview
14
+ import CommunityOverview
15
+
16
+ routeModule = SourceLocation.here().module()
17
+
18
+ data PageData(menuEntry: MenuItem, sections: List[Section])
19
+
20
+ handle(request: WebRequest[WebResponse], context: RouteContext, directory: String, name: Option[String]) {
21
+ let path = [directory, ...name.toList()]
22
+ Menu.findItem(path).or {Html.serve404(request)}: menuEntry =>
23
+
24
+ let sections = path.{
25
+ | ["getting-started"] => GettingStarted.sections()
26
+ | ["examples"] => ExamplesOverview.sections()
27
+ | ["examples", "counting-button"] => CountingButtonDemo.sections()
28
+ | ["examples", "matching-passwords"] => MatchingPasswordsDemo.sections()
29
+ | ["examples", "connecting-to-postgresql"] => PostgresqlDemo.sections()
30
+ | ["packages"] => PackagesOverview.sections()
31
+ | ["community"] => CommunityOverview.sections()
32
+ | _ => []
33
+ }
34
+ if(sections.isEmpty()) {Html.serve404(request)} else:
35
+ let pageData = PageData(menuEntry, sections)
36
+ let title = Html.title(menuEntry)
37
+ Html.renderAndServe(context.system, routeModule, pageData, title, request, {render(_, pageData)})
38
+ }
39
+
40
+ browserMain(system: BrowserSystem) {
41
+ Html.renderToMain(system, {render(_, _)})
42
+ }
43
+
44
+ render(lux: Lux, data: PageData) {
45
+ Website.renderContentWithNext(lux, data.menuEntry.path, data.menuEntry.next) {lux =>
46
+ Guide.renderSections(lux, data.sections, ExamplesOverview.demos())
47
+ }
48
+ }
@@ -0,0 +1,40 @@
1
+ import Lux from ff:lux
2
+ import WebServer from ff:webserver
3
+ import Router
4
+ import Guide
5
+ import ExamplesOverview
6
+ import FrontPage
7
+ import DocumentParser
8
+ import Html
9
+ import Website
10
+ import Menu
11
+
12
+ routeModule = SourceLocation.here().module()
13
+
14
+ data PageData(menuEntry: MenuItem, sections: List[Section])
15
+
16
+ handle(request: WebRequest[WebResponse], context: RouteContext, kebab: Option[String]) {
17
+ let path = ["reference", ...kebab.toList()]
18
+ Menu.findItem(path).or {Html.serve404(request)}: menuEntry =>
19
+
20
+ let asset = "/assets/markdown/" + path.join("/") + ".md"
21
+ try {context.system.assets().readText(asset)}.toOption().or {
22
+ Log.trace("Asset not found: " + asset)
23
+ Html.serve404(request)
24
+ }: markdown =>
25
+ let parser = DocumentParser(path.last().grab(), markdown.split('\n'), 0)
26
+ let sections = parser.parseDocument()
27
+ let pageData = PageData(menuEntry, sections)
28
+ let title = Html.title(menuEntry)
29
+ Html.renderAndServe(context.system, routeModule, pageData, title, request, {render(_, pageData)})
30
+ }
31
+
32
+ browserMain(system: BrowserSystem) {
33
+ Html.renderToMain(system, {render(_, _)})
34
+ }
35
+
36
+ render(lux: Lux, data: PageData) {
37
+ Website.renderContentWithNext(lux, data.menuEntry.path, data.menuEntry.next) {lux =>
38
+ Guide.renderSections(lux, data.sections, ExamplesOverview.demos())
39
+ }
40
+ }
@@ -0,0 +1,33 @@
1
+ import WebServer from ff:webserver
2
+ import WebRoute from ff:webserver
3
+ import RouteFront
4
+ import RouteReference
5
+ import RouteNonMarkdown
6
+
7
+ capability RouteContext(system: NodeSystem)
8
+
9
+ frontRoute: WebRoute0 = WebRoute.new0(
10
+ "/"
11
+ )
12
+
13
+ referenceRoute: WebRoute1[Option[String]] = WebRoute.new1(
14
+ "/reference/{name?}"
15
+ )
16
+
17
+ nonMarkdownRoute: WebRoute2[String, Option[String]] = WebRoute.new2(
18
+ "/{directory}/{name?}"
19
+ )
20
+
21
+ modulesWithBrowserMain(): List[String] {
22
+ [
23
+ RouteFront.routeModule
24
+ RouteReference.routeModule
25
+ RouteNonMarkdown.routeModule
26
+ ]
27
+ }
28
+
29
+ handlers(handler: WebRouteHandler[RouteContext]) {
30
+ handler.add0(frontRoute, RouteFront.handle)
31
+ handler.add1(referenceRoute, RouteReference.handle)
32
+ handler.add2(nonMarkdownRoute, RouteNonMarkdown.handle)
33
+ }
@@ -0,0 +1,133 @@
1
+ import Lux from ff:lux
2
+ import LuxEvent from ff:lux
3
+ import Css from ff:lux
4
+ import Styles
5
+ import Menu
6
+
7
+ renderContentWithNext(
8
+ lux: Lux
9
+ path: List[String]
10
+ next: Option[MenuItem]
11
+ content: Lux => Unit
12
+ ) {
13
+ lux.add("div") {
14
+ lux.useState(False): showMenu, setMenu =>
15
+ lux.cssClass(Styles.pageCss)
16
+ lux.add("div") {
17
+ lux.cssClass(Styles.guideCss)
18
+ lux.add("main") {
19
+ lux.cssClass(Styles.guideMainCss)
20
+ lux.add("article") {
21
+ lux.cssClass(Styles.guideDocumentCss)
22
+ content(lux)
23
+ renderNext(lux, next)
24
+ }
25
+ }
26
+ renderTopbar(lux, showMenu, setMenu)
27
+ lux.add("div") {
28
+ lux.cssClass(Styles.guideSidebarBackdropCss)
29
+ if(showMenu) {lux.cssClass(Styles.guideSidebarBackdropOpenCss)}
30
+ lux.onClick {event =>
31
+ event.preventDefault()
32
+ setMenu(False)
33
+ }
34
+ }
35
+ renderSidebar(lux, path, showMenu)
36
+ }
37
+ }
38
+ }
39
+
40
+ renderNext(lux: Lux, nextItem: Option[MenuItem]) {
41
+ nextItem.each {next =>
42
+ lux.div {
43
+ lux.cssClass(Styles.guideNextButtonCss)
44
+ lux.add("a") {
45
+ lux.cssClass(Styles.guideButtonCss)
46
+ lux.set("href", "/" + next.path.join("/"))
47
+ lux.text("Next: " + next.name)
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ renderTopbar(lux: Lux, showMenu: Bool, setMenu: Bool => Unit) {
54
+ lux.add("div") {
55
+ lux.cssClass(Styles.guideTopbarCss)
56
+ lux.add("a") {
57
+ lux.set("href", "/")
58
+ lux.cssClass(Styles.guideTopbarLogoCss)
59
+ lux.add("img") {
60
+ lux.set("src", "/assets/image/firefly-logo-yellow.webp")
61
+ }
62
+ lux.div {
63
+ lux.text("Firefly")
64
+ }
65
+ }
66
+ lux.add("button") {
67
+ lux.set("aria-label", "Toggle the menu")
68
+ lux.cssClass(Styles.guideTopbarButtonCss)
69
+ lux.onClick {event =>
70
+ event.preventDefault()
71
+ setMenu(True)
72
+ }
73
+ }
74
+ }
75
+ }
76
+
77
+ renderSidebar(lux: Lux, selectedPath: List[String], showMenu: Bool) {
78
+ lux.add("nav") {
79
+ lux.cssClass(Styles.guideSidebarCss)
80
+ if(showMenu) {lux.cssClass(Styles.guideSidebarOpenCss)}
81
+ lux.add("a") {
82
+ lux.set("href", "/")
83
+ lux.cssClass(Styles.guideSidebarLogoCss)
84
+ lux.add("img") {
85
+ lux.set("src", "/assets/image/firefly-logo-yellow.webp")
86
+ }
87
+ lux.div {
88
+ lux.text("Firefly")
89
+ }
90
+ }
91
+ lux.add("form") {
92
+ lux.set("role", "search")
93
+ lux.add("input") {
94
+ lux.set("aria-label", "Search")
95
+ lux.cssClass(Styles.searchInputCss)
96
+ lux.set("placeholder", "Search...")
97
+ }
98
+ }
99
+ lux.add("ul") {
100
+ lux.cssClass(Styles.guideSidebarUl1Css)
101
+ Menu.menu.each {item =>
102
+ lux.add("li") {
103
+ lux.cssClass(Styles.guideSidebarLi1Css)
104
+ lux.add("a") {
105
+ lux.cssClass(Styles.whiteLinkCss)
106
+ if(selectedPath == [item.path]) {
107
+ lux.set("aria-current", "page")
108
+ }
109
+ lux.set("href", "/" + item.path)
110
+ lux.text(item.name)
111
+ }
112
+ if(item.menu.size() > 1):
113
+ lux.add("ul") {
114
+ lux.cssClass(Styles.guideSidebarUl2Css)
115
+ item.menu.each {subItem =>
116
+ lux.add("li") {
117
+ lux.cssClass(Styles.guideSidebarLi2Css)
118
+ lux.add("a") {
119
+ lux.cssClass(Styles.whiteLinkCss)
120
+ if(selectedPath == [item.path, subItem.path]) {
121
+ lux.set("aria-current", "page")
122
+ }
123
+ lux.set("href", "/" + item.path + "/" + subItem.path)
124
+ lux.text(subItem.name)
125
+ }
126
+ }
127
+ }
128
+ }
129
+ }
130
+ }
131
+ }
132
+ }
133
+ }
@@ -362,4 +362,4 @@ Some(1).map {_ + 1} // Some(2)
362
362
 
363
363
  # Trait functions
364
364
 
365
- Trait functions are covered in the section about [traits and instances](traits-and-instances)
365
+ Trait functions are covered in the section about [traits and instances](traits-and-instances)
@@ -83,4 +83,3 @@ Binary operators are left associative and the operator precedence is as follows,
83
83
  * `x.y` `x.V()` `x.{_}`
84
84
 
85
85
  Unary operators `!` and `-` have higher precedence than `^` and lower precedence than `f()`.
86
-
@@ -96,4 +96,3 @@ However, there are two problems here:
96
96
 
97
97
  * If all the fetch tasks are waiting to write to the `out` channel, `in.write(url)` will block forever.
98
98
  * There's no logic to discover that there are no API calls left to do, so the `total` will never be reported.
99
-
@@ -0,0 +1,3 @@
1
+ # Reference
2
+
3
+ This is a reference for the Firefly programming language.
@@ -0,0 +1 @@
1
+ package ff:graph:0.0.0
package/graph/Graph.ff ADDED
@@ -0,0 +1,79 @@
1
+ /*nodeMain(system: NodeSystem) {
2
+ let result = tarjan([1]) {
3
+ | 1, f => f(2); f(3); f(4)
4
+ | 2, f => f(5)
5
+ | 5, f => f(2)
6
+ | 3, f => f(6); f(7)
7
+ | 4, f => f(8)
8
+ | 8, f => f(9); f(10)
9
+ | 9, f => f(11); f(10)
10
+ | 10, f => f(8); f(9)
11
+ | _, f =>
12
+ }
13
+ Log.show(result)
14
+ }*/
15
+
16
+ breadthFirst(roots: List[Int], eachEdge: (Int, Int => Unit) => Unit): Unit {
17
+ mutable seen = IntMap.new()
18
+ let queue = Array.new()
19
+ queue.pushList(roots)
20
+ mutable i = 0
21
+ while {i < queue.size()} {
22
+ eachEdge(queue.grab(i)) {v =>
23
+ if(!seen.has(v)) {
24
+ seen.set(v, v)
25
+ queue.push(v)
26
+ }
27
+ }
28
+ i += 1
29
+ }
30
+ }
31
+
32
+ tarjan(roots: List[Int], eachEdge: (Int, Int => Unit) => Unit): List[List[Int]] {
33
+ mutable index = 0
34
+ mutable stack = Array.new[Int]()
35
+ mutable onStack = IntMap.new[Bool]()
36
+ mutable indices = IntMap.new[Int]()
37
+ mutable lowlink = IntMap.new[Int]()
38
+ mutable sccs = Array.new[List[Int]]()
39
+
40
+ function go(v: Int) {
41
+ indices.set(v, index)
42
+ lowlink.set(v, index)
43
+ index += 1
44
+
45
+ stack.push(v)
46
+ onStack.set(v, True)
47
+
48
+ eachEdge(v) {w =>
49
+ if(!indices.has(w)) {
50
+ go(w)
51
+ lowlink.set(v, lowlink.grab(v).min(lowlink.grab(w)))
52
+ } elseIf {onStack.grab(w)} {
53
+ lowlink.set(v, lowlink.grab(v).min(indices.grab(w)))
54
+ }
55
+ }
56
+
57
+ if(lowlink.grab(v) == indices.grab(v)) {
58
+ let scc = Array.new[Int]()
59
+ mutable done = False
60
+ while {!done} {
61
+ let w = stack.pop().grab()
62
+ onStack.set(w, False)
63
+ scc.push(w)
64
+ if(w == v) {
65
+ done = True
66
+ }
67
+ }
68
+ sccs.push(scc.drain())
69
+ }
70
+ }
71
+
72
+ roots.each {v =>
73
+ if(!indices.has(v)) {
74
+ go(v)
75
+ }
76
+ }
77
+
78
+ sccs.drain()
79
+ }
@@ -792,8 +792,8 @@ toplevelCompletion(lspHook: LspHook): List[CompletionInfo] {
792
792
  "}"
793
793
  ""
794
794
  "buildMain(system: BuildSystem) {"
795
- " let browser = system.compileForBrowser(\"$TM_FILENAME_BASE.ff\")"
796
- " let assets = AssetSystem.create().addAssets(\"/js\", browser.assets())"
795
+ " let browserAssets = system.compileForBrowser([\"$TM_FILENAME_BASE.ff\"])"
796
+ " let assets = AssetSystem.create().addAssets(\"/js\", browserAssets)"
797
797
  " system.setAssets(assets)"
798
798
  "}"
799
799
  ].join("\n"),
package/lux/CssTest.ff CHANGED
@@ -42,7 +42,7 @@ nodeMain(system: NodeSystem) {
42
42
  }
43
43
 
44
44
  buildMain(system: BuildSystem) {
45
- let browser = system.compileForBrowser("CssTest.ff")
46
- let assets = AssetSystem.create().addAssets("/js", browser.assets())
45
+ let browserAssets = system.compileForBrowser(["CssTest.ff"])
46
+ let assets = AssetSystem.create().addAssets("/js", browserAssets)
47
47
  system.setAssets(assets)
48
48
  }
package/lux/Main.ff CHANGED
@@ -117,7 +117,7 @@ in E.object
117
117
  ]
118
118
  */
119
119
  buildMain(system: BuildSystem) {
120
- let browser = system.compileForBrowser("Main.ff")
121
- let assets = AssetSystem.create().addAssets("/js", browser.assets())
120
+ let browserAssets = system.compileForBrowser(["Main.ff"])
121
+ let assets = AssetSystem.create().addAssets("/js", browserAssets)
122
122
  system.setAssets(assets)
123
123
  }
package/lux/Main2.ff CHANGED
@@ -125,8 +125,8 @@ nodeMain(system: NodeSystem): Unit {
125
125
  }
126
126
 
127
127
  buildMain(system: BuildSystem) {
128
- let browser = system.compileForBrowser("Main2.ff")
129
- let assets = AssetSystem.create().addAssets("/js", browser.assets())
128
+ let browserAssets = system.compileForBrowser(["Main2.ff"])
129
+ let assets = AssetSystem.create().addAssets("/js", browserAssets)
130
130
  system.setAssets(assets)
131
131
  }
132
132
 
@@ -125,7 +125,7 @@ return {root_, packageFile_, files_};
125
125
 
126
126
 
127
127
 
128
- export function build_(system_, emitTarget_, mainPackage_, mainModule_, resolvedDependencies_, compilerModulePath_, tempPath_, jsOutputPath_, printMeasurements_, moduleCache_) {
128
+ export function build_(system_, emitTarget_, mainPackage_, mainModules_, resolvedDependencies_, compilerModulePath_, tempPath_, jsOutputPath_, printMeasurements_, moduleCache_) {
129
129
  if(ff_core_Path.Path_exists(tempPath_, false, false, false)) {
130
130
  ff_core_Path.Path_delete(tempPath_, 0, 100)
131
131
  };
@@ -134,7 +134,10 @@ const jsPathFile_ = ff_core_Path.Path_slash(tempPath_, "js");
134
134
  ff_core_Path.Path_createDirectory(jsPathFile_, true);
135
135
  const success_ = ff_core_Core.do_((() => {
136
136
  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_());
137
- ff_compiler_Compiler.Compiler_emit(compiler_, mainPackage_, mainModule_, true);
137
+ for(let for_a = mainModules_, for_i = 0, for_l = for_a.length; for_i < for_l; for_i++) {
138
+ const mainModule_ = for_a[for_i];
139
+ ff_compiler_Compiler.Compiler_emit(compiler_, mainPackage_, mainModule_, true)
140
+ };
138
141
  if(printMeasurements_) {
139
142
  ff_compiler_Compiler.Compiler_printMeasurements(compiler_)
140
143
  };
@@ -186,15 +189,29 @@ ff_core_NodeSystem.NodeSystem_writeErrorBuffer(system_, result_.standardError_)
186
189
  }
187
190
  }
188
191
 
189
- export function buildViaBuildSystem_(system_, fireflyPath_, mainFile_, target_) {
190
- const resolvedDependencies_ = ff_compiler_Dependencies.process_(ff_core_NodeSystem.NodeSystem_httpClient(system_), ff_compiler_DependencyLock.new_(ff_core_NodeSystem.NodeSystem_mainTask(system_)), ff_core_NodeSystem.NodeSystem_path(system_, mainFile_));
192
+ export function buildViaBuildSystem_(system_, fireflyPath_, mainFiles_, target_) {
193
+ const mainPaths_ = ff_core_List.List_map(mainFiles_, ((_w1) => {
194
+ return ff_core_Path.Path_absolute(ff_core_Option.Option_grab(ff_core_Path.Path_parent(ff_core_NodeSystem.NodeSystem_path(system_, _w1))))
195
+ }));
196
+ {
197
+ const if_o = ff_core_List.List_find(mainPaths_, ((_w1) => {
198
+ return (_w1 !== ff_core_List.List_grabFirst(mainPaths_))
199
+ }))
200
+ if(if_o.Some) {
201
+ const path_ = if_o.value_;
202
+ ff_core_Core.panic_(((("Can't build multiple main files in different directories: " + path_) + " vs. ") + ff_core_List.List_grabFirst(mainPaths_)))
203
+ }
204
+ };
205
+ const resolvedDependencies_ = ff_compiler_Dependencies.process_(ff_core_NodeSystem.NodeSystem_httpClient(system_), ff_compiler_DependencyLock.new_(ff_core_NodeSystem.NodeSystem_mainTask(system_)), ff_core_NodeSystem.NodeSystem_path(system_, ff_core_List.List_grabFirst(mainFiles_)));
191
206
  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)
192
207
  ? resolvedDependencies_.packagePaths_
193
208
  : ff_core_Map.Map_add(resolvedDependencies_.packagePaths_, ff_compiler_Syntax.PackagePair("ff", "core"), ff_core_Path.Path_slash(fireflyPath_, "core"), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair));
194
209
  if((target_ !== "browser")) {
195
210
  ff_core_Core.panic_("buildViaBuildSystem is currently limited to browser target only - the restriction can be lifted")
196
211
  };
197
- ff_compiler_Builder.build_(system_, ff_compiler_JsEmitter.EmitBrowser(), resolvedDependencies_.mainPackagePair_, ff_core_String.String_dropLast(mainFile_, ".ff".length), (((_c) => {
212
+ ff_compiler_Builder.build_(system_, ff_compiler_JsEmitter.EmitBrowser(), resolvedDependencies_.mainPackagePair_, ff_core_List.List_map(mainFiles_, ((_w1) => {
213
+ return ff_core_String.String_dropLast(_w1, ".ff".length)
214
+ })), (((_c) => {
198
215
  return ff_compiler_Dependencies.ResolvedDependencies(_c.mainPackagePair_, _c.packages_, fixedPackagePaths_, _c.singleFilePackages_)
199
216
  }))(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))
200
217
  }
@@ -368,7 +385,7 @@ const pkg_ = import$0;
368
385
  pkg_.exec([packageFile_.absolutePath_, "--out-path", outputPath_.absolutePath_, "--target", ff_core_List.List_join(targets_, ",")])
369
386
  }
370
387
 
371
- export async function build_$(system_, emitTarget_, mainPackage_, mainModule_, resolvedDependencies_, compilerModulePath_, tempPath_, jsOutputPath_, printMeasurements_, moduleCache_, $task) {
388
+ export async function build_$(system_, emitTarget_, mainPackage_, mainModules_, resolvedDependencies_, compilerModulePath_, tempPath_, jsOutputPath_, printMeasurements_, moduleCache_, $task) {
372
389
  if((await ff_core_Path.Path_exists$(tempPath_, false, false, false, $task))) {
373
390
  (await ff_core_Path.Path_delete$(tempPath_, 0, 100, $task))
374
391
  };
@@ -377,7 +394,10 @@ const jsPathFile_ = (await ff_core_Path.Path_slash$(tempPath_, "js", $task));
377
394
  (await ff_core_Path.Path_createDirectory$(jsPathFile_, true, $task));
378
395
  const success_ = (await ff_core_Core.do_$((async ($task) => {
379
396
  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));
380
- (await ff_compiler_Compiler.Compiler_emit$(compiler_, mainPackage_, mainModule_, true, $task));
397
+ for(let for_a = mainModules_, for_i = 0, for_l = for_a.length; for_i < for_l; for_i++) {
398
+ const mainModule_ = for_a[for_i];
399
+ (await ff_compiler_Compiler.Compiler_emit$(compiler_, mainPackage_, mainModule_, true, $task))
400
+ };
381
401
  if(printMeasurements_) {
382
402
  (await ff_compiler_Compiler.Compiler_printMeasurements$(compiler_, $task))
383
403
  };
@@ -429,15 +449,29 @@ if((result_.exitCode_ !== 0)) {
429
449
  }
430
450
  }
431
451
 
432
- export async function buildViaBuildSystem_$(system_, fireflyPath_, mainFile_, target_, $task) {
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)), (await ff_core_NodeSystem.NodeSystem_path$(system_, mainFile_, $task)), $task));
452
+ export async function buildViaBuildSystem_$(system_, fireflyPath_, mainFiles_, target_, $task) {
453
+ const mainPaths_ = (await ff_core_List.List_map$(mainFiles_, (async (_w1, $task) => {
454
+ return (await ff_core_Path.Path_absolute$(ff_core_Option.Option_grab((await ff_core_Path.Path_parent$((await ff_core_NodeSystem.NodeSystem_path$(system_, _w1, $task)), $task))), $task))
455
+ }), $task));
456
+ {
457
+ const if_o = ff_core_List.List_find(mainPaths_, ((_w1) => {
458
+ return (_w1 !== ff_core_List.List_grabFirst(mainPaths_))
459
+ }))
460
+ if(if_o.Some) {
461
+ const path_ = if_o.value_;
462
+ ff_core_Core.panic_(((("Can't build multiple main files in different directories: " + path_) + " vs. ") + ff_core_List.List_grabFirst(mainPaths_)))
463
+ }
464
+ };
465
+ 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)), (await ff_core_NodeSystem.NodeSystem_path$(system_, ff_core_List.List_grabFirst(mainFiles_), $task)), $task));
434
466
  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)
435
467
  ? resolvedDependencies_.packagePaths_
436
468
  : ff_core_Map.Map_add(resolvedDependencies_.packagePaths_, ff_compiler_Syntax.PackagePair("ff", "core"), (await ff_core_Path.Path_slash$(fireflyPath_, "core", $task)), ff_compiler_Syntax.ff_core_Ordering_Order$ff_compiler_Syntax_PackagePair));
437
469
  if((target_ !== "browser")) {
438
470
  ff_core_Core.panic_("buildViaBuildSystem is currently limited to browser target only - the restriction can be lifted")
439
471
  };
440
- (await ff_compiler_Builder.build_$(system_, ff_compiler_JsEmitter.EmitBrowser(), resolvedDependencies_.mainPackagePair_, ff_core_String.String_dropLast(mainFile_, ".ff".length), (((_c) => {
472
+ (await ff_compiler_Builder.build_$(system_, ff_compiler_JsEmitter.EmitBrowser(), resolvedDependencies_.mainPackagePair_, ff_core_List.List_map(mainFiles_, ((_w1) => {
473
+ return ff_core_String.String_dropLast(_w1, ".ff".length)
474
+ })), (((_c) => {
441
475
  return ff_compiler_Dependencies.ResolvedDependencies(_c.mainPackagePair_, _c.packages_, fixedPackagePaths_, _c.singleFilePackages_)
442
476
  }))(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))
443
477
  }
@@ -614,5 +648,3 @@ const pkg_ = import$0;
614
648
 
615
649
 
616
650
 
617
-
618
-
@@ -264,7 +264,7 @@ return ff_compiler_Dictionaries.Dictionaries_processModule(ff_compiler_Dictionar
264
264
  }
265
265
 
266
266
  export function Compiler_emit(self_, packagePair_, moduleName_, isMainModule_) {
267
- ff_compiler_ModuleCache.ModuleCache_cacheEmittedModule(self_.cache_, self_.packagePaths_, packagePair_, moduleName_, ((path_) => {
267
+ ff_compiler_ModuleCache.ModuleCache_cacheEmittedModule(self_.cache_, self_.packagePaths_, packagePair_, moduleName_, isMainModule_, ((path_) => {
268
268
  ff_compiler_Compiler.Compiler_measure(self_, "Emit", packagePair_, moduleName_, (() => {
269
269
  const module_ = ff_compiler_Compiler.Compiler_infer(self_, packagePair_, moduleName_);
270
270
  const otherModules_ = ff_core_List.List_map(ff_compiler_Compiler.Compiler_imports(self_, module_), ((i_) => {
@@ -273,13 +273,23 @@ ff_compiler_Compiler.Compiler_emit(self_, i_.packagePair_, newModuleName_, false
273
273
  return ff_compiler_Compiler.Compiler_infer(self_, i_.packagePair_, newModuleName_)
274
274
  }));
275
275
  const allModules_ = [module_, ...otherModules_];
276
- const js_ = ff_compiler_JsEmitter.JsEmitter_emitModule(ff_compiler_JsEmitter.new_(allModules_, self_.emitTarget_, isMainModule_, ff_core_Option.Option_map(self_.compilerModulePath_, ((_w1) => {
276
+ const emitter_ = ff_compiler_JsEmitter.new_(allModules_, self_.emitTarget_, isMainModule_, ff_core_Option.Option_map(self_.compilerModulePath_, ((_w1) => {
277
277
  return ff_core_Path.Path_url(_w1)
278
- })), packagePair_, moduleName_), packagePair_, module_);
278
+ })), packagePair_, moduleName_);
279
+ const js_ = ff_compiler_JsEmitter.JsEmitter_emitModule(emitter_, packagePair_, module_);
279
280
  const jsPath_ = ff_core_Path.Path_slash(ff_core_Path.Path_slash(self_.jsOutputPath_, packagePair_.group_), packagePair_.name_);
280
281
  const jsFile_ = ff_core_Path.Path_slash(jsPath_, (moduleName_ + ".mjs"));
281
282
  ff_core_Path.Path_createDirectory(jsPath_, true);
282
- return ff_core_Path.Path_writeText(jsFile_, js_)
283
+ ff_core_Path.Path_writeText(jsFile_, js_);
284
+ if(isMainModule_) {
285
+ return ff_core_Option.Some((function() {
286
+ const runJs_ = ff_compiler_JsEmitter.JsEmitter_emitRun(emitter_, moduleName_, module_.functions_, packagePair_, ((packagePair_.group_ === "ff") && (packagePair_.name_ === "compiler")));
287
+ const jsRunFile_ = ff_core_Path.Path_slash(jsPath_, (moduleName_ + ".run.mjs"));
288
+ return ff_core_Path.Path_writeText(jsRunFile_, ff_core_List.List_join(ff_core_List.List_map(runJs_, ((_w1) => {
289
+ return (_w1 + "\n")
290
+ })), ""))
291
+ })())
292
+ } else return ff_core_Option.None()
283
293
  }))
284
294
  }))
285
295
  }
@@ -405,7 +415,7 @@ return ff_compiler_Dictionaries.Dictionaries_processModule(ff_compiler_Dictionar
405
415
  }
406
416
 
407
417
  export async function Compiler_emit$(self_, packagePair_, moduleName_, isMainModule_, $task) {
408
- (await ff_compiler_ModuleCache.ModuleCache_cacheEmittedModule$(self_.cache_, self_.packagePaths_, packagePair_, moduleName_, (async (path_, $task) => {
418
+ (await ff_compiler_ModuleCache.ModuleCache_cacheEmittedModule$(self_.cache_, self_.packagePaths_, packagePair_, moduleName_, isMainModule_, (async (path_, $task) => {
409
419
  (await ff_compiler_Compiler.Compiler_measure$(self_, "Emit", packagePair_, moduleName_, (async ($task) => {
410
420
  const module_ = (await ff_compiler_Compiler.Compiler_infer$(self_, packagePair_, moduleName_, $task));
411
421
  const otherModules_ = (await ff_core_List.List_map$((await ff_compiler_Compiler.Compiler_imports$(self_, module_, $task)), (async (i_, $task) => {
@@ -414,17 +424,25 @@ const newModuleName_ = ff_core_String.String_dropLast(i_.file_, ".ff".length);
414
424
  return (await ff_compiler_Compiler.Compiler_infer$(self_, i_.packagePair_, newModuleName_, $task))
415
425
  }), $task));
416
426
  const allModules_ = [module_, ...otherModules_];
417
- const js_ = ff_compiler_JsEmitter.JsEmitter_emitModule(ff_compiler_JsEmitter.new_(allModules_, self_.emitTarget_, isMainModule_, (await ff_core_Option.Option_map$(self_.compilerModulePath_, (async (_w1, $task) => {
427
+ const emitter_ = ff_compiler_JsEmitter.new_(allModules_, self_.emitTarget_, isMainModule_, (await ff_core_Option.Option_map$(self_.compilerModulePath_, (async (_w1, $task) => {
418
428
  return (await ff_core_Path.Path_url$(_w1, $task))
419
- }), $task)), packagePair_, moduleName_), packagePair_, module_);
429
+ }), $task)), packagePair_, moduleName_);
430
+ const js_ = ff_compiler_JsEmitter.JsEmitter_emitModule(emitter_, packagePair_, module_);
420
431
  const jsPath_ = (await ff_core_Path.Path_slash$((await ff_core_Path.Path_slash$(self_.jsOutputPath_, packagePair_.group_, $task)), packagePair_.name_, $task));
421
432
  const jsFile_ = (await ff_core_Path.Path_slash$(jsPath_, (moduleName_ + ".mjs"), $task));
422
433
  (await ff_core_Path.Path_createDirectory$(jsPath_, true, $task));
423
- return (await ff_core_Path.Path_writeText$(jsFile_, js_, $task))
434
+ (await ff_core_Path.Path_writeText$(jsFile_, js_, $task));
435
+ if(isMainModule_) {
436
+ return ff_core_Option.Some((await (async function() {
437
+ const runJs_ = ff_compiler_JsEmitter.JsEmitter_emitRun(emitter_, moduleName_, module_.functions_, packagePair_, ((packagePair_.group_ === "ff") && (packagePair_.name_ === "compiler")));
438
+ const jsRunFile_ = (await ff_core_Path.Path_slash$(jsPath_, (moduleName_ + ".run.mjs"), $task));
439
+ return (await ff_core_Path.Path_writeText$(jsRunFile_, ff_core_List.List_join(ff_core_List.List_map(runJs_, ((_w1) => {
440
+ return (_w1 + "\n")
441
+ })), ""), $task))
442
+ })()))
443
+ } else return ff_core_Option.None()
424
444
  }), $task))
425
445
  }), $task))
426
446
  }
427
447
 
428
448
 
429
-
430
-
@@ -415,5 +415,3 @@ if(ff_core_Equal.notEquals_(newDependencies_, [], ff_core_List.ff_core_Equal_Equ
415
415
  }
416
416
 
417
417
 
418
-
419
-
@@ -130,5 +130,3 @@ return (await body_($task))
130
130
  }
131
131
 
132
132
 
133
-
134
-
@@ -1052,5 +1052,3 @@ throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_core_Serial
1052
1052
  }
1053
1053
  }
1054
1054
  };
1055
-
1056
-
@@ -1093,5 +1093,3 @@ throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_core_Serial
1093
1093
  }
1094
1094
  }
1095
1095
  };
1096
-
1097
-