This commit is contained in:
dmitry 2021-03-11 17:06:31 +03:00
parent ebc8ee2aa3
commit a1c69819d2

View File

@ -1,19 +1,26 @@
package aqua.ast.algebra.abilities
import aqua.AquaError
import aqua.ast.algebra.types.ArrowType
import aqua.parser.lexer.{Name, Token}
import cats.data.{NonEmptyList, NonEmptyMap, State}
import cats.data.{EitherT, NonEmptyList, NonEmptyMap, State}
import cats.{~>, MonadError}
import shapeless.Lens
import cats.syntax.functor._
class AbilitiesInterpreter[F[_], X](implicit lens: Lens[X, AbState[F]]) extends (AbilityOp.Aux[F, *] ~> State[X, *]) {
class AbilitiesInterpreter[F[_], X](implicit lens: Lens[X, AbState[F]])
extends (AbilityOp.Aux[F, *] ~> EitherT[State[X, *], AquaError, *]) {
private def getState: State[X, AbState[F]] = State.get.map(lens.get)
private def setState(st: AbState[F]): State[X, Unit] = State.modify(s => lens.set(s)(st))
private def modify(f: AbState[F] => AbState[F]): State[X, Unit] = State.modify(s => lens.set(s)(f(lens.get(s))))
type S[A] = State[X, A]
type G[A] = EitherT[S, AquaError, A]
override def apply[A](fa: AbilityOp.Aux[F, A]): State[X, A] =
private def getState: G[AbState[F]] = EitherT.right(State.get.map(lens.get))
private def setState(st: AbState[F]): G[Unit] = EitherT.right(State.modify(s => lens.set(s)(st)))
private def modify(f: AbState[F] => AbState[F]): G[Unit] =
EitherT.right(State.modify(s => lens.set(s)(f(lens.get(s)))))
override def apply[A](fa: AbilityOp.Aux[F, A]): EitherT[State[X, *], AquaError, A] =
(fa match {
case bs: BeginScope[F] =>
modify(_.beginScope(bs.token))
@ -23,24 +30,29 @@ class AbilitiesInterpreter[F[_], X](implicit lens: Lens[X, AbState[F]]) extends
case PurgeArrows() =>
getState.map(_.purgeArrows).flatMap {
case (Some(arrs), nextState) => setState(nextState).as(arrs)
case _ => ??? //setError
case _ => EitherT.leftT[S, A](???) //setError
}
case GetArrow(name, arrow) =>
// Find the scope with ability
// get ability arrows
// find arrow by name
// if no matching arrow, error
// Find the scope with ability
// get ability arrows
// find arrow by name
// if no matching arrow, error
EitherT.left(???)
case SetServiceId(name, id) =>
// in current scope, set service id by its name
// check that it's registered, and that it is a service
case DefineArrow(arrow, t) =>
// in current scope, save arrow in the cache
// if an arrow with this name already exists, raise
// in current scope, save arrow in the cache
// if an arrow with this name already exists, raise
EitherT.left(???)
case DefineService(name, arrows) =>
// in current scope, define a service (or do it globally?)
// in case service name is already used for another ability, raise
}).asInstanceOf[State[X, A]]
// in current scope, define a service (or do it globally?)
// in case service name is already used for another ability, raise
EitherT.left(???)
}).asInstanceOf[EitherT[State[X, *], AquaError, A]]
}
case class AbState[F[_]](stack: List[AbScope[F]]) {