mirror of
https://github.com/fluencelabs/aqua.git
synced 2025-06-24 03:51:32 +00:00
Module and Use expressions (#245)
* Module and Use expressions * UseFromExpr * ImportFromExpr * PubExpr * Export, declares * Collecting all the needed info WIP * Got all the needed data * Tests fixed * HeaderSem * HeaderSem wip * Everything except `export`/`declares` should be working * Compile bug fixed * Fix readme: cli/assembly * Handle declares, exports * Compile only exports in AquaRes * Call services imported from modules * Import consts, types, services from modules * Resolve arrows from modules * Bugfix
This commit is contained in:
@ -9,26 +9,29 @@ import cats.free.Cofree
|
||||
import cats.parse.Parser0 as P0
|
||||
import cats.{Comonad, Eval}
|
||||
|
||||
case class Ast[F[_]](head: Ast.Head[F], tree: Ast.Tree[F]) {
|
||||
case class Ast[S[_]](head: Ast.Head[S], tree: Ast.Tree[S]) {
|
||||
|
||||
def cata[T](folder: (Expr[F], Chain[T]) => Eval[T]): Eval[T] =
|
||||
Cofree.cata[Chain, Expr[F], T](tree)(folder)
|
||||
def cata[T](folder: (Expr[S], Chain[T]) => Eval[T]): Eval[T] =
|
||||
Cofree.cata[Chain, Expr[S], T](tree)(folder)
|
||||
|
||||
def cataHead[T](folder: (HeaderExpr[S], Chain[T]) => Eval[T]): Eval[T] =
|
||||
Cofree.cata[Chain, HeaderExpr[S], T](head)(folder)
|
||||
}
|
||||
|
||||
object Ast {
|
||||
type Tree[F[_]] = Cofree[Chain, Expr[F]]
|
||||
type Head[F[_]] = Cofree[Chain, HeaderExpr[F]]
|
||||
type Tree[S[_]] = Cofree[Chain, Expr[S]]
|
||||
type Head[S[_]] = Cofree[Chain, HeaderExpr[S]]
|
||||
|
||||
def parser[F[_]: LiftParser: Comonad](): P0[ValidatedNec[ParserError[F], Ast[F]]] =
|
||||
(HeadExpr.ast[F].with1 ~ RootExpr.ast[F]()).map { case (head, bodyMaybe) =>
|
||||
def parser[S[_]: LiftParser: Comonad](): P0[ValidatedNec[ParserError[S], Ast[S]]] =
|
||||
(HeadExpr.ast[S].with1 ~ RootExpr.ast[S]()).map { case (head, bodyMaybe) =>
|
||||
bodyMaybe.map(Ast(head, _))
|
||||
}
|
||||
|
||||
def fromString[F[_]: LiftParser: Comonad](script: String): ValidatedNec[ParserError[F], Ast[F]] =
|
||||
parser[F]()
|
||||
def fromString[S[_]: LiftParser: Comonad](script: String): ValidatedNec[ParserError[S], Ast[S]] =
|
||||
parser[S]()
|
||||
.parseAll(script) match {
|
||||
case Right(value) => value
|
||||
case Left(e) => Validated.invalidNec(LexerError[F](e.wrapErr))
|
||||
case Left(e) => Validated.invalidNec(LexerError[S](e.wrapErr))
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ case class AbilityIdExpr[F[_]](ability: Ability[F], id: Value[F])
|
||||
object AbilityIdExpr extends Expr.Leaf {
|
||||
|
||||
override def p[F[_]: LiftParser: Comonad]: P[AbilityIdExpr[F]] =
|
||||
((Ability.ab[F] <* ` `) ~ Value.`value`).map { case (ability, id) =>
|
||||
((Ability.dotted[F] <* ` `) ~ Value.`value`).map { case (ability, id) =>
|
||||
AbilityIdExpr(ability, id)
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ object CallArrowExpr extends Expr.Leaf {
|
||||
|
||||
override def p[F[_]: LiftParser: Comonad]: P[CallArrowExpr[F]] =
|
||||
((comma(Name.p[F]) <* ` <- `).backtrack.?.with1 ~
|
||||
((Ability.ab[F] <* `.`).?.with1 ~
|
||||
((Ability.dotted[F] <* `.`).?.with1 ~
|
||||
Name.p[F] ~
|
||||
comma0(Value.`value`[F].surroundedBy(`/s*`)).between(`(` <* `/s*`, `/s*` *> `)`))).map {
|
||||
case (variables, ((ability, funcName), args)) =>
|
||||
|
20
parser/src/main/scala/aqua/parser/head/ExportExpr.scala
Normal file
20
parser/src/main/scala/aqua/parser/head/ExportExpr.scala
Normal file
@ -0,0 +1,20 @@
|
||||
package aqua.parser.head
|
||||
|
||||
import aqua.parser.lexer.Token.*
|
||||
import aqua.parser.lexer.{Literal, Value, Token}
|
||||
import aqua.parser.lift.LiftParser
|
||||
import cats.Comonad
|
||||
import cats.data.NonEmptyList
|
||||
import cats.parse.Parser
|
||||
import cats.syntax.either.*
|
||||
|
||||
case class ExportExpr[F[_]](pubs: NonEmptyList[FromExpr.NameOrAbAs[F]]) extends HeaderExpr[F] {
|
||||
override def token: Token[F] =
|
||||
pubs.head.bimap(_._1, _._1).fold(identity, identity)
|
||||
}
|
||||
|
||||
object ExportExpr extends HeaderExpr.Leaf {
|
||||
|
||||
override def p[F[_]: LiftParser: Comonad]: Parser[ExportExpr[F]] =
|
||||
(`_export` *> ` `) *> comma(FromExpr.nameOrAbAs[F]).map(ExportExpr(_))
|
||||
}
|
11
parser/src/main/scala/aqua/parser/head/FilenameExpr.scala
Normal file
11
parser/src/main/scala/aqua/parser/head/FilenameExpr.scala
Normal file
@ -0,0 +1,11 @@
|
||||
package aqua.parser.head
|
||||
|
||||
import aqua.parser.lexer.{Literal, Token}
|
||||
|
||||
trait FilenameExpr[F[_]] extends HeaderExpr[F] {
|
||||
def filename: Literal[F]
|
||||
|
||||
override def token: Token[F] = filename
|
||||
|
||||
def fileValue: String = filename.value.drop(1).dropRight(1)
|
||||
}
|
22
parser/src/main/scala/aqua/parser/head/FromExpr.scala
Normal file
22
parser/src/main/scala/aqua/parser/head/FromExpr.scala
Normal file
@ -0,0 +1,22 @@
|
||||
package aqua.parser.head
|
||||
|
||||
import aqua.parser.lexer.Token._
|
||||
import aqua.parser.lexer.{Ability, Name}
|
||||
import aqua.parser.lift.LiftParser
|
||||
import cats.Comonad
|
||||
import cats.data.NonEmptyList
|
||||
import cats.parse.Parser as P
|
||||
|
||||
trait FromExpr[F[_]] {
|
||||
def imports: NonEmptyList[FromExpr.NameOrAbAs[F]]
|
||||
}
|
||||
|
||||
object FromExpr {
|
||||
type NameOrAbAs[F[_]] = Either[Name.As[F], Ability.As[F]]
|
||||
|
||||
def nameOrAbAs[F[_]: LiftParser: Comonad]: P[NameOrAbAs[F]] =
|
||||
Name.nameAs[F].map(Left(_)) | Ability.abAs[F].map(Right(_))
|
||||
|
||||
def importFrom[F[_]: LiftParser: Comonad]: P[NonEmptyList[NameOrAbAs[F]]] =
|
||||
comma[NameOrAbAs[F]](nameOrAbAs[F]) <* ` ` <* `from`
|
||||
}
|
@ -3,25 +3,30 @@ package aqua.parser.head
|
||||
import aqua.parser.Ast
|
||||
import aqua.parser.lexer.Token.` \n+`
|
||||
import aqua.parser.lift.LiftParser
|
||||
import aqua.parser.lift.LiftParser.*
|
||||
import cats.{Comonad, Eval}
|
||||
import cats.data.Chain
|
||||
import cats.free.Cofree
|
||||
import cats.parse.{Parser => P, Parser0 => P0}
|
||||
import aqua.parser.lexer.Token
|
||||
|
||||
case class HeadExpr[F[_]]() extends HeaderExpr[F]
|
||||
case class HeadExpr[S[_]](token: Token[S]) extends HeaderExpr[S]
|
||||
|
||||
object HeadExpr {
|
||||
|
||||
def headExprs: List[HeaderExpr.Companion] =
|
||||
ImportExpr :: Nil
|
||||
UseFromExpr :: UseExpr :: ImportFromExpr :: ImportExpr :: ExportExpr :: Nil
|
||||
|
||||
def ast[F[_]: LiftParser: Comonad]: P0[Ast.Head[F]] =
|
||||
P.repSep0(P.oneOf(headExprs.map(_.ast[F])), ` \n+`)
|
||||
def ast[S[_]: LiftParser: Comonad]: P0[Ast.Head[S]] =
|
||||
(P.unit.lift0.map(Token.lift) ~ ((ModuleExpr.p[S] <* ` \n+`).? ~
|
||||
P.repSep0(P.oneOf(headExprs.map(_.ast[S].backtrack)), ` \n+`).map(Chain.fromSeq))
|
||||
.surroundedBy(` \n+`.?)
|
||||
.?
|
||||
.map {
|
||||
case Some(exprs) => Chain.fromSeq(exprs)
|
||||
case None => Chain.empty[Ast.Head[F]]
|
||||
}
|
||||
.map(exprs => Cofree(HeadExpr[F](), Eval.now(exprs)))
|
||||
.?).map {
|
||||
case (p, Some((maybeMod, exprs))) =>
|
||||
Cofree(
|
||||
maybeMod.getOrElse(HeadExpr[S](p)),
|
||||
Eval.now(exprs)
|
||||
)
|
||||
case (p, None) => Cofree(HeadExpr[S](p), Eval.now(Chain.nil))
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,23 @@
|
||||
package aqua.parser.head
|
||||
|
||||
import aqua.parser.Ast
|
||||
import aqua.parser.lexer.Token
|
||||
import aqua.parser.lift.LiftParser
|
||||
import cats.{Comonad, Eval}
|
||||
import cats.data.Chain
|
||||
import cats.free.Cofree
|
||||
import cats.parse.{Parser => P}
|
||||
import cats.parse.Parser as P
|
||||
|
||||
trait HeaderExpr[F[_]]
|
||||
trait HeaderExpr[S[_]] {
|
||||
def token: Token[S]
|
||||
}
|
||||
|
||||
object HeaderExpr {
|
||||
|
||||
trait Companion {
|
||||
def p[F[_]: LiftParser: Comonad]: P[HeaderExpr[F]]
|
||||
def p[S[_]: LiftParser: Comonad]: P[HeaderExpr[S]]
|
||||
|
||||
def ast[F[_]: LiftParser: Comonad]: P[Ast.Head[F]]
|
||||
def ast[S[_]: LiftParser: Comonad]: P[Ast.Head[S]]
|
||||
}
|
||||
|
||||
abstract class Leaf extends Companion {
|
||||
|
@ -6,7 +6,7 @@ import aqua.parser.lift.LiftParser
|
||||
import cats.Comonad
|
||||
import cats.parse.Parser
|
||||
|
||||
case class ImportExpr[F[_]](filename: Literal[F]) extends HeaderExpr[F]
|
||||
case class ImportExpr[F[_]](filename: Literal[F]) extends FilenameExpr[F]
|
||||
|
||||
object ImportExpr extends HeaderExpr.Leaf {
|
||||
|
||||
|
21
parser/src/main/scala/aqua/parser/head/ImportFromExpr.scala
Normal file
21
parser/src/main/scala/aqua/parser/head/ImportFromExpr.scala
Normal file
@ -0,0 +1,21 @@
|
||||
package aqua.parser.head
|
||||
|
||||
import aqua.parser.lexer.Token.*
|
||||
import aqua.parser.lexer.{Literal, Value}
|
||||
import aqua.parser.lift.LiftParser
|
||||
import cats.Comonad
|
||||
import cats.data.NonEmptyList
|
||||
import cats.parse.Parser
|
||||
|
||||
case class ImportFromExpr[F[_]](
|
||||
imports: NonEmptyList[FromExpr.NameOrAbAs[F]],
|
||||
filename: Literal[F]
|
||||
) extends FilenameExpr[F] with FromExpr[F]
|
||||
|
||||
object ImportFromExpr extends HeaderExpr.Leaf {
|
||||
|
||||
override def p[F[_]: LiftParser: Comonad]: Parser[HeaderExpr[F]] =
|
||||
(`import` *> FromExpr.importFrom[F].surroundedBy(` `) ~ Value.string[F]).map {
|
||||
case (imports, filename) => ImportFromExpr(imports, filename)
|
||||
}
|
||||
}
|
54
parser/src/main/scala/aqua/parser/head/ModuleExpr.scala
Normal file
54
parser/src/main/scala/aqua/parser/head/ModuleExpr.scala
Normal file
@ -0,0 +1,54 @@
|
||||
package aqua.parser.head
|
||||
|
||||
import aqua.parser.lexer.Token.*
|
||||
import aqua.parser.lexer.Token
|
||||
import aqua.parser.lexer.{Ability, Literal, Name, Value}
|
||||
import aqua.parser.lift.LiftParser
|
||||
import aqua.parser.lift.LiftParser.*
|
||||
import cats.Comonad
|
||||
import cats.parse.Parser
|
||||
|
||||
case class ModuleExpr[F[_]](
|
||||
name: Ability[F],
|
||||
declareAll: Option[Token[F]],
|
||||
declareNames: List[Name[F]],
|
||||
declareCustom: List[Ability[F]]
|
||||
) extends HeaderExpr[F] {
|
||||
override def token: Token[F] = name
|
||||
}
|
||||
|
||||
object ModuleExpr extends HeaderExpr.Leaf {
|
||||
|
||||
type NameOrAb[F[_]] = Either[Name[F], Ability[F]]
|
||||
|
||||
def nameOrAb[F[_]: LiftParser: Comonad]: Parser[NameOrAb[F]] =
|
||||
Name.p[F].map(Left(_)) | Ability.ab[F].map(Right(_))
|
||||
|
||||
def nameOrAbList[F[_]: LiftParser: Comonad]: Parser[List[NameOrAb[F]]] =
|
||||
comma[NameOrAb[F]](nameOrAb[F]).map(_.toList)
|
||||
|
||||
def nameOrAbListOrAll[F[_]: LiftParser: Comonad]: Parser[Either[List[NameOrAb[F]], Token[F]]] =
|
||||
nameOrAbList[F].map(Left(_)) | `star`.lift.map(Token.lift(_)).map(Right(_))
|
||||
|
||||
override def p[F[_]: LiftParser: Comonad]: Parser[ModuleExpr[F]] =
|
||||
(`module` *> ` ` *> Ability.ab[F] ~
|
||||
(` declares ` *> nameOrAbListOrAll[F]).?).map {
|
||||
case (name, None) =>
|
||||
ModuleExpr(name, None, Nil, Nil)
|
||||
case (name, Some(Left(exportMembers))) =>
|
||||
ModuleExpr(
|
||||
name,
|
||||
None,
|
||||
exportMembers.collect { case Left(x) => x },
|
||||
exportMembers.collect { case Right(x) => x }
|
||||
)
|
||||
case (name, Some(Right(point))) =>
|
||||
ModuleExpr(
|
||||
name,
|
||||
Some(point),
|
||||
Nil,
|
||||
Nil
|
||||
)
|
||||
}
|
||||
|
||||
}
|
21
parser/src/main/scala/aqua/parser/head/UseExpr.scala
Normal file
21
parser/src/main/scala/aqua/parser/head/UseExpr.scala
Normal file
@ -0,0 +1,21 @@
|
||||
package aqua.parser.head
|
||||
|
||||
import aqua.parser.lexer.Token.*
|
||||
import aqua.parser.lexer.{Ability, Literal, Value}
|
||||
import aqua.parser.lift.LiftParser
|
||||
import cats.Comonad
|
||||
import cats.parse.Parser
|
||||
|
||||
case class UseExpr[F[_]](
|
||||
filename: Literal[F],
|
||||
asModule: Option[Ability[F]]
|
||||
) extends FilenameExpr[F]
|
||||
|
||||
object UseExpr extends HeaderExpr.Leaf {
|
||||
|
||||
override def p[F[_]: LiftParser: Comonad]: Parser[HeaderExpr[F]] =
|
||||
(`use` *> Value
|
||||
.string[F] ~ (` as ` *> Ability.ab[F]).?).map { case (filename, asModule) =>
|
||||
UseExpr(filename, asModule)
|
||||
}
|
||||
}
|
23
parser/src/main/scala/aqua/parser/head/UseFromExpr.scala
Normal file
23
parser/src/main/scala/aqua/parser/head/UseFromExpr.scala
Normal file
@ -0,0 +1,23 @@
|
||||
package aqua.parser.head
|
||||
|
||||
import aqua.parser.lexer.Token.*
|
||||
import aqua.parser.lexer.{Ability, Literal, Name, Value}
|
||||
import aqua.parser.lift.LiftParser
|
||||
import cats.Comonad
|
||||
import cats.data.NonEmptyList
|
||||
import cats.parse.Parser
|
||||
|
||||
case class UseFromExpr[F[_]](
|
||||
imports: NonEmptyList[FromExpr.NameOrAbAs[F]],
|
||||
filename: Literal[F],
|
||||
asModule: Ability[F]
|
||||
) extends FilenameExpr[F] with FromExpr[F]
|
||||
|
||||
object UseFromExpr extends HeaderExpr.Leaf {
|
||||
|
||||
override def p[F[_]: LiftParser: Comonad]: Parser[HeaderExpr[F]] =
|
||||
(`use` *> FromExpr.importFrom[F].surroundedBy(` `) ~ Value
|
||||
.string[F] ~ (` as ` *> Ability.ab[F])).map { case ((imports, filename), asModule) =>
|
||||
UseFromExpr(imports, filename, asModule)
|
||||
}
|
||||
}
|
@ -15,7 +15,14 @@ case class Ability[F[_]: Comonad](name: F[String]) extends Token[F] {
|
||||
}
|
||||
|
||||
object Ability {
|
||||
type As[F[_]] = (Ability[F], Option[Ability[F]])
|
||||
|
||||
def ab[F[_]: LiftParser: Comonad]: P[Ability[F]] =
|
||||
`Class`.lift.map(Ability(_))
|
||||
|
||||
def dotted[F[_]: LiftParser: Comonad]: P[Ability[F]] =
|
||||
P.repSep(`Class`, `.`).map(_.toList.mkString(".")).lift.map(Ability(_))
|
||||
|
||||
def abAs[F[_]: LiftParser: Comonad]: P[As[F]] =
|
||||
asOpt(ab[F])
|
||||
}
|
||||
|
@ -16,6 +16,15 @@ case class Name[F[_]: Comonad](name: F[String]) extends Token[F] {
|
||||
|
||||
object Name {
|
||||
|
||||
type As[F[_]] = (Name[F], Option[Name[F]])
|
||||
|
||||
def p[F[_]: LiftParser: Comonad]: P[Name[F]] =
|
||||
`name`.lift.map(Name(_))
|
||||
|
||||
def dotted[F[_]: LiftParser: Comonad]: P[Name[F]] =
|
||||
((`Class`.repSep(`.`).map(_.toList.mkString(".")) ~ `.`).?.with1 ~ `name`).string.lift
|
||||
.map(Name(_))
|
||||
|
||||
def nameAs[F[_]: LiftParser: Comonad]: P[As[F]] =
|
||||
asOpt(p[F])
|
||||
}
|
||||
|
@ -25,8 +25,17 @@ object Token {
|
||||
val `const`: P[Unit] = P.string("const")
|
||||
val `data`: P[Unit] = P.string("data")
|
||||
val `import`: P[Unit] = P.string("import")
|
||||
val `module`: P[Unit] = P.string("module")
|
||||
val `declares`: P[Unit] = P.string("declares")
|
||||
val ` declares ` : P[Unit] = `declares`.surroundedBy(` `)
|
||||
val `declare`: P[Unit] = P.string("declare")
|
||||
val `_export`: P[Unit] = P.string("export")
|
||||
val `star`: P[Unit] = P.char('*')
|
||||
val `use`: P[Unit] = P.string("use")
|
||||
val `from`: P[Unit] = P.string("from")
|
||||
val ` from ` : P[Unit] = `from`.surroundedBy(` `)
|
||||
val `as`: P[Unit] = P.string("as")
|
||||
val ` as ` : P[Unit] = `as`.surroundedBy(` `)
|
||||
val `alias`: P[Unit] = P.string("alias")
|
||||
val `service`: P[Unit] = P.string("service")
|
||||
val `func`: P[Unit] = P.string("func")
|
||||
@ -64,7 +73,7 @@ object Token {
|
||||
val `.` : P[Unit] = P.char('.')
|
||||
val `"` : P[Unit] = P.char('"')
|
||||
val `*` : P[Unit] = P.char('*')
|
||||
val exclamation : P[Unit] = P.char('!')
|
||||
val exclamation: P[Unit] = P.char('!')
|
||||
val `[]` : P[Unit] = P.string("[]")
|
||||
val `⊤` : P[Unit] = P.char('⊤')
|
||||
val `⊥` : P[Unit] = P.char('⊥')
|
||||
@ -92,4 +101,7 @@ object Token {
|
||||
|
||||
def comma0[T](p: P[T]): P0[List[T]] =
|
||||
P.repSep0(p, `,` <* ` \n+`.rep0)
|
||||
|
||||
def asOpt[T](p: P[T]): P[(T, Option[T])] =
|
||||
p ~ (` as ` *> p).?
|
||||
}
|
||||
|
@ -54,7 +54,12 @@ case class CustomTypeToken[F[_]: Comonad](name: F[String]) extends DataTypeToken
|
||||
}
|
||||
|
||||
object CustomTypeToken {
|
||||
def ct[F[_]: LiftParser: Comonad]: P[CustomTypeToken[F]] = `Class`.lift.map(CustomTypeToken(_))
|
||||
|
||||
def ct[F[_]: LiftParser: Comonad]: P[CustomTypeToken[F]] =
|
||||
`Class`.lift.map(CustomTypeToken(_))
|
||||
|
||||
def dotted[F[_]: LiftParser: Comonad]: P[CustomTypeToken[F]] =
|
||||
`Class`.repSep(`.`).string.lift.map(CustomTypeToken(_))
|
||||
}
|
||||
|
||||
case class BasicTypeToken[F[_]: Comonad](scalarType: F[ScalarType]) extends DataTypeToken[F] {
|
||||
@ -115,7 +120,7 @@ object DataTypeToken {
|
||||
P.defer(`arraytypedef`[F]) :: P.defer(StreamTypeToken.`streamtypedef`) :: P.defer(
|
||||
OptionTypeToken.`optiontypedef`
|
||||
) :: BasicTypeToken
|
||||
.`basictypedef`[F] :: CustomTypeToken.ct[F] :: Nil
|
||||
.`basictypedef`[F] :: CustomTypeToken.dotted[F] :: Nil
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ case class Literal[F[_]: Comonad](valueToken: F[String], ts: LiteralType) extend
|
||||
object Value {
|
||||
|
||||
def varLambda[F[_]: LiftParser: Comonad]: P[VarLambda[F]] =
|
||||
(Name.p[F] ~ LambdaOp.ops[F].?).map { case (n, l) ⇒
|
||||
(Name.dotted[F] ~ LambdaOp.ops[F].?).map { case (n, l) ⇒
|
||||
VarLambda(n, l.fold[List[LambdaOp[F]]](Nil)(_.toList))
|
||||
}
|
||||
|
||||
|
@ -3,26 +3,26 @@ package aqua.parser.lift
|
||||
import cats.Id
|
||||
import cats.parse.{Parser, Parser0}
|
||||
|
||||
trait LiftParser[F[_]] {
|
||||
def lift[T](p: Parser[T]): Parser[F[T]]
|
||||
trait LiftParser[S[_]] {
|
||||
def lift[T](p: Parser[T]): Parser[S[T]]
|
||||
|
||||
def lift0[T](p0: Parser0[T]): Parser0[F[T]]
|
||||
def lift0[T](p0: Parser0[T]): Parser0[S[T]]
|
||||
|
||||
def wrapErr(e: Parser.Error): F[Parser.Error]
|
||||
def wrapErr(e: Parser.Error): S[Parser.Error]
|
||||
}
|
||||
|
||||
object LiftParser {
|
||||
|
||||
implicit class LiftErrorOps[F[_]: LiftParser, T](e: Parser.Error) {
|
||||
def wrapErr: F[Parser.Error] = implicitly[LiftParser[F]].wrapErr(e)
|
||||
implicit class LiftErrorOps[S[_]: LiftParser, T](e: Parser.Error) {
|
||||
def wrapErr: S[Parser.Error] = implicitly[LiftParser[S]].wrapErr(e)
|
||||
}
|
||||
|
||||
implicit class LiftParserOps[F[_]: LiftParser, T](parser: Parser[T]) {
|
||||
def lift: Parser[F[T]] = implicitly[LiftParser[F]].lift(parser)
|
||||
implicit class LiftParserOps[S[_]: LiftParser, T](parser: Parser[T]) {
|
||||
def lift: Parser[S[T]] = implicitly[LiftParser[S]].lift(parser)
|
||||
}
|
||||
|
||||
implicit class LiftParser0Ops[F[_]: LiftParser, T](parser0: Parser0[T]) {
|
||||
def lift0: Parser0[F[T]] = implicitly[LiftParser[F]].lift0(parser0)
|
||||
implicit class LiftParser0Ops[S[_]: LiftParser, T](parser0: Parser0[T]) {
|
||||
def lift0: Parser0[S[T]] = implicitly[LiftParser[S]].lift0(parser0)
|
||||
}
|
||||
|
||||
object Implicits {
|
||||
|
Reference in New Issue
Block a user