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":
|
par on "quray":
|
||||||
Peer.is_connected("qurara")
|
Peer.is_connected("qurara")
|
||||||
if isOnline:
|
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 scalaTestV = "3.2.7" // TODO update version for scala 3-RC3
|
||||||
val fs2V = "3.0.2"
|
val fs2V = "3.0.2"
|
||||||
val catsEffectV = "3.1.0"
|
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 declineV = "2.0.0-RC1" // Scala3 issue: https://github.com/bkirwi/decline/issues/260
|
||||||
|
val declineEnumV = "1.3.0"
|
||||||
|
|
||||||
name := "aqua-hll"
|
name := "aqua-hll"
|
||||||
|
|
||||||
val commons = Seq(
|
val commons = Seq(
|
||||||
baseAquaVersion := "0.1.1",
|
baseAquaVersion := "0.1.1",
|
||||||
version := baseAquaVersion.value + "-" + sys.env.getOrElse("BUILD_NUMBER", "SNAPSHOT"),
|
version := baseAquaVersion.value + "-" + sys.env.getOrElse("BUILD_NUMBER", "SNAPSHOT"),
|
||||||
scalaVersion := dottyVersion,
|
scalaVersion := dottyVersion,
|
||||||
libraryDependencies += "org.scalatest" %% "scalatest" % scalaTestV % Test,
|
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)
|
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 / mainClass := Some("aqua.AquaCli"),
|
||||||
assembly / assemblyJarName := "aqua-cli-" + version.value + ".jar",
|
assembly / assemblyJarName := "aqua-cli-" + version.value + ".jar",
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
"com.monovore" %% "decline" % declineV,
|
"com.monovore" %% "decline" % declineV,
|
||||||
"com.monovore" %% "decline-effect" % declineV,
|
"com.monovore" %% "decline-effect" % declineV,
|
||||||
"org.typelevel" %% "cats-effect" % catsEffectV,
|
"org.typelevel" %% "cats-effect" % catsEffectV,
|
||||||
"co.fs2" %% "fs2-core" % fs2V,
|
"co.fs2" %% "fs2-core" % fs2V,
|
||||||
"co.fs2" %% "fs2-io" % 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)
|
.dependsOn(semantics, `backend-air`, `backend-ts`, linker)
|
||||||
@ -63,6 +76,9 @@ lazy val parser = project
|
|||||||
lazy val linker = project
|
lazy val linker = project
|
||||||
.settings(commons: _*)
|
.settings(commons: _*)
|
||||||
.settings(
|
.settings(
|
||||||
|
libraryDependencies ++= Seq(
|
||||||
|
"org.wvlet.airframe" %% "airframe-log" % airframeLogV
|
||||||
|
)
|
||||||
)
|
)
|
||||||
.dependsOn(parser)
|
.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 aqua.model.transform.BodyConfig
|
||||||
import cats.data.Validated
|
import cats.data.Validated
|
||||||
import cats.effect.{Concurrent, ExitCode, IO, IOApp}
|
import cats.effect._
|
||||||
import cats.effect.std.Console
|
import cats.effect.std.Console
|
||||||
import com.monovore.decline.Opts
|
|
||||||
import com.monovore.decline.effect.CommandIOApp
|
|
||||||
import cats.syntax.apply._
|
import cats.syntax.apply._
|
||||||
import cats.syntax.functor._
|
import cats.syntax.functor._
|
||||||
|
import com.monovore.decline.Opts
|
||||||
|
import com.monovore.decline.effect.CommandIOApp
|
||||||
import fs2.io.file.Files
|
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] =
|
// if there is `--help` or `--version` flag - show help and version
|
||||||
Opts.option[Path]("input", "Path to the input directory that contains your .aqua files", "i")
|
// otherwise continue program execution
|
||||||
|
h.map(_ => helpAndExit) orElse v.map(_ => versionAndExit) getOrElse
|
||||||
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) =>
|
|
||||||
AquaCompiler
|
AquaCompiler
|
||||||
.compileFilesTo[F](
|
.compileFilesTo[F](
|
||||||
input,
|
input,
|
||||||
@ -66,21 +57,21 @@ object AquaCli extends IOApp {
|
|||||||
ExitCode.Success
|
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](
|
CommandIOApp.run[IO](
|
||||||
"aqua-c",
|
"aqua-c",
|
||||||
"Aquamarine compiler",
|
"Aquamarine compiler",
|
||||||
helpFlag = true,
|
helpFlag = false,
|
||||||
Option(getClass.getPackage.getImplementationVersion).filter(_.nonEmpty)
|
None
|
||||||
)(
|
)(
|
||||||
mainOpts[IO],
|
main[IO],
|
||||||
// Weird ugly hack: in case version flag or help flag is present, ignore other options,
|
args
|
||||||
// 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
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,13 @@ import aqua.parser.lexer.Token
|
|||||||
import aqua.parser.lift.FileSpan
|
import aqua.parser.lift.FileSpan
|
||||||
import aqua.semantics.{CompilerState, Semantics}
|
import aqua.semantics.{CompilerState, Semantics}
|
||||||
import cats.Applicative
|
import cats.Applicative
|
||||||
import cats.data.{Chain, EitherT, NonEmptyChain, Validated, ValidatedNec}
|
import cats.data._
|
||||||
import cats.effect.kernel.Concurrent
|
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.flatMap._
|
||||||
|
import cats.syntax.functor._
|
||||||
|
import cats.syntax.monoid._
|
||||||
import cats.syntax.show._
|
import cats.syntax.show._
|
||||||
|
import fs2.io.file.Files
|
||||||
import fs2.text
|
import fs2.text
|
||||||
|
|
||||||
import java.nio.file.Path
|
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
|
package aqua
|
||||||
|
|
||||||
import aqua.model.transform.BodyConfig
|
import aqua.model.transform.BodyConfig
|
||||||
import cats.effect.{IO, IOApp}
|
|
||||||
import cats.data.Validated
|
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
|
import java.nio.file.Paths
|
||||||
|
|
||||||
object Test extends IOApp.Simple {
|
object Test extends IOApp.Simple {
|
||||||
|
|
||||||
|
implicit def logger[F[_]: Sync]: SelfAwareStructuredLogger[F] =
|
||||||
|
Slf4jLogger.getLogger[F]
|
||||||
|
|
||||||
override def run: IO[Unit] =
|
override def run: IO[Unit] =
|
||||||
AquaCompiler
|
AquaCompiler
|
||||||
.compileFilesTo[IO](
|
.compileFilesTo[IO](
|
||||||
|
@ -3,10 +3,11 @@ package aqua.linker
|
|||||||
import cats.data.{NonEmptyChain, Validated, ValidatedNec}
|
import cats.data.{NonEmptyChain, Validated, ValidatedNec}
|
||||||
import cats.kernel.{Monoid, Semigroup}
|
import cats.kernel.{Monoid, Semigroup}
|
||||||
import cats.syntax.monoid._
|
import cats.syntax.monoid._
|
||||||
|
import wvlet.log.LogSupport
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
|
|
||||||
object Linker {
|
object Linker extends LogSupport {
|
||||||
|
|
||||||
@tailrec
|
@tailrec
|
||||||
def iter[I, E, T: Semigroup](
|
def iter[I, E, T: Semigroup](
|
||||||
@ -18,29 +19,31 @@ object Linker {
|
|||||||
case Nil => Right(proc)
|
case Nil => Right(proc)
|
||||||
case _ =>
|
case _ =>
|
||||||
val (canHandle, postpone) = mods.partition(_.dependsOn.keySet.forall(proc.contains))
|
val (canHandle, postpone) = mods.partition(_.dependsOn.keySet.forall(proc.contains))
|
||||||
println("ITERATE, can handle: " + canHandle.map(_.id))
|
debug("ITERATE, can handle: " + canHandle.map(_.id))
|
||||||
println(s"proc = ${proc.keySet}")
|
debug(s"proc = ${proc.keySet}")
|
||||||
|
|
||||||
if (canHandle.isEmpty && postpone.nonEmpty)
|
if (canHandle.isEmpty && postpone.nonEmpty)
|
||||||
Left(cycleError(postpone))
|
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(
|
iter(
|
||||||
postpone,
|
postpone,
|
||||||
// TODO can be done in parallel
|
// TODO can be done in parallel
|
||||||
canHandle.foldLeft(proc) { case (acc, m) =>
|
folded,
|
||||||
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))
|
|
||||||
},
|
|
||||||
cycleError
|
cycleError
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def apply[I, E, T: Monoid](
|
def apply[I, E, T: Monoid](
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package aqua.parser.expr
|
package aqua.parser.expr
|
||||||
|
|
||||||
import aqua.parser.Ast.Tree
|
import aqua.parser.Ast.Tree
|
||||||
import aqua.parser.lexer.Token.` \n+`
|
import aqua.parser.lexer.Token._
|
||||||
import aqua.parser.{Expr, ParserError}
|
|
||||||
import aqua.parser.lift.LiftParser
|
import aqua.parser.lift.LiftParser
|
||||||
import cats.{Comonad, Eval}
|
import aqua.parser.{Expr, ParserError}
|
||||||
import cats.data.{Chain, NonEmptyChain, Validated, ValidatedNec}
|
import cats.data.{Chain, NonEmptyChain, Validated, ValidatedNec}
|
||||||
import cats.free.Cofree
|
import cats.free.Cofree
|
||||||
import cats.parse.{Parser => P}
|
import cats.parse.{Parser => P}
|
||||||
|
import cats.{Comonad, Eval}
|
||||||
|
|
||||||
case class RootExpr[F[_]]() extends Expr[F](RootExpr)
|
case class RootExpr[F[_]]() extends Expr[F](RootExpr)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user