mirror of
https://github.com/fluencelabs/aqua.git
synced 2025-03-15 11:40:50 +00:00
Bug fixes (#127)
This commit is contained in:
parent
720de27f14
commit
9f5c0d64ed
@ -20,4 +20,4 @@ func betterMessage(relay: string):
|
||||
par on "quray":
|
||||
Peer.is_connected("qurara")
|
||||
if isOnline:
|
||||
Test.doSomething()
|
||||
Test.doSomething()
|
||||
|
34
build.sbt
34
build.sbt
@ -12,15 +12,23 @@ val monocleV = "3.0.0-M5"
|
||||
val scalaTestV = "3.2.7" // TODO update version for scala 3-RC3
|
||||
val fs2V = "3.0.2"
|
||||
val catsEffectV = "3.1.0"
|
||||
val airframeLogV = "21.5.4"
|
||||
val log4catsV = "2.1.1"
|
||||
val enumeratumV = "1.6.1"
|
||||
val slf4jV = "1.7.25"
|
||||
val declineV = "2.0.0-RC1" // Scala3 issue: https://github.com/bkirwi/decline/issues/260
|
||||
val declineEnumV = "1.3.0"
|
||||
|
||||
name := "aqua-hll"
|
||||
|
||||
val commons = Seq(
|
||||
baseAquaVersion := "0.1.1",
|
||||
version := baseAquaVersion.value + "-" + sys.env.getOrElse("BUILD_NUMBER", "SNAPSHOT"),
|
||||
scalaVersion := dottyVersion,
|
||||
libraryDependencies += "org.scalatest" %% "scalatest" % scalaTestV % Test,
|
||||
baseAquaVersion := "0.1.1",
|
||||
version := baseAquaVersion.value + "-" + sys.env.getOrElse("BUILD_NUMBER", "SNAPSHOT"),
|
||||
scalaVersion := dottyVersion,
|
||||
libraryDependencies ++= Seq(
|
||||
"org.typelevel" %% "log4cats-core" % "2.1.1",
|
||||
"org.scalatest" %% "scalatest" % scalaTestV % Test
|
||||
),
|
||||
addCompilerPlugin("org.typelevel" %% "kind-projector" % "0.11.3" cross CrossVersion.full)
|
||||
)
|
||||
|
||||
@ -33,11 +41,16 @@ lazy val cli = project
|
||||
assembly / mainClass := Some("aqua.AquaCli"),
|
||||
assembly / assemblyJarName := "aqua-cli-" + version.value + ".jar",
|
||||
libraryDependencies ++= Seq(
|
||||
"com.monovore" %% "decline" % declineV,
|
||||
"com.monovore" %% "decline-effect" % declineV,
|
||||
"org.typelevel" %% "cats-effect" % catsEffectV,
|
||||
"co.fs2" %% "fs2-core" % fs2V,
|
||||
"co.fs2" %% "fs2-io" % fs2V
|
||||
"com.monovore" %% "decline" % declineV,
|
||||
"com.monovore" %% "decline-effect" % declineV,
|
||||
"org.typelevel" %% "cats-effect" % catsEffectV,
|
||||
"co.fs2" %% "fs2-core" % fs2V,
|
||||
"co.fs2" %% "fs2-io" % fs2V,
|
||||
"org.typelevel" %% "log4cats-slf4j" % log4catsV,
|
||||
"org.wvlet.airframe" %% "airframe-log" % airframeLogV,
|
||||
"com.beachape" %% "enumeratum" % enumeratumV,
|
||||
"org.slf4j" % "slf4j-jdk14" % slf4jV,
|
||||
"com.monovore" %% "decline-enumeratum" % declineEnumV
|
||||
)
|
||||
)
|
||||
.dependsOn(semantics, `backend-air`, `backend-ts`, linker)
|
||||
@ -63,6 +76,9 @@ lazy val parser = project
|
||||
lazy val linker = project
|
||||
.settings(commons: _*)
|
||||
.settings(
|
||||
libraryDependencies ++= Seq(
|
||||
"org.wvlet.airframe" %% "airframe-log" % airframeLogV
|
||||
)
|
||||
)
|
||||
.dependsOn(parser)
|
||||
|
||||
|
117
cli/src/main/scala/aqua/AppOps.scala
Normal file
117
cli/src/main/scala/aqua/AppOps.scala
Normal file
@ -0,0 +1,117 @@
|
||||
package aqua
|
||||
|
||||
import cats.Functor
|
||||
import cats.data.Validated.{Invalid, Valid}
|
||||
import cats.data.{Validated, ValidatedNel}
|
||||
import cats.effect.ExitCode
|
||||
import cats.effect.std.Console
|
||||
import cats.syntax.functor._
|
||||
import cats.syntax.traverse._
|
||||
import com.monovore.decline.Opts.help
|
||||
import com.monovore.decline.enumeratum._
|
||||
import com.monovore.decline.{Opts, Visibility}
|
||||
|
||||
import java.nio.file.Path
|
||||
|
||||
object AppOps {
|
||||
|
||||
val helpOpt: Opts[Unit] =
|
||||
Opts.flag("help", help = "Display this help text", "h", Visibility.Partial).asHelp.as(())
|
||||
|
||||
val versionOpt: Opts[Unit] =
|
||||
Opts.flag("version", help = "Show version", "v", Visibility.Partial)
|
||||
|
||||
val logLevelOpt: Opts[LogLevel] =
|
||||
Opts.option[LogLevel]("log-level", help = "Set log level").withDefault(LogLevel.Info)
|
||||
|
||||
def checkPath: Path => ValidatedNel[String, Path] = { p =>
|
||||
Validated
|
||||
.fromEither(Validated.catchNonFatal {
|
||||
val f = p.toFile
|
||||
if (f.exists() && f.isDirectory) {
|
||||
Right(p)
|
||||
} else {
|
||||
Left(s"There is no path '${p.toString}' or it is not a directory")
|
||||
}
|
||||
}.toEither.left.map(t => s"An error occurred on imports reading: ${t.getMessage}").flatten)
|
||||
.toValidatedNel
|
||||
}
|
||||
|
||||
val inputOpts: Opts[Path] =
|
||||
Opts
|
||||
.option[Path](
|
||||
"input",
|
||||
"Path to the input directory that contains your .aqua files. It can only be a directory",
|
||||
"i"
|
||||
)
|
||||
.mapValidated(checkPath)
|
||||
|
||||
val outputOpts: Opts[Path] =
|
||||
Opts.option[Path]("output", "Path to the output directory", "o").mapValidated(checkPath)
|
||||
|
||||
val importOpts: Opts[LazyList[Path]] =
|
||||
Opts
|
||||
.options[Path]("import", "Path to the directory to import from", "m")
|
||||
.mapValidated { ps =>
|
||||
val checked = ps
|
||||
.map(p => {
|
||||
Validated.catchNonFatal {
|
||||
val f = p.toFile
|
||||
if (f.exists() && f.isDirectory) {
|
||||
Right(p)
|
||||
} else {
|
||||
Left(s"There is no path ${p.toString} or it is not a directory")
|
||||
}
|
||||
}
|
||||
})
|
||||
.toList
|
||||
|
||||
checked.map {
|
||||
case Validated.Valid(pE) =>
|
||||
pE match {
|
||||
case Right(p) =>
|
||||
Validated.Valid(p)
|
||||
case Left(e) =>
|
||||
Validated.Invalid(e)
|
||||
}
|
||||
case Validated.Invalid(e) =>
|
||||
Validated.Invalid(s"Error occurred on imports reading: ${e.getMessage}")
|
||||
}.traverse {
|
||||
case Valid(a) => Validated.validNel(a)
|
||||
case Invalid(e) => Validated.invalidNel(e)
|
||||
}.map(_.to(LazyList))
|
||||
}
|
||||
.withDefault(LazyList.empty)
|
||||
|
||||
val compileToAir: Opts[Boolean] =
|
||||
Opts
|
||||
.flag("air", "Generate .air file instead of typescript", "a")
|
||||
.map(_ => true)
|
||||
.withDefault(false)
|
||||
|
||||
val noRelay: Opts[Boolean] =
|
||||
Opts
|
||||
.flag("no-relay", "Do not generate a pass through the relay node")
|
||||
.map(_ => true)
|
||||
.withDefault(false)
|
||||
|
||||
val noXorWrapper: Opts[Boolean] =
|
||||
Opts
|
||||
.flag("no-xor", "Do not generate a wrapper that catches and displays errors")
|
||||
.map(_ => true)
|
||||
.withDefault(false)
|
||||
|
||||
lazy val versionStr: String =
|
||||
Option(getClass.getPackage.getImplementationVersion).filter(_.nonEmpty).getOrElse("no version")
|
||||
|
||||
def versionAndExit[F[_]: Console: Functor]: F[ExitCode] = Console[F]
|
||||
.println(versionStr)
|
||||
.as(ExitCode.Success)
|
||||
|
||||
def helpAndExit[F[_]: Console: Functor]: F[ExitCode] = Console[F]
|
||||
.println(help)
|
||||
.as(ExitCode.Success)
|
||||
|
||||
def wrapWithOption[A](opt: Opts[A]): Opts[Option[A]] =
|
||||
opt.map(v => Some(v)).withDefault(None)
|
||||
}
|
@ -2,51 +2,42 @@ package aqua
|
||||
|
||||
import aqua.model.transform.BodyConfig
|
||||
import cats.data.Validated
|
||||
import cats.effect.{Concurrent, ExitCode, IO, IOApp}
|
||||
import cats.effect._
|
||||
import cats.effect.std.Console
|
||||
import com.monovore.decline.Opts
|
||||
import com.monovore.decline.effect.CommandIOApp
|
||||
import cats.syntax.apply._
|
||||
import cats.syntax.functor._
|
||||
import com.monovore.decline.Opts
|
||||
import com.monovore.decline.effect.CommandIOApp
|
||||
import fs2.io.file.Files
|
||||
import org.typelevel.log4cats.slf4j.Slf4jLogger
|
||||
import org.typelevel.log4cats.{Logger, SelfAwareStructuredLogger}
|
||||
import wvlet.log.{LogSupport, Logger => WLogger}
|
||||
|
||||
import java.nio.file.Path
|
||||
object AquaCli extends IOApp with LogSupport {
|
||||
import AppOps._
|
||||
|
||||
object AquaCli extends IOApp {
|
||||
def main[F[_]: Concurrent: Files: Console: Logger]: Opts[F[ExitCode]] = {
|
||||
versionOpt
|
||||
.as(
|
||||
versionAndExit
|
||||
) orElse helpOpt.as(
|
||||
helpAndExit
|
||||
) orElse (
|
||||
inputOpts,
|
||||
importOpts,
|
||||
outputOpts,
|
||||
compileToAir,
|
||||
noRelay,
|
||||
noXorWrapper,
|
||||
wrapWithOption(helpOpt),
|
||||
wrapWithOption(versionOpt),
|
||||
logLevelOpt
|
||||
).mapN { case (input, imports, output, toAir, noRelay, noXor, h, v, logLevel) =>
|
||||
WLogger.setDefaultLogLevel(LogLevel.toLogLevel(logLevel))
|
||||
|
||||
val inputOpts: Opts[Path] =
|
||||
Opts.option[Path]("input", "Path to the input directory that contains your .aqua files", "i")
|
||||
|
||||
val outputOpts: Opts[Path] =
|
||||
Opts.option[Path]("output", "Path to the output directory", "o")
|
||||
|
||||
val importOpts: Opts[LazyList[Path]] =
|
||||
Opts
|
||||
.options[Path]("import", "Path to the directory to import from", "m")
|
||||
.map(_.toList.to(LazyList))
|
||||
.withDefault(LazyList.empty)
|
||||
|
||||
val compileToAir: Opts[Boolean] =
|
||||
Opts
|
||||
.flag("air", "Generate .air file instead of typescript", "a")
|
||||
.map(_ => true)
|
||||
.withDefault(false)
|
||||
|
||||
val noRelay: Opts[Boolean] =
|
||||
Opts
|
||||
.flag("no-relay", "Do not generate a pass through the relay node")
|
||||
.map(_ => true)
|
||||
.withDefault(false)
|
||||
|
||||
val noXorWrapper: Opts[Boolean] =
|
||||
Opts
|
||||
.flag("no-xor", "Do not generate a wrapper that catches and displays errors")
|
||||
.map(_ => true)
|
||||
.withDefault(false)
|
||||
|
||||
def mainOpts[F[_]: Console: Concurrent: Files]: Opts[F[ExitCode]] =
|
||||
(inputOpts, importOpts, outputOpts, compileToAir, noRelay, noXorWrapper).mapN {
|
||||
case (input, imports, output, toAir, noRelay, noXor) =>
|
||||
// if there is `--help` or `--version` flag - show help and version
|
||||
// otherwise continue program execution
|
||||
h.map(_ => helpAndExit) orElse v.map(_ => versionAndExit) getOrElse
|
||||
AquaCompiler
|
||||
.compileFilesTo[F](
|
||||
input,
|
||||
@ -66,21 +57,21 @@ object AquaCli extends IOApp {
|
||||
ExitCode.Success
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override def run(args: List[String]): IO[ExitCode] = {
|
||||
|
||||
implicit def logger[F[_]: Sync]: SelfAwareStructuredLogger[F] =
|
||||
Slf4jLogger.getLogger[F]
|
||||
|
||||
override def run(args: List[String]): IO[ExitCode] =
|
||||
CommandIOApp.run[IO](
|
||||
"aqua-c",
|
||||
"Aquamarine compiler",
|
||||
helpFlag = true,
|
||||
Option(getClass.getPackage.getImplementationVersion).filter(_.nonEmpty)
|
||||
helpFlag = false,
|
||||
None
|
||||
)(
|
||||
mainOpts[IO],
|
||||
// Weird ugly hack: in case version flag or help flag is present, ignore other options,
|
||||
// be it correct or not
|
||||
args match {
|
||||
case _ if args.contains("-v") || args.contains("--version") => "-v" :: Nil
|
||||
case _ if args.contains("-h") || args.contains("--help") => "-h" :: Nil
|
||||
case _ => args
|
||||
}
|
||||
main[IO],
|
||||
args
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -10,13 +10,13 @@ import aqua.parser.lexer.Token
|
||||
import aqua.parser.lift.FileSpan
|
||||
import aqua.semantics.{CompilerState, Semantics}
|
||||
import cats.Applicative
|
||||
import cats.data.{Chain, EitherT, NonEmptyChain, Validated, ValidatedNec}
|
||||
import cats.data._
|
||||
import cats.effect.kernel.Concurrent
|
||||
import fs2.io.file.Files
|
||||
import cats.syntax.monoid._
|
||||
import cats.syntax.functor._
|
||||
import cats.syntax.flatMap._
|
||||
import cats.syntax.functor._
|
||||
import cats.syntax.monoid._
|
||||
import cats.syntax.show._
|
||||
import fs2.io.file.Files
|
||||
import fs2.text
|
||||
|
||||
import java.nio.file.Path
|
||||
|
30
cli/src/main/scala/aqua/LogLevel.scala
Normal file
30
cli/src/main/scala/aqua/LogLevel.scala
Normal file
@ -0,0 +1,30 @@
|
||||
package aqua
|
||||
|
||||
import enumeratum._
|
||||
import wvlet.log.{LogLevel => WLogLevel}
|
||||
|
||||
sealed trait LogLevel extends EnumEntry with EnumEntry.Lowercase
|
||||
|
||||
object LogLevel extends Enum[LogLevel] {
|
||||
case object Debug extends LogLevel
|
||||
case object Trace extends LogLevel
|
||||
case object Info extends LogLevel
|
||||
case object Off extends LogLevel
|
||||
case object Warn extends LogLevel
|
||||
case object Error extends LogLevel
|
||||
case object All extends LogLevel
|
||||
|
||||
val values = findValues
|
||||
|
||||
def toLogLevel(logLevel: LogLevel): WLogLevel = {
|
||||
logLevel match {
|
||||
case LogLevel.Debug => WLogLevel.DEBUG
|
||||
case LogLevel.Trace => WLogLevel.TRACE
|
||||
case LogLevel.Info => WLogLevel.INFO
|
||||
case LogLevel.Off => WLogLevel.OFF
|
||||
case LogLevel.Warn => WLogLevel.WARN
|
||||
case LogLevel.Error => WLogLevel.ERROR
|
||||
case LogLevel.All => WLogLevel.ALL
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,18 @@
|
||||
package aqua
|
||||
|
||||
import aqua.model.transform.BodyConfig
|
||||
import cats.effect.{IO, IOApp}
|
||||
import cats.data.Validated
|
||||
import cats.effect.{IO, IOApp, Sync}
|
||||
import org.typelevel.log4cats.SelfAwareStructuredLogger
|
||||
import org.typelevel.log4cats.slf4j.Slf4jLogger
|
||||
|
||||
import java.nio.file.Paths
|
||||
|
||||
object Test extends IOApp.Simple {
|
||||
|
||||
implicit def logger[F[_]: Sync]: SelfAwareStructuredLogger[F] =
|
||||
Slf4jLogger.getLogger[F]
|
||||
|
||||
override def run: IO[Unit] =
|
||||
AquaCompiler
|
||||
.compileFilesTo[IO](
|
||||
|
@ -3,10 +3,11 @@ package aqua.linker
|
||||
import cats.data.{NonEmptyChain, Validated, ValidatedNec}
|
||||
import cats.kernel.{Monoid, Semigroup}
|
||||
import cats.syntax.monoid._
|
||||
import wvlet.log.LogSupport
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
||||
object Linker {
|
||||
object Linker extends LogSupport {
|
||||
|
||||
@tailrec
|
||||
def iter[I, E, T: Semigroup](
|
||||
@ -18,29 +19,31 @@ object Linker {
|
||||
case Nil => Right(proc)
|
||||
case _ =>
|
||||
val (canHandle, postpone) = mods.partition(_.dependsOn.keySet.forall(proc.contains))
|
||||
println("ITERATE, can handle: " + canHandle.map(_.id))
|
||||
println(s"proc = ${proc.keySet}")
|
||||
debug("ITERATE, can handle: " + canHandle.map(_.id))
|
||||
debug(s"proc = ${proc.keySet}")
|
||||
|
||||
if (canHandle.isEmpty && postpone.nonEmpty)
|
||||
Left(cycleError(postpone))
|
||||
else
|
||||
else {
|
||||
val folded = canHandle.foldLeft(proc) { case (acc, m) =>
|
||||
debug(m.id + " dependsOn " + m.dependsOn.keySet)
|
||||
val deps: T => T =
|
||||
m.dependsOn.keySet.map(acc).foldLeft[T => T](identity) { case (fAcc, f) =>
|
||||
debug("COMBINING ONE TIME ")
|
||||
t => {
|
||||
debug(s"call combine ${t}")
|
||||
fAcc(t) |+| f(t)
|
||||
}
|
||||
}
|
||||
acc + (m.id -> m.body.compose(deps))
|
||||
}
|
||||
iter(
|
||||
postpone,
|
||||
// TODO can be done in parallel
|
||||
canHandle.foldLeft(proc) { case (acc, m) =>
|
||||
println(m.id + " dependsOn " + m.dependsOn.keySet)
|
||||
val deps: T => T =
|
||||
m.dependsOn.keySet.map(acc).foldLeft[T => T](identity) { case (fAcc, f) =>
|
||||
println("COMBINING ONE TIME ")
|
||||
t => {
|
||||
println(s"call combine ${t}")
|
||||
fAcc(t) |+| f(t)
|
||||
}
|
||||
}
|
||||
acc + (m.id -> m.body.compose(deps))
|
||||
},
|
||||
folded,
|
||||
cycleError
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def apply[I, E, T: Monoid](
|
||||
|
@ -1,13 +1,13 @@
|
||||
package aqua.parser.expr
|
||||
|
||||
import aqua.parser.Ast.Tree
|
||||
import aqua.parser.lexer.Token.` \n+`
|
||||
import aqua.parser.{Expr, ParserError}
|
||||
import aqua.parser.lexer.Token._
|
||||
import aqua.parser.lift.LiftParser
|
||||
import cats.{Comonad, Eval}
|
||||
import aqua.parser.{Expr, ParserError}
|
||||
import cats.data.{Chain, NonEmptyChain, Validated, ValidatedNec}
|
||||
import cats.free.Cofree
|
||||
import cats.parse.{Parser => P}
|
||||
import cats.{Comonad, Eval}
|
||||
|
||||
case class RootExpr[F[_]]() extends Expr[F](RootExpr)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user