mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 22:50:18 +00:00
Added type argument to parsers
This commit is contained in:
parent
bde8017d31
commit
37f99eb15e
@ -1,8 +1,10 @@
|
||||
package aqua
|
||||
|
||||
import aqua.parse.{ArrowType, Block, DataType, Type}
|
||||
import cats.Id
|
||||
import cats.data.NonEmptyMap
|
||||
import cats.parse.{Parser ⇒ P, Parser0 ⇒ P0}
|
||||
import aqua.parse.lift.LiftParser.Implicits.idLiftParser
|
||||
|
||||
case class Aqua(
|
||||
inputs: Map[String, DataType],
|
||||
@ -12,7 +14,7 @@ case class Aqua(
|
||||
)
|
||||
|
||||
object Aqua {
|
||||
import aqua.parse.Token._
|
||||
import aqua.parse.lexer.Token._
|
||||
|
||||
val `parser`: P0[List[Block]] = P.repSep0(Block.`block`, ` \n*`)
|
||||
val `parser`: P0[List[Block[Id]]] = P.repSep0(Block.`block`[Id], ` \n*`)
|
||||
}
|
||||
|
@ -1,25 +1,28 @@
|
||||
package aqua.parse
|
||||
|
||||
import aqua.parse.DataType.`datatypedef`
|
||||
import aqua.parse.Token._
|
||||
import aqua.parse.lexer.Token._
|
||||
import aqua.parse.Type.{`arrowdef`, `typedef`}
|
||||
import aqua.parse.lift.LiftParser
|
||||
import aqua.parse.lift.LiftParser._
|
||||
import cats.Functor
|
||||
import cats.data.{NonEmptyList, NonEmptyMap}
|
||||
import cats.parse.{Parser ⇒ P}
|
||||
|
||||
sealed trait Block
|
||||
case class DefType(name: String, fields: NonEmptyMap[String, DataType]) extends Block
|
||||
case class DefService(name: String, funcs: NonEmptyMap[String, ArrowType]) extends Block
|
||||
sealed trait Block[F[_]]
|
||||
case class DefType[F[_]](name: F[String], fields: NonEmptyMap[String, DataType]) extends Block[F]
|
||||
case class DefService[F[_]](name: F[String], funcs: NonEmptyMap[String, ArrowType]) extends Block[F]
|
||||
|
||||
case class FuncHead(name: String, args: Map[String, Type], ret: Option[DataType])
|
||||
case class FuncHead[F[_]](name: F[String], args: Map[String, Type], ret: Option[DataType])
|
||||
|
||||
case class DefFunc(head: FuncHead, body: NonEmptyList[FuncOp]) extends Block
|
||||
case class DefFunc[F[_]](head: FuncHead[F], body: NonEmptyList[F[FuncOp[F]]]) extends Block[F]
|
||||
|
||||
object DefType {
|
||||
val `dname`: P[String] = `data` *> ` ` *> Name <* ` `.? <* `:` <* ` \n*`
|
||||
def `dname`[F[_]: LiftParser]: P[F[String]] = `data` *> ` ` *> Name.lift <* ` `.? <* `:` <* ` \n*`
|
||||
|
||||
val `dataname`: P[(String, DataType)] = (`name` <* ` : `) ~ `datatypedef`
|
||||
|
||||
val `deftype`: P[DefType] =
|
||||
def `deftype`[F[_]: LiftParser]: P[DefType[F]] =
|
||||
(`dname` ~ indented(`dataname`)).map {
|
||||
case (n, t) ⇒ DefType(n, t.toNem)
|
||||
}
|
||||
@ -30,17 +33,17 @@ object DefFunc {
|
||||
val `funcdef`: P[(String, ArrowType)] =
|
||||
(`name` <* ` : `) ~ `arrowdef`
|
||||
|
||||
val `funcname`: P[String] = ` `.?.with1 *> `func` *> ` ` *> name <* ` `.?
|
||||
def `funcname`[F[_]: LiftParser]: P[F[String]] = ` `.?.with1 *> `func` *> ` ` *> name.lift <* ` `.?
|
||||
|
||||
val `funcargs`: P[Map[String, Type]] =
|
||||
`(` *> comma0((`name` <* ` : `) ~ `typedef`).map(_.toMap) <* `)`
|
||||
|
||||
val `funchead`: P[FuncHead] =
|
||||
def `funchead`[F[_]: LiftParser]: P[FuncHead[F]] =
|
||||
(`funcname` ~ (`funcargs` ~ (`->` *> `datatypedef`).?)).map {
|
||||
case (n, (a, r)) ⇒ FuncHead(n, a, r)
|
||||
}
|
||||
|
||||
val `deffunc`: P[DefFunc] =
|
||||
def `deffunc`[F[_]: LiftParser: Functor]: P[DefFunc[F]] =
|
||||
((`funchead` <* ` : ` <* ` \n*`) ~ FuncOp.body).map {
|
||||
case (h, b) ⇒ DefFunc(h, b)
|
||||
}
|
||||
@ -50,9 +53,9 @@ object DefFunc {
|
||||
object DefService {
|
||||
import DefFunc.`funcdef`
|
||||
|
||||
val `servicename`: P[String] = `service` *> ` ` *> Name <* ` `.? <* `:` <* ` \n*`
|
||||
def `servicename`[F[_]: LiftParser]: P[F[String]] = `service` *> ` ` *> Name.lift <* ` `.? <* `:` <* ` \n*`
|
||||
|
||||
val `defservice`: P[DefService] =
|
||||
def `defservice`[F[_]: LiftParser]: P[DefService[F]] =
|
||||
(`servicename` ~ indented(`funcdef`).map(_.toNem)).map {
|
||||
case (n, f) ⇒ DefService(n, f)
|
||||
}
|
||||
@ -60,6 +63,6 @@ object DefService {
|
||||
|
||||
object Block {
|
||||
|
||||
val block: P[Block] =
|
||||
def block[F[_]: LiftParser: Functor]: P[Block[F]] =
|
||||
` \n*`.rep0.with1 *> P.oneOf(DefType.`deftype` :: DefService.`defservice` :: DefFunc.`deffunc` :: Nil)
|
||||
}
|
||||
|
@ -1,67 +1,84 @@
|
||||
package aqua.parse
|
||||
|
||||
import aqua.parse.Token._
|
||||
import aqua.parse.lexer.Token._
|
||||
import aqua.parse.lexer.Value
|
||||
import cats.data.NonEmptyList
|
||||
import cats.parse.{Parser ⇒ P}
|
||||
import Value.`value`
|
||||
import aqua.parse.lexer.Value.`value`
|
||||
import aqua.parse.lift.LiftParser
|
||||
import aqua.parse.lift.LiftParser._
|
||||
import cats.Functor
|
||||
import cats.syntax.functor._
|
||||
|
||||
sealed trait FuncOp
|
||||
sealed trait InstrOp extends FuncOp
|
||||
sealed trait FuncOp[F[_]]
|
||||
sealed trait InstrOp[F[_]] extends FuncOp[F]
|
||||
|
||||
sealed trait ExecOp extends InstrOp
|
||||
sealed trait CallOp extends ExecOp
|
||||
sealed trait ExecOp[F[_]] extends InstrOp[F]
|
||||
sealed trait CallOp[F[_]] extends ExecOp[F]
|
||||
|
||||
case class FuncCall(name: String, args: List[Value]) extends CallOp
|
||||
case class AbilityFuncCall(ability: String, call: FuncCall) extends CallOp
|
||||
case class Extract(v: String, from: CallOp) extends ExecOp
|
||||
case class FuncCall[F[_]](name: F[String], args: List[F[Value]]) extends CallOp[F]
|
||||
case class AbilityFuncCall[F[_]](ability: F[String], call: F[FuncCall[F]]) extends CallOp[F]
|
||||
case class Extract[F[_]](v: F[String], from: F[CallOp[F]]) extends ExecOp[F]
|
||||
|
||||
case class On(peer: Value, ops: NonEmptyList[ExecOp]) extends InstrOp
|
||||
case class On[F[_]](peer: F[Value], ops: NonEmptyList[F[ExecOp[F]]]) extends InstrOp[F]
|
||||
|
||||
case class Par(op: InstrOp) extends FuncOp
|
||||
case class Par[F[_]](op: F[InstrOp[F]]) extends FuncOp[F]
|
||||
|
||||
// TODO: can't be in Par, can be in On
|
||||
sealed trait AbilityResolve extends ExecOp
|
||||
case class AbilityId(ability: String, id: Value) extends AbilityResolve
|
||||
sealed trait AbilityResolve[F[_]] extends ExecOp[F]
|
||||
case class AbilityId[F[_]](ability: F[String], id: F[Value]) extends AbilityResolve[F]
|
||||
|
||||
object FuncOp {
|
||||
|
||||
|
||||
val funcCall: P[FuncCall] =
|
||||
(`name` ~ P.repSep0(`value`, `,`).between(`(`, `)`)).map{
|
||||
def funcCall[F[_]: LiftParser]: P[F[FuncCall[F]]] =
|
||||
(`name`.lift ~ P.repSep0(`value`.lift, `,`).between(`(`, `)`)).map {
|
||||
case (fnName, args) ⇒ FuncCall(fnName, args)
|
||||
}
|
||||
}.lift
|
||||
|
||||
val abilityFuncCall: P[AbilityFuncCall] =
|
||||
((`Name` <* `.`) ~ funcCall).map{
|
||||
def abilityFuncCall[F[_]: LiftParser]: P[F[AbilityFuncCall[F]]] =
|
||||
((`Name`.lift <* `.`) ~ funcCall).map {
|
||||
case (abName, fc) ⇒ AbilityFuncCall(abName, fc)
|
||||
}
|
||||
}.lift
|
||||
|
||||
val callOp: P[CallOp] = P.oneOf(funcCall :: abilityFuncCall :: Nil)
|
||||
def callOp[F[_]: LiftParser: Functor]: P[F[CallOp[F]]] =
|
||||
P.oneOf(funcCall[F].map(_.widen[CallOp[F]]) :: abilityFuncCall[F].map(_.widen[CallOp[F]]) :: Nil)
|
||||
|
||||
val extract: P[Extract] = ((`name` <* `<-`) ~ callOp).map{
|
||||
case (v, f) ⇒ Extract(v, f)
|
||||
}
|
||||
def extract[F[_]: LiftParser: Functor]: P[F[Extract[F]]] =
|
||||
((`name`.lift <* `<-`) ~ callOp[F]).map {
|
||||
case (v, f) ⇒ Extract(v, f)
|
||||
}.lift
|
||||
|
||||
val abilityResolve: P[AbilityResolve] = ((`Name` <* ` `) ~ `value`).map{
|
||||
case (n, v) ⇒ AbilityId(n, v)
|
||||
}
|
||||
def abilityResolve[F[_]: LiftParser: Functor]: P[F[AbilityResolve[F]]] =
|
||||
((`Name`.lift <* ` `) ~ `value`.lift).map {
|
||||
case (n, v) ⇒ AbilityId(n, v)
|
||||
}.widen[AbilityResolve[F]].lift
|
||||
|
||||
// TODO can't be in Par, can be in On
|
||||
val execOp: P[ExecOp] = P.oneOf( callOp.backtrack :: abilityResolve.backtrack :: extract :: Nil)
|
||||
def execOp[F[_]: LiftParser: Functor]: P[F[ExecOp[F]]] =
|
||||
P.oneOf(
|
||||
callOp.map(_.widen[ExecOp[F]]).backtrack
|
||||
:: abilityResolve.map(_.widen[ExecOp[F]]).backtrack
|
||||
:: extract.map(_.widen[ExecOp[F]]) :: Nil
|
||||
)
|
||||
|
||||
val startOn: P[Value] = `on` *> ` ` *> `value` <* ` `.? <* `:` <* ` \n*`
|
||||
def startOn[F[_]: LiftParser]: P[F[Value]] = `on` *> ` ` *> `value`.lift <* ` `.? <* `:` <* ` \n*`
|
||||
|
||||
val execOn: P[On] =
|
||||
(startOn ~ indented(execOp)).map{
|
||||
def execOn[F[_]: LiftParser: Functor]: P[F[On[F]]] =
|
||||
(startOn ~ indented(execOp[F])).map {
|
||||
case (v, i) ⇒ On(v, i)
|
||||
}
|
||||
}.lift
|
||||
|
||||
val instrOp: P[InstrOp] = P.oneOf( execOn.backtrack :: execOp :: Nil)
|
||||
def instrOp[F[_]: LiftParser: Functor]: P[F[InstrOp[F]]] =
|
||||
P.oneOf(
|
||||
execOn.map(_.widen[InstrOp[F]]).backtrack
|
||||
:: execOp.map(_.widen[InstrOp[F]]) :: Nil
|
||||
)
|
||||
|
||||
val parOp: P[Par] =
|
||||
`par` *> ` ` *> instrOp.map(Par)
|
||||
def parOp[F[_]: LiftParser: Functor]: P[F[Par[F]]] =
|
||||
(`par` *> ` ` *> instrOp[F].map(Par(_))).lift
|
||||
|
||||
val `funcop`: P[FuncOp] = P.oneOf( parOp.backtrack :: instrOp :: Nil)
|
||||
def `funcop`[F[_]: LiftParser: Functor]: P[F[FuncOp[F]]] =
|
||||
P.oneOf(parOp.map(_.widen[FuncOp[F]]).backtrack :: instrOp.map(_.widen[FuncOp[F]]) :: Nil)
|
||||
|
||||
val body: P[NonEmptyList[FuncOp]] = indented(`funcop`)
|
||||
def body[F[_]: LiftParser: Functor]: P[NonEmptyList[F[FuncOp[F]]]] = indented(`funcop`)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package aqua.parse
|
||||
|
||||
import aqua.parse.Token._
|
||||
import aqua.parse.lexer.Token._
|
||||
import cats.parse.{Parser ⇒ P}
|
||||
|
||||
sealed trait Type
|
||||
|
@ -1,4 +1,4 @@
|
||||
package aqua.parse
|
||||
package aqua.parse.lexer
|
||||
|
||||
import cats.data.NonEmptyList
|
||||
import cats.parse.{Accumulator0, Parser ⇒ P, Parser0 ⇒ P0}
|
@ -1,8 +1,8 @@
|
||||
package aqua.parse
|
||||
package aqua.parse.lexer
|
||||
|
||||
import aqua.parse.Token._
|
||||
import cats.parse.{Parser ⇒ P}
|
||||
import cats.parse.Numbers
|
||||
import aqua.parse.BasicType
|
||||
import aqua.parse.lexer.Token._
|
||||
import cats.parse.{Numbers, Parser ⇒ P}
|
||||
|
||||
sealed trait Value
|
||||
case class VarLambda(name: String, lambda: Option[String]) extends Value
|
23
src/main/scala/aqua/parse/lift/LiftParser.scala
Normal file
23
src/main/scala/aqua/parse/lift/LiftParser.scala
Normal file
@ -0,0 +1,23 @@
|
||||
package aqua.parse.lift
|
||||
|
||||
import cats.Id
|
||||
import cats.parse.Parser
|
||||
|
||||
trait LiftParser[F[_]] {
|
||||
def lift[T](p: Parser[T]): Parser[F[T]]
|
||||
}
|
||||
|
||||
object LiftParser {
|
||||
|
||||
implicit class LiftParserOps[F[_]: LiftParser, T](parser: Parser[T]) {
|
||||
def lift: Parser[F[T]] = implicitly[LiftParser[F]].lift(parser)
|
||||
}
|
||||
|
||||
object Implicits {
|
||||
|
||||
implicit object idLiftParser extends LiftParser[Id] {
|
||||
override def lift[T](p: Parser[T]): Parser[Id[T]] = p
|
||||
}
|
||||
|
||||
}
|
||||
}
|
19
src/main/scala/aqua/parse/lift/Span.scala
Normal file
19
src/main/scala/aqua/parse/lift/Span.scala
Normal file
@ -0,0 +1,19 @@
|
||||
package aqua.parse.lift
|
||||
|
||||
import cats.parse.{Parser ⇒ P}
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
case class Span[T](startIndex: Int, endIndex: Int, value: T)
|
||||
|
||||
object Span {
|
||||
|
||||
implicit object spanLiftParser extends LiftParser[Span] {
|
||||
|
||||
override def lift[T](p: P[T]): P[Span[T]] =
|
||||
(P.index.with1 ~ p ~ P.index).map {
|
||||
case ((s, v), e) ⇒ Span(s, e, v)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +1,59 @@
|
||||
package aqua.parse
|
||||
|
||||
import aqua.parse.lexer.{Literal, VarLambda}
|
||||
import cats.data.NonEmptyList
|
||||
import org.scalatest.EitherValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import aqua.parse.lift.LiftParser.Implicits.idLiftParser
|
||||
import cats.Id
|
||||
|
||||
class FuncOpSpec extends AnyFlatSpec with Matchers with EitherValues {
|
||||
|
||||
"func calls" should "parse func()" in {
|
||||
FuncOp.`funcop`.parseAll("func()") should be(Right(FuncCall("func", Nil)))
|
||||
FuncOp.`funcop`.parseAll("func(arg)") should be(Right(FuncCall("func", VarLambda("arg", None) :: Nil)))
|
||||
FuncOp.`funcop`.parseAll("func(arg)") should be(Right(FuncCall[Id]("func", VarLambda("arg", None) :: Nil)))
|
||||
FuncOp.`funcop`.parseAll("func(arg.doSomeThing)") should be(
|
||||
Right(FuncCall("func", VarLambda("arg", Some("doSomeThing")) :: Nil))
|
||||
Right(FuncCall[Id]("func", VarLambda("arg", Some("doSomeThing")) :: Nil))
|
||||
)
|
||||
FuncOp.`funcop`.parseAll("func(arg.doSomeThing, arg2)") should be(
|
||||
Right(FuncCall("func", VarLambda("arg", Some("doSomeThing")) :: VarLambda("arg2", None) :: Nil))
|
||||
Right(FuncCall[Id]("func", VarLambda("arg", Some("doSomeThing")) :: VarLambda("arg2", None) :: Nil))
|
||||
)
|
||||
}
|
||||
|
||||
"ability calls" should "parse Ab.func()" in {
|
||||
FuncOp.`funcop`.parseAll("Ab.func()") should be(Right(AbilityFuncCall("Ab", FuncCall("func", Nil))))
|
||||
FuncOp.`funcop`.parseAll("Ab.func()") should be(Right(AbilityFuncCall[Id]("Ab", FuncCall[Id]("func", Nil))))
|
||||
FuncOp.`funcop`.parseAll("Ab.func(arg)") should be(
|
||||
Right(AbilityFuncCall("Ab", FuncCall("func", VarLambda("arg", None) :: Nil)))
|
||||
Right(AbilityFuncCall[Id]("Ab", FuncCall[Id]("func", VarLambda("arg", None) :: Nil)))
|
||||
)
|
||||
FuncOp.`funcop`.parseAll("Ab.func(arg.doSomeThing)") should be(
|
||||
Right(AbilityFuncCall("Ab", FuncCall("func", VarLambda("arg", Some("doSomeThing")) :: Nil)))
|
||||
Right(AbilityFuncCall[Id]("Ab", FuncCall[Id]("func", VarLambda("arg", Some("doSomeThing")) :: Nil)))
|
||||
)
|
||||
FuncOp.`funcop`.parseAll("Ab.func(arg.doSomeThing, arg2)") should be(
|
||||
Right(
|
||||
AbilityFuncCall("Ab", FuncCall("func", VarLambda("arg", Some("doSomeThing")) :: VarLambda("arg2", None) :: Nil))
|
||||
AbilityFuncCall[Id](
|
||||
"Ab",
|
||||
FuncCall[Id]("func", VarLambda("arg", Some("doSomeThing")) :: VarLambda("arg2", None) :: Nil)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
"extracting" should "parse x <- func()" in {
|
||||
FuncOp.`funcop`.parseAll("someThing <- func()") should be(Right(Extract("someThing", FuncCall("func", Nil))))
|
||||
FuncOp.`funcop`.parseAll("someThing <- func()") should be(
|
||||
Right(Extract[Id]("someThing", FuncCall[Id]("func", Nil)))
|
||||
)
|
||||
}
|
||||
|
||||
"extracting" should "parse x <- Ab.func()" in {
|
||||
val fCall = AbilityFuncCall("Ab", FuncCall("func", Nil))
|
||||
FuncOp.`funcop`.parseAll("x <- Ab.func()") should be(Right(Extract("x", fCall)))
|
||||
val fCall = AbilityFuncCall[Id]("Ab", FuncCall[Id]("func", Nil))
|
||||
FuncOp.`funcop`.parseAll("x <- Ab.func()") should be(Right(Extract[Id]("x", fCall)))
|
||||
}
|
||||
|
||||
// TODO test with literals
|
||||
"ability resolve" should "parse id getter" in {
|
||||
FuncOp.`funcop`.parseAll("Ab x") should be(Right(AbilityId("Ab", VarLambda("x", None))))
|
||||
FuncOp.`funcop`.parseAll("Ab x.id") should be(Right(AbilityId("Ab", VarLambda("x", Some("id")))))
|
||||
FuncOp.`funcop`.parseAll("Ab x") should be(Right(AbilityId[Id]("Ab", VarLambda("x", None))))
|
||||
FuncOp.`funcop`.parseAll("Ab x.id") should be(Right(AbilityId[Id]("Ab", VarLambda("x", Some("id")))))
|
||||
}
|
||||
|
||||
"on" should "parse startOn" in {
|
||||
@ -54,10 +62,10 @@ class FuncOpSpec extends AnyFlatSpec with Matchers with EitherValues {
|
||||
}
|
||||
|
||||
"on" should "parse on x: y" in {
|
||||
val fCall = AbilityFuncCall("Ab", FuncCall("func", Nil))
|
||||
val extr = Extract("x", fCall)
|
||||
val resl = AbilityId("Peer", Literal("\"some id\"", BasicType.string))
|
||||
val call = FuncCall("call", Literal("true", BasicType.bool) :: Nil)
|
||||
val fCall = AbilityFuncCall[Id]("Ab", FuncCall[Id]("func", Nil))
|
||||
val extr = Extract[Id]("x", fCall)
|
||||
val resl = AbilityId[Id]("Peer", Literal("\"some id\"", BasicType.string))
|
||||
val call = FuncCall[Id]("call", Literal("true", BasicType.bool) :: Nil)
|
||||
|
||||
val script = """on peer.id:
|
||||
| x <- Ab.func()
|
||||
@ -65,12 +73,12 @@ class FuncOpSpec extends AnyFlatSpec with Matchers with EitherValues {
|
||||
| call(true)""".stripMargin
|
||||
|
||||
FuncOp.`funcop`.parseAll(script).right.value should be(
|
||||
On(VarLambda("peer", Some("id")), NonEmptyList.of(extr, resl, call))
|
||||
On[Id](VarLambda("peer", Some("id")), NonEmptyList.of(extr, resl, call))
|
||||
)
|
||||
}
|
||||
|
||||
"par" should "parse" in {
|
||||
FuncOp.`funcop`.parseAll("par func()") should be(Right(Par(FuncCall("func", Nil))))
|
||||
FuncOp.`funcop`.parseAll("par func()") should be(Right(Par[Id](FuncCall[Id]("func", Nil))))
|
||||
|
||||
val script = """par on peer.id:
|
||||
|
|
||||
|
@ -1,13 +1,16 @@
|
||||
package aqua.parse
|
||||
|
||||
import aqua.parse.lexer.{Literal, VarLambda}
|
||||
import cats.data.NonEmptyList
|
||||
import org.scalatest.EitherValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import aqua.parse.lift.LiftParser.Implicits.idLiftParser
|
||||
import cats.Id
|
||||
|
||||
class FuncSpec extends AnyFlatSpec with Matchers with EitherValues {
|
||||
|
||||
private val getTimeHead = FuncHead(
|
||||
private val getTimeHead = FuncHead[Id](
|
||||
"getTime",
|
||||
Map("peer" -> CustomType("PeerId"), "ret" -> ArrowType(BasicType("i32") :: Nil, BasicType("()"))),
|
||||
Some(BasicType("string"))
|
||||
@ -47,17 +50,17 @@ class FuncSpec extends AnyFlatSpec with Matchers with EitherValues {
|
||||
| ret(t)""".stripMargin
|
||||
|
||||
DefFunc.`deffunc`.parseAll(func).right.value should be(
|
||||
DefFunc(
|
||||
DefFunc[Id](
|
||||
getTimeHead,
|
||||
NonEmptyList.of(
|
||||
On(
|
||||
On[Id](
|
||||
VarLambda("peer", None),
|
||||
NonEmptyList.of(
|
||||
AbilityId("Peer", Literal("\"peer\"", BasicType.string)),
|
||||
Extract("t", AbilityFuncCall("Peer", FuncCall("timestamp", Nil)))
|
||||
AbilityId[Id]("Peer", Literal("\"peer\"", BasicType.string)),
|
||||
Extract[Id]("t", AbilityFuncCall[Id]("Peer", FuncCall[Id]("timestamp", Nil)))
|
||||
)
|
||||
),
|
||||
FuncCall("ret", VarLambda("t", None) :: Nil)
|
||||
FuncCall[Id]("ret", VarLambda("t", None) :: Nil)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -1,11 +1,11 @@
|
||||
package aqua.parse
|
||||
package aqua.parse.lexer
|
||||
|
||||
import aqua.parse.lexer.Token._
|
||||
import org.scalatest.EitherValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import Token._
|
||||
|
||||
class TokenSpec extends AnyFlatSpec with Matchers with EitherValues{
|
||||
class TokenSpec extends AnyFlatSpec with Matchers with EitherValues {
|
||||
|
||||
"\\n token" should "be parsed" in {
|
||||
` \n`.parseAll("\n") should be('right)
|
||||
@ -36,13 +36,12 @@ class TokenSpec extends AnyFlatSpec with Matchers with EitherValues{
|
||||
}
|
||||
|
||||
"\\n* token" should "match multi-line comments" in {
|
||||
` \n*`.parseAll(
|
||||
""" -- comment line 1
|
||||
|-- line 2
|
||||
|
|
||||
| -- line 3
|
||||
| -- line 4
|
||||
|""".stripMargin).right.value should be(())
|
||||
` \n*`.parseAll(""" -- comment line 1
|
||||
|-- line 2
|
||||
|
|
||||
| -- line 3
|
||||
| -- line 4
|
||||
|""".stripMargin).right.value should be(())
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package aqua.parse
|
||||
package aqua.parse.lexer
|
||||
|
||||
import aqua.parse.BasicType
|
||||
import org.scalatest.EitherValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
Loading…
Reference in New Issue
Block a user