Co expression (#181)

This commit is contained in:
Dmitry Kurinskiy 2021-06-24 11:01:59 +03:00 committed by GitHub
parent c48bf5c488
commit bbf47628c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 67 additions and 10 deletions

View File

@ -50,7 +50,14 @@ object AirGen extends LogSupport {
case SeqRes => case SeqRes =>
Eval later ops.toList.reduceLeftOption(SeqGen).getOrElse(NullGen) Eval later ops.toList.reduceLeftOption(SeqGen).getOrElse(NullGen)
case ParRes => case ParRes =>
Eval later ops.toList.reduceLeftOption(ParGen).getOrElse(NullGen) Eval later (ops.toList match {
case o :: Nil => ParGen(o, NullGen)
case _ =>
ops.toList.reduceLeftOption(ParGen).getOrElse {
warn("ParRes with no children converted to Null")
NullGen
}
})
case XorRes => case XorRes =>
Eval later (ops.toList match { Eval later (ops.toList match {
case o :: Nil => XorGen(o, NullGen) case o :: Nil => XorGen(o, NullGen)

View File

@ -24,7 +24,7 @@ val airframeLog = "org.wvlet.airframe" %% "airframe-log" % airframeLogV
name := "aqua-hll" name := "aqua-hll"
val commons = Seq( val commons = Seq(
baseAquaVersion := "0.1.7", baseAquaVersion := "0.1.8",
version := baseAquaVersion.value + "-" + sys.env.getOrElse("BUILD_NUMBER", "SNAPSHOT"), version := baseAquaVersion.value + "-" + sys.env.getOrElse("BUILD_NUMBER", "SNAPSHOT"),
scalaVersion := dottyVersion, scalaVersion := dottyVersion,
libraryDependencies ++= Seq( libraryDependencies ++= Seq(

View File

@ -111,7 +111,8 @@ object FuncOp {
object RightAssocSemi extends Semigroup[FuncOp] { object RightAssocSemi extends Semigroup[FuncOp] {
override def combine(x: FuncOp, y: FuncOp): FuncOp = (x.tree.head, y.tree.head) match { override def combine(x: FuncOp, y: FuncOp): FuncOp = (x.tree.head, y.tree.head) match {
case (ParTag, ParTag) => FuncOp(y.tree.copy(tail = (x.tree.tail, y.tree.tail).mapN(_ ++ _))) case (_: ParGroupTag, ParTag) =>
FuncOp(y.tree.copy(tail = (x.tree.tail, y.tree.tail).mapN(_ ++ _)))
case (XorTag, XorTag) => case (XorTag, XorTag) =>
FuncOp(y.tree.copy(tail = (x.tree.tail, y.tree.tail).mapN(_ ++ _))) FuncOp(y.tree.copy(tail = (x.tree.tail, y.tree.tail).mapN(_ ++ _)))
case (XorTag.LeftBiased, XorTag) => case (XorTag.LeftBiased, XorTag) =>

View File

@ -64,6 +64,9 @@ object FuncOps {
.map(FuncOp(_)) .map(FuncOp(_))
) )
def co(ops: FuncOp*): FuncOp =
FuncOp.wrap(ParTag.Detach, seq(ops: _*))
def xor(left: FuncOp, right: FuncOp): FuncOp = def xor(left: FuncOp, right: FuncOp): FuncOp =
FuncOp.node(XorTag, Chain(left, right)) FuncOp.node(XorTag, Chain(left, right))

View File

@ -18,7 +18,7 @@ object PathFinder extends LogSupport {
!isExit && !isExit &&
to.leftSiblings.isEmpty && to.leftSiblings.isEmpty &&
to.moveUp.exists(_.pathOn == to.pathOn) && to.moveUp.exists(_.pathOn == to.pathOn) &&
!to.parentTag.contains(ParTag) !to.parentTag.exists(_.isInstanceOf[ParGroupTag])
if (wasHandled) { if (wasHandled) {
debug("Was handled") debug("Was handled")

View File

@ -44,14 +44,14 @@ case class RawCursor(tree: NonEmptyList[ChainZipper[FuncOp.Tree]])
lazy val lastExecuted: Option[RawCursor] = tag match { lazy val lastExecuted: Option[RawCursor] = tag match {
case XorTag => toFirstChild.flatMap(_.lastExecuted) case XorTag => toFirstChild.flatMap(_.lastExecuted)
case _: SeqGroupTag => toLastChild.flatMap(_.lastExecuted) case _: SeqGroupTag => toLastChild.flatMap(_.lastExecuted)
case ParTag => None case _: ParGroupTag => None
case _: NoExecTag => None case _: NoExecTag => None
case _ => Some(this) case _ => Some(this)
} }
lazy val firstExecuted: Option[RawCursor] = tag match { lazy val firstExecuted: Option[RawCursor] = tag match {
case _: SeqGroupTag => toLastChild.flatMap(_.lastExecuted) case _: SeqGroupTag => toLastChild.flatMap(_.lastExecuted)
case ParTag => None case _: ParGroupTag => None
case _: NoExecTag => None case _: NoExecTag => None
case _ => Some(this) case _ => Some(this)
} }
@ -95,7 +95,7 @@ case class RawCursor(tree: NonEmptyList[ChainZipper[FuncOp.Tree]])
} }
lazy val pathToNext: Chain[ValueModel] = parentTag.fold(Chain.empty[ValueModel]) { lazy val pathToNext: Chain[ValueModel] = parentTag.fold(Chain.empty[ValueModel]) {
case ParTag => case _: ParGroupTag =>
val exports = FuncOp(current).exportsVarNames.value val exports = FuncOp(current).exportsVarNames.value
if (exports.nonEmpty && checkNamesUsedLater(exports)) if (exports.nonEmpty && checkNamesUsedLater(exports))
seqNext.fold(Chain.empty[ValueModel])(nxt => seqNext.fold(Chain.empty[ValueModel])(nxt =>

View File

@ -35,12 +35,16 @@ sealed trait NoExecTag extends RawTag
sealed trait GroupTag extends RawTag sealed trait GroupTag extends RawTag
sealed trait SeqGroupTag extends GroupTag sealed trait SeqGroupTag extends GroupTag
sealed trait ParGroupTag extends GroupTag
case object SeqTag extends SeqGroupTag case object SeqTag extends SeqGroupTag
case object ParTag extends GroupTag
case object ParTag extends ParGroupTag {
case object Detach extends ParGroupTag
}
case object XorTag extends SeqGroupTag { case object XorTag extends SeqGroupTag {
case object LeftBiased extends GroupTag case object LeftBiased extends SeqGroupTag
} }
case class XorParTag(xor: FuncOp, par: FuncOp) extends RawTag case class XorParTag(xor: FuncOp, par: FuncOp) extends RawTag

View File

@ -54,7 +54,7 @@ object Topology extends LogSupport {
case _: OnTag => SeqRes case _: OnTag => SeqRes
case MatchMismatchTag(a, b, s) => MatchMismatchRes(a, b, s) case MatchMismatchTag(a, b, s) => MatchMismatchRes(a, b, s)
case ForTag(item, iter) => FoldRes(item, iter) case ForTag(item, iter) => FoldRes(item, iter)
case ParTag => ParRes case ParTag | ParTag.Detach => ParRes
case XorTag | XorTag.LeftBiased => XorRes case XorTag | XorTag.LeftBiased => XorRes
case NextTag(item) => NextRes(item) case NextTag(item) => NextRes(item)
case CallServiceTag(serviceId, funcName, call) => case CallServiceTag(serviceId, funcName, call) =>

View File

@ -0,0 +1,19 @@
package aqua.parser.expr
import aqua.parser.Expr
import aqua.parser.lexer.Token
import aqua.parser.lift.LiftParser
import aqua.parser.lift.LiftParser._
import cats.Comonad
import cats.parse.Parser
import Token.`co`
case class CoExpr[F[_]](point: Token[F]) extends Expr[F](CoExpr, point)
object CoExpr extends Expr.Prefix {
override def continueWith: List[Expr.Lexem] = ParExpr.continueWith
override def p[F[_]: LiftParser: Comonad]: Parser[Expr[F]] =
`co`.lift.map(Token.lift[F, Unit](_)).map(CoExpr(_))
}

View File

@ -30,6 +30,7 @@ object FuncExpr extends Expr.AndIndented {
ElseOtherwiseExpr :: ElseOtherwiseExpr ::
CatchExpr :: CatchExpr ::
ParExpr :: ParExpr ::
CoExpr ::
DeclareStreamExpr :: DeclareStreamExpr ::
Nil Nil

View File

@ -18,6 +18,8 @@ object IfExpr extends Expr.AndIndented {
CallArrowExpr :: CallArrowExpr ::
AbilityIdExpr :: AbilityIdExpr ::
AssignmentExpr :: AssignmentExpr ::
Expr.defer(ParExpr) ::
Expr.defer(CoExpr) ::
Expr.defer(TryExpr) :: Expr.defer(TryExpr) ::
Expr.defer(ForExpr) :: Expr.defer(ForExpr) ::
Expr.defer(IfExpr) :: Expr.defer(IfExpr) ::

View File

@ -17,6 +17,7 @@ object OnExpr extends Expr.AndIndented {
AbilityIdExpr :: AbilityIdExpr ::
AssignmentExpr :: AssignmentExpr ::
ParExpr :: ParExpr ::
CoExpr ::
Expr.defer(TryExpr) :: Expr.defer(TryExpr) ::
Expr.defer(ForExpr) :: Expr.defer(ForExpr) ::
Expr.defer(IfExpr) :: Expr.defer(IfExpr) ::

View File

@ -42,6 +42,7 @@ object Token {
val `try`: P[Unit] = P.string("try") val `try`: P[Unit] = P.string("try")
val `catch`: P[Unit] = P.string("catch") val `catch`: P[Unit] = P.string("catch")
val `par`: P[Unit] = P.string("par") val `par`: P[Unit] = P.string("par")
val `co`: P[Unit] = P.string("co")
val `:` : P[Unit] = P.char(':') val `:` : P[Unit] = P.char(':')
val ` : ` : P[Unit] = P.char(':').surroundedBy(` `.?) val ` : ` : P[Unit] = P.char(':').surroundedBy(` `.?)

View File

@ -35,6 +35,7 @@ object ExprSem {
case expr: CatchExpr[F] => new CatchSem(expr).program[G] case expr: CatchExpr[F] => new CatchSem(expr).program[G]
case expr: ElseOtherwiseExpr[F] => new ElseOtherwiseSem(expr).program[G] case expr: ElseOtherwiseExpr[F] => new ElseOtherwiseSem(expr).program[G]
case expr: ParExpr[F] => new ParSem(expr).program[G] case expr: ParExpr[F] => new ParSem(expr).program[G]
case expr: CoExpr[F] => new CoSem(expr).program[G]
case expr: ReturnExpr[F] => new ReturnSem(expr).program[G] case expr: ReturnExpr[F] => new ReturnSem(expr).program[G]
case expr: ServiceExpr[F] => new ServiceSem(expr).program[G] case expr: ServiceExpr[F] => new ServiceSem(expr).program[G]
case expr: RootExpr[F] => new RootSem(expr).program[G] case expr: RootExpr[F] => new RootSem(expr).program[G]

View File

@ -0,0 +1,17 @@
package aqua.semantics.expr
import aqua.model.Model
import aqua.model.func.raw.{FuncOp, ParTag}
import aqua.parser.expr.CoExpr
import aqua.semantics.Prog
import cats.free.Free
class CoSem[F[_]](val expr: CoExpr[F]) extends AnyVal {
def program[Alg[_]]: Prog[Alg, Model] =
Prog.after[Alg, Model] {
case g: FuncOp =>
Free.pure[Alg, Model](FuncOp.wrap(ParTag.Detach, g))
case g => Free.pure[Alg, Model](g)
}
}