refactor: introduce decline to integrate command-line parsing with cats-effect
This commit is contained in:
@@ -9,7 +9,6 @@
|
|||||||
//> using dep org.typelevel::cats-effect::3.5.7
|
//> using dep org.typelevel::cats-effect::3.5.7
|
||||||
//> using dep com.monovore::decline::2.5.0
|
//> using dep com.monovore::decline::2.5.0
|
||||||
//> using dep com.monovore::decline-effect::2.5.0
|
//> using dep com.monovore::decline-effect::2.5.0
|
||||||
//> using dep com.github.scopt::scopt::4.1.0
|
|
||||||
//> using test.dep org.scalatest::scalatest::3.2.19
|
//> using test.dep org.scalatest::scalatest::3.2.19
|
||||||
//> using dep org.typelevel::cats-effect-testing-scalatest::1.6.0
|
//> using dep org.typelevel::cats-effect-testing-scalatest::1.6.0
|
||||||
|
|
||||||
|
|||||||
@@ -3,40 +3,40 @@ package wacc
|
|||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import cats.data.Chain
|
import cats.data.Chain
|
||||||
import parsley.{Failure, Success}
|
import parsley.{Failure, Success}
|
||||||
import scopt.OParser
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
import cats.implicits.*
|
import cats.implicits.*
|
||||||
|
|
||||||
import assemblyIR as asm
|
|
||||||
import cats.effect.IO
|
import cats.effect.IO
|
||||||
import cats.effect.IOApp
|
import cats.effect.ExitCode
|
||||||
|
|
||||||
|
import com.monovore.decline._
|
||||||
|
import com.monovore.decline.effect._
|
||||||
|
import com.monovore.decline.Argument
|
||||||
|
|
||||||
|
import assemblyIR as asm
|
||||||
|
|
||||||
|
|
||||||
case class CliConfig(
|
case class CliConfig(
|
||||||
file: File = new File(".")
|
file: File = new File(".")
|
||||||
)
|
)
|
||||||
|
|
||||||
val cliBuilder = OParser.builder[CliConfig]
|
given Argument[File] = Argument.from("file") { str =>
|
||||||
val cliParser = {
|
val file = File(str)
|
||||||
import cliBuilder._
|
(
|
||||||
OParser.sequence(
|
Option.when(file.exists())(file).toValidNel(s"File '${file.getAbsolutePath}' does not exist"),
|
||||||
programName("wacc-compiler"),
|
Option
|
||||||
help('h', "help")
|
.when(file.isFile())(file)
|
||||||
.text("Prints this help message"),
|
.toValidNel(s"File '${file.getAbsolutePath}' must be a regular file"),
|
||||||
arg[File]("<file>")
|
Option.when(file.getName.endsWith(".wacc"))(file).toValidNel("File must have .wacc extension")
|
||||||
.text("Input WACC source file")
|
).mapN((_, _, _) => file)
|
||||||
.required()
|
|
||||||
.action((f, c) => c.copy(file = f))
|
|
||||||
.validate(f =>
|
|
||||||
if (!f.exists) failure("File does not exist")
|
|
||||||
else if (!f.isFile) failure("File must be a regular file")
|
|
||||||
else if (!f.getName.endsWith(".wacc"))
|
|
||||||
failure("File must have .wacc extension")
|
|
||||||
else success
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val cliCommand: Command[File] =
|
||||||
|
Command("wacc-compiler", "Compile WACC programs") {
|
||||||
|
Opts.argument[File]("file")
|
||||||
|
}
|
||||||
|
|
||||||
def frontend(
|
def frontend(
|
||||||
contents: String
|
contents: String
|
||||||
)(using stdout: PrintStream): IO[Either[Int, microWacc.Program]] = {
|
)(using stdout: PrintStream): IO[Either[Int, microWacc.Program]] = {
|
||||||
@@ -87,13 +87,18 @@ def compile(filename: String, outFile: Option[File] = None)(using
|
|||||||
)
|
)
|
||||||
} yield exitCode
|
} yield exitCode
|
||||||
|
|
||||||
object Main extends IOApp.Simple {
|
object Main
|
||||||
override def run: IO[Unit] =
|
extends CommandIOApp(
|
||||||
OParser.parse(cliParser, sys.env.getOrElse("WACC_ARGS", "").split(" "), CliConfig()).traverse_ {
|
name = "wacc-compiler",
|
||||||
config =>
|
header = "the ultimate wacc compiler",
|
||||||
compile(
|
version = "1.0"
|
||||||
config.file.getAbsolutePath,
|
) {
|
||||||
outFile = Some(File(".", config.file.getName.stripSuffix(".wacc") + ".s"))
|
def main: Opts[IO[ExitCode]] =
|
||||||
)
|
Opts.argument[File]("file").map { file =>
|
||||||
|
compile(
|
||||||
|
file.getAbsolutePath,
|
||||||
|
outFile = Some(File(".", file.getName.stripSuffix(".wacc") + ".s"))
|
||||||
|
).map(ExitCode(_)) // turn the int into exit code for compatibility with commandioapp
|
||||||
|
// https://ben.kirw.in/decline/effect.html
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user