feat: introduction of logger to eliminate printstreams

This commit is contained in:
Jonny
2025-03-01 01:19:50 +00:00
parent d214723f35
commit 667fbf4949
4 changed files with 43 additions and 26 deletions

View File

@@ -4,7 +4,6 @@ import scala.collection.mutable
import cats.data.Chain
import parsley.{Failure, Success}
import java.io.File
import java.io.PrintStream
import cats.implicits.*
import cats.effect.IO
@@ -14,6 +13,9 @@ import com.monovore.decline._
import com.monovore.decline.effect._
import com.monovore.decline.Argument
import org.typelevel.log4cats.slf4j.Slf4jLogger
import org.typelevel.log4cats.Logger
import assemblyIR as asm
given Argument[File] = Argument.from("file") { str =>
@@ -32,30 +34,33 @@ val cliCommand: Command[File] =
Opts.argument[File]("file")
}
given logger: Logger[IO] = Slf4jLogger.getLogger[IO]
def frontend(
contents: String
)(using stdout: PrintStream): IO[Either[Int, microWacc.Program]] = {
IO(parser.parse(contents)).map {
): IO[Either[Int, microWacc.Program]] = {
IO(parser.parse(contents)).flatMap {
case Failure(msg) =>
stdout.println(msg)
Left(100) // Syntax error
logger.error(s"Syntax error: $msg").as(Left(100))
case Success(prog) =>
given errors: mutable.Builder[Error, List[Error]] = List.newBuilder
given errorContent: String = contents
val (names, funcs) = renamer.rename(prog)
given ctx: typeChecker.TypeCheckerCtx = typeChecker.TypeCheckerCtx(names, funcs, errors)
val typedProg = typeChecker.check(prog)
if (errors.result.isEmpty) Right(typedProg)
if (errors.result.isEmpty) IO.pure(Right(typedProg))
else {
errors.result.foreach(printError)
Left(errors.result.view.map {
val exitCode = errors.result.view.map {
case _: Error.InternalError => 201
case _ => 200
}.max)
}.max
logger.error(s"Semantic errors:\n${errors.result.mkString("\n")}") *> IO.pure(
Left(exitCode)
)
}
}
}
@@ -64,21 +69,18 @@ val s = "enter an integer to echo"
def backend(typedProg: microWacc.Program): Chain[asm.AsmLine] =
asmGenerator.generateAsm(typedProg)
def compile(filename: String, outFile: Option[File] = None)(using
stdout: PrintStream = Console.out
): IO[Int] =
def compile(filename: String, outFile: Option[File] = None): IO[Int] =
for {
contents <- IO(os.read(os.Path(filename)))
_ <- logger.info(s"Compiling file: $filename")
result <- frontend(contents)
exitCode <- result.fold(
IO.pure, // Return error code (handles Left case)
code => logger.error(s"Compilation failed for $filename\nExit code: $code").as(code),
typedProg =>
IO {
writer.writeTo(
backend(typedProg),
PrintStream(outFile.getOrElse(File(filename.stripSuffix(".wacc") + ".s")))
)
}.as(0) // Compilation succeeded
val outputFile = outFile.getOrElse(File(filename.stripSuffix(".wacc") + ".s"))
writer.writeTo(backend(typedProg), outputFile) *> logger
.info(s"Compilation succeeded: $filename")
.as(0)
)
} yield exitCode