Skip to content

Commit

Permalink
Add feature flags jsNode and jsWeb (#454)
Browse files Browse the repository at this point in the history
  • Loading branch information
b-studios authored Jul 30, 2024
2 parents a77f41e + 1b240ff commit 77772aa
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 7 deletions.
2 changes: 1 addition & 1 deletion effekt/js/src/main/scala/effekt/Backend.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package effekt

class Backend {
val compiler = generator.js.JavaScript()
val compiler = generator.js.JavaScriptWeb()
val runner = ()
}
3 changes: 2 additions & 1 deletion effekt/jvm/src/main/scala/effekt/Backend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ case class Backend[E](name: String, compiler: Compiler[E], runner: Runner[E])
object Backend {

def backend(name: String): Backend[_] = name match {
case "js" => Backend("js", js.JavaScript(), JSRunner)
case "js" => Backend("js", js.JavaScriptNode(), JSNodeRunner)
case "js-web" => Backend("js-web", js.JavaScriptWeb(), JSWebRunner)
case "chez-monadic" => Backend("chez-monadic", chez.ChezSchemeMonadic(), ChezMonadicRunner)
case "chez-callcc" => Backend("chez-callcc", chez.ChezSchemeCallCC(), ChezCallCCRunner)
case "chez-lift" => Backend("chez-lift", chez.ChezSchemeLift(), ChezLiftRunner)
Expand Down
2 changes: 1 addition & 1 deletion effekt/jvm/src/main/scala/effekt/EffektConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class EffektConfig(args: Seq[String]) extends REPLConfig(args.takeWhile(_ != "--
)

val backend: ScallopOption[Backend[_]] = choice(
choices = List("js", "chez-callcc", "chez-monadic", "chez-lift", "llvm", "ml"),
choices = List("js", "js-web", "chez-callcc", "chez-monadic", "chez-lift", "llvm", "ml"),
name = "backend",
descr = "The backend that should be used",
default = Some("js"),
Expand Down
39 changes: 38 additions & 1 deletion effekt/jvm/src/main/scala/effekt/Runner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ trait Runner[Executable] {
}
}

object JSRunner extends Runner[String] {
object JSNodeRunner extends Runner[String] {
import scala.sys.process.Process

val extension = "js"
Expand Down Expand Up @@ -163,6 +163,43 @@ object JSRunner extends Runner[String] {
createScript(exePath, "node", jsMainFilePath)
}
}
object JSWebRunner extends Runner[String] {
import scala.sys.process.Process

val extension = "js"

def standardLibraryPath(root: File): File = root / "libraries" / "common"

override def prelude: List[String] = List("effekt", "option", "list", "result", "exception", "array", "string", "ref")

def checkSetup(): Either[String, Unit] =
Left("Running js-web code directly is not supported. Use `--compile` to generate a js file / `--build` to generate a html file.")

/**
* Creates an openable `.html` file besides the given `.js` file ([[path]])
* and then errors out, printing it's path.
*/
def build(path: String)(using C: Context): String =
import java.nio.file.Path
val out = C.config.outputPath().getAbsolutePath
val jsFilePath = (out / path).unixPath
val jsFileName = jsFilePath.split("/").last
val htmlFilePath = jsFilePath.stripSuffix(s".$extension") + ".html"
val mainName = "$" + jsFileName.stripSuffix(".js") + ".main"
val htmlContent =
s"""<!DOCTYPE html>
|<html>
| <body>
| <script type="text/javascript" src="${jsFileName}"></script>
| <script type="text/javascript">
| window.onload=${mainName};
| </script>
| </body>
|</html>
|""".stripMargin
IO.createFile(htmlFilePath, htmlContent, false)
C.abort(s"Open file://${htmlFilePath} in your browser or include ${jsFilePath}.")
}

trait ChezRunner extends Runner[String] {
val extension = "ss"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import kiama.output.PrettyPrinterTypes.Document
import kiama.util.Source


class JavaScript extends Compiler[String] {
class JavaScript(additionalFeatureFlags: List[String] = Nil) extends Compiler[String] {

// Implementation of the Compiler Interface:
// -----------------------------------------
def extension = ".js"

override def supportedFeatureFlags: List[String] = TransformerMonadicWhole.jsFeatureFlags
override def supportedFeatureFlags: List[String] = additionalFeatureFlags ++ TransformerMonadicWhole.jsFeatureFlags

override def prettyIR(source: Source, stage: Stage)(using Context): Option[Document] = stage match {
case Stage.Core => Core(source).map { res => core.PrettyPrinter.format(res.core) }
Expand Down Expand Up @@ -62,3 +62,5 @@ class JavaScript extends Compiler[String] {
private def pretty(stmts: List[js.Stmt]): Document =
js.PrettyPrinter.format(stmts)
}
class JavaScriptWeb extends JavaScript(List("jsWeb")) {}
class JavaScriptNode extends JavaScript(List("jsNode")) {}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ case class Module(name: JSName, imports: List[Import], exports: List[Export], st
js.Destruct(names, js.Call(Variable(JSName("require")), List(JsString(s"./${ file }"))))
}

val exportStatement = js.Assign(RawExpr("module.exports"),
val exportStatement = js.Assign(RawExpr(s"(typeof module != \"undefined\" && module !== null ? module : {}).exports = ${name.name}"),
js.Object(exports.map { e => e.name -> e.expr })
)

Expand Down

0 comments on commit 77772aa

Please sign in to comment.