feat: initial parallel type-checker implementation

This commit is contained in:
2025-03-14 04:09:34 +00:00
parent 42515abf2a
commit 53d47fda63
5 changed files with 322 additions and 283 deletions

View File

@@ -1,6 +1,5 @@
package wacc
import scala.collection.mutable
import cats.data.{Chain, NonEmptyList}
import parsley.{Failure, Success}
@@ -19,6 +18,7 @@ import org.typelevel.log4cats.Logger
import assemblyIR as asm
import cats.data.ValidatedNel
import java.io.File
import cats.data.NonEmptySeq
/*
TODO:
@@ -71,18 +71,15 @@ val outputOpt: Opts[Option[Path]] =
def frontend(
contents: String,
file: File
): IO[Either[NonEmptyList[Error], microWacc.Program]] =
): IO[Either[NonEmptySeq[Error], microWacc.Program]] =
parser.parse(contents) match {
case Failure(msg) => IO.pure(Left(NonEmptyList.one(Error.SyntaxError(file, msg))))
case Failure(msg) => IO.pure(Left(NonEmptySeq.one(Error.SyntaxError(file, msg))))
case Success(fn) =>
val partialProg = fn(file)
given errors: mutable.Builder[Error, List[Error]] = List.newBuilder
for {
(prog, renameErrors) <- renamer.rename(partialProg)
_ = errors.addAll(renameErrors.toList)
typedProg = typeChecker.check(prog, errors)
res = errors.result.toNel.toLeft(typedProg)
(typedProg, errors) <- semantics.check(partialProg)
res = NonEmptySeq.fromSeq(errors.iterator.toSeq).map(Left(_)).getOrElse(Right(typedProg))
} yield res
}
@@ -103,12 +100,19 @@ def compile(
// TODO: path, file , the names are confusing (when Path is the type but we are working with files)
def writeOutputFile(typedProg: microWacc.Program, outputPath: Path): IO[Unit] =
writer.writeTo(backend(typedProg), outputPath) *>
logger.info(s"Success: ${outputPath.toAbsolutePath}")
val backendStart = System.nanoTime()
val asmLines = backend(typedProg)
val backendEnd = System.nanoTime()
writer.writeTo(asmLines, outputPath) *>
logAction(s"Backend time (${filePath.toRealPath()}): ${(backendEnd - backendStart).toFloat / 1e6} ms") *>
logAction(s"Success: ${outputPath.toAbsolutePath}")
def processProgram(contents: String, file: File, outDir: Path): IO[Int] =
val frontendStart = System.nanoTime()
for {
frontendResult <- frontend(contents, file)
frontendEnd = System.nanoTime()
_ <- logAction(s"Frontend time (${filePath.toRealPath()}): ${(frontendEnd - frontendStart).toFloat / 1e6} ms")
res <- frontendResult match {
case Left(errors) =>
val code = errors.map(err => err.exitCode).toList.min