Join expression (#402)

This commit is contained in:
Dmitry Kurinskiy 2022-01-13 13:58:20 +03:00 committed by GitHub
parent 5a8a702f1c
commit f795edfaf7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 71 additions and 9 deletions

View File

@ -13,5 +13,7 @@ func sayHello(info: Info) -> string:
co on "target-peer" via "target-relay":
res <- HelloWorld.hello(%init_peer_id%)
join comp
-- send the result to the initiator
<- comp

View File

@ -31,6 +31,7 @@ object ArrowExpr extends Expr.AndIndented {
CatchExpr ::
ParExpr ::
CoExpr ::
JoinExpr ::
DeclareStreamExpr ::
ClosureExpr ::
AssignmentExpr ::

View File

@ -8,7 +8,7 @@ import aqua.parser.lift.LiftParser
import aqua.parser.lift.LiftParser.*
import cats.parse.Parser as P
import cats.syntax.comonad.*
import cats.{Comonad, ~>}
import cats.{~>, Comonad}
import aqua.parser.lift.Span
import aqua.parser.lift.Span.{P0ToSpan, PToSpan}
@ -33,6 +33,7 @@ object ForExpr extends Expr.AndIndented {
CallArrowExpr ::
AbilityIdExpr ::
AssignmentExpr ::
JoinExpr ::
PushToStreamExpr ::
Expr.defer(TryExpr) ::
Expr.defer(IfExpr) ::
@ -43,9 +44,9 @@ object ForExpr extends Expr.AndIndented {
Nil
override def p: P[ForExpr[Span.S]] =
((`for` *> ` ` *> Name.p <* ` <- `) ~ Value
.`value` ~ (` ` *> (`par`.as(ParMode: Mode).lift | `try`.as(TryMode: Mode).lift)).?).map {
case ((item, iterable), mode) =>
ForExpr(item, iterable, mode.map(m => m -> m.extract))
((`for` *> ` ` *> Name.p <* ` <- `) ~ Value.`value` ~ (` ` *> (`par`
.as(ParMode: Mode)
.lift | `try`.as(TryMode: Mode).lift)).?).map { case ((item, iterable), mode) =>
ForExpr(item, iterable, mode.map(m => m -> m.extract))
}
}

View File

@ -0,0 +1,24 @@
package aqua.parser.expr.func
import aqua.parser.Expr
import aqua.parser.expr.*
import aqua.parser.lexer.Token.*
import aqua.parser.lexer.{Value, VarLambda}
import aqua.parser.lift.{LiftParser, Span}
import aqua.parser.lift.Span.{P0ToSpan, PToSpan}
import cats.parse.Parser
import cats.{~>, Comonad}
import cats.data.NonEmptyList
case class JoinExpr[F[_]](values: NonEmptyList[VarLambda[F]])
extends Expr[F](JoinExpr, values.head) {
override def mapK[K[_]: Comonad](fk: F ~> K): JoinExpr[K] =
copy(values.map(_.mapK(fk)))
}
object JoinExpr extends Expr.Leaf {
override val p: Parser[JoinExpr[Span.S]] =
(`join` *> ` ` *> comma(Value.varLambda)).map(JoinExpr(_))
}

View File

@ -6,7 +6,7 @@ import aqua.parser.lexer.Token.*
import aqua.parser.lexer.Value
import aqua.parser.lift.LiftParser
import cats.parse.Parser as P
import cats.{Comonad, ~>}
import cats.{~>, Comonad}
import aqua.parser.lift.Span
import aqua.parser.lift.Span.{P0ToSpan, PToSpan}
@ -26,6 +26,7 @@ object OnExpr extends Expr.AndIndented {
PushToStreamExpr ::
ParExpr ::
CoExpr ::
JoinExpr ::
Expr.defer(TryExpr) ::
Expr.defer(ForExpr) ::
Expr.defer(IfExpr) ::
@ -34,9 +35,9 @@ object OnExpr extends Expr.AndIndented {
Nil
override def p: P[OnExpr[Span.S]] = {
(`on` *> ` ` *> Value
.`value` ~ (` ` *> `via` *> ` ` *> Value.`value`).rep0).map { case (peerId, via) =>
OnExpr(peerId, via)
(`on` *> ` ` *> Value.`value` ~ (` ` *> `via` *> ` ` *> Value.`value`).rep0).map {
case (peerId, via) =>
OnExpr(peerId, via)
}
}
}

View File

@ -60,6 +60,7 @@ object Token {
val `catch`: P[Unit] = P.string("catch")
val `par`: P[Unit] = P.string("par")
val `co`: P[Unit] = P.string("co")
val `join`: P[Unit] = P.string("join")
val `:` : P[Unit] = P.char(':')
val ` : ` : P[Unit] = P.char(':').surroundedBy(` `.?)
val `anum_*` : P[Unit] = whileAnum.void

View File

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

View File

@ -0,0 +1,31 @@
package aqua.semantics.expr.func
import aqua.parser.expr.func.JoinExpr
import aqua.raw.Raw
import aqua.raw.ops.{FuncOp, JoinTag}
import aqua.semantics.Prog
import aqua.semantics.rules.ValuesAlgebra
import aqua.semantics.rules.types.TypesAlgebra
import cats.Monad
import cats.data.NonEmptyList
import cats.syntax.applicative.*
import cats.syntax.flatMap.*
import cats.syntax.functor.*
import cats.syntax.traverse.*
class JoinSem[S[_]](val expr: JoinExpr[S]) extends AnyVal {
def program[Alg[_]: Monad](implicit
V: ValuesAlgebra[S, Alg]
): Prog[Alg, Raw] =
expr.values
.traverse(V.valueToRaw)
.map(_.toList.flatten.distinct)
.map(NonEmptyList.fromList)
.map {
case Some(vals) =>
FuncOp.leaf(JoinTag(vals))
case None =>
Raw.error("Join values resolution failed")
}
}