Working on Gen

This commit is contained in:
dmitry 2021-03-16 14:03:06 +03:00
parent e3ad4f4ed1
commit a80c8cd571
16 changed files with 56 additions and 25 deletions

View File

@ -0,0 +1,8 @@
service Local("local"):
gt: u32, u32 -> bool
onIn: string -> ()
func tryGen(in1: u32, in2: string) -> bool:
on in2:
Local.onIn(in2)
Local.gt(in1, 25)

View File

@ -23,9 +23,11 @@ import aqua.parser.lexer.Token
import cats.arrow.FunctionK import cats.arrow.FunctionK
import cats.data.Validated.{Invalid, Valid} import cats.data.Validated.{Invalid, Valid}
import cats.data.{EitherK, NonEmptyList, State, ValidatedNel} import cats.data.{EitherK, NonEmptyList, State, ValidatedNel}
import cats.{Comonad, Eval} import cats.Eval
import cats.free.Free import cats.free.Free
import cats.syntax.flatMap._ import cats.syntax.flatMap._
import cats.syntax.apply._
import cats.syntax.semigroup._
import monocle.Lens import monocle.Lens
import monocle.macros.GenLens import monocle.macros.GenLens
@ -52,7 +54,7 @@ object Compiler {
case expr: OnExpr[F] => expr.program[G] case expr: OnExpr[F] => expr.program[G]
case expr: ParExpr[F] => expr.program[G] case expr: ParExpr[F] => expr.program[G]
case expr: ServiceExpr[F] => expr.program[G] case expr: ServiceExpr[F] => expr.program[G]
case _: RootExpr[F] => Free.pure[G, Gen](Gen("Root expr")) case expr: RootExpr[F] => expr.program[G]
} }
def folder[F[_], G[_]](implicit def folder[F[_], G[_]](implicit
@ -64,8 +66,9 @@ object Compiler {
case (expr, inners) => case (expr, inners) =>
Eval later exprToProg[F, G](expr) Eval later exprToProg[F, G](expr)
.apply( .apply(
// TODO: instead of >>, do >>= and merge Gens inners
inners.foldLeft(Free.pure[G, Gen](Gen("Folder begin")))(_ >> _) .reduceLeftOption[Free[G, Gen]]((a, b) => (a, b).mapN(_ |+| _))
.getOrElse(Free.pure(Gen.noop))
) )
} }

View File

@ -19,7 +19,7 @@ object Main extends IOApp.Simple {
println(Console.RED + s"Aqua script errored, total ${errs.length} problems found" + Console.RESET) println(Console.RED + s"Aqua script errored, total ${errs.length} problems found" + Console.RESET)
} }
val script = Source.fromResource("typecheck.aqua").mkString val script = Source.fromResource("generate.aqua").mkString
process(script) process(script)
} }

View File

@ -1,13 +1,21 @@
package aqua.ast package aqua.ast
import aqua.ast.algebra.types.ArrowType import aqua.ast.algebra.types.ArrowType
import cats.Semigroup
import cats.free.Free import cats.free.Free
case class Gen(log: String) { case class Gen(log: String, children: List[Gen] = Nil) {
def lift[F[_]]: Free[F, Gen] = Free.pure(this) def lift[F[_]]: Free[F, Gen] = Free.pure(this)
} }
object Gen { object Gen {
implicit object GenSemigroup extends Semigroup[Gen] {
override def combine(x: Gen, y: Gen): Gen =
x.copy(children = y :: x.children)
}
def noop = new Gen("noop") def noop = new Gen("noop")
case class Arrow(`type`: ArrowType, gen: Gen) case class Arrow(`type`: ArrowType, gen: Gen)

View File

@ -31,4 +31,6 @@ object Prog {
def around[Alg[_], R, A](before: Free[Alg, R], after: (R, A) => Free[Alg, A]): Prog[Alg, A] = def around[Alg[_], R, A](before: Free[Alg, R], after: (R, A) => Free[Alg, A]): Prog[Alg, A] =
RunAround(before, after) RunAround(before, after)
def noop[Alg[_], A]: Prog[Alg, A] =
RunAround(Free.pure(()), (_: Unit, a: A) => Free.pure(a))
} }

View File

@ -8,6 +8,7 @@ import cats.~>
import cats.syntax.functor._ import cats.syntax.functor._
import monocle.Lens import monocle.Lens
import monocle.macros.GenLens import monocle.macros.GenLens
import monocle.macros.syntax.all._
class AbilitiesInterpreter[F[_], X](implicit lens: Lens[X, AbilitiesState[F]], error: ReportError[F, X]) class AbilitiesInterpreter[F[_], X](implicit lens: Lens[X, AbilitiesState[F]], error: ReportError[F, X])
extends StackInterpreter[F, X, AbilitiesState[F], AbilityStackFrame[F]](GenLens[AbilitiesState[F]](_.stack)) extends StackInterpreter[F, X, AbilitiesState[F], AbilityStackFrame[F]](GenLens[AbilitiesState[F]](_.stack))
@ -35,6 +36,8 @@ class AbilitiesInterpreter[F[_], X](implicit lens: Lens[X, AbilitiesState[F]], e
case ga: GetArrow[F] => case ga: GetArrow[F] =>
getService(ga.name.value).flatMap { getService(ga.name.value).flatMap {
case Some(arrows) => case Some(arrows) =>
// TODO: must be resolved
arrows(ga.arrow.value) arrows(ga.arrow.value)
.fold( .fold(
report( report(
@ -50,7 +53,7 @@ class AbilitiesInterpreter[F[_], X](implicit lens: Lens[X, AbilitiesState[F]], e
getService(s.name.value).flatMap { getService(s.name.value).flatMap {
case Some(_) => case Some(_) =>
mapStackHead( mapStackHead(
report(s.name, "Trying to set service ID while out of the scope").as(false) modify(_.focus(_.rootServiceIds).index(s.name.value).replace(s.id)).as(true)
)(h => h.copy(serviceIds = h.serviceIds.updated(s.name.value, s.id)) -> true) )(h => h.copy(serviceIds = h.serviceIds.updated(s.name.value, s.id)) -> true)
case None => case None =>
@ -79,7 +82,8 @@ class AbilitiesInterpreter[F[_], X](implicit lens: Lens[X, AbilitiesState[F]], e
case class AbilitiesState[F[_]]( case class AbilitiesState[F[_]](
stack: List[AbilityStackFrame[F]] = Nil, stack: List[AbilityStackFrame[F]] = Nil,
services: Map[String, NonEmptyMap[String, ArrowType]] = Map.empty services: Map[String, NonEmptyMap[String, ArrowType]] = Map.empty,
rootServiceIds: Map[String, Value[F]] = Map.empty[String, Value[F]]
) { ) {
def purgeArrows: Option[(NonEmptyList[(Name[F], ArrowType)], AbilitiesState[F])] = def purgeArrows: Option[(NonEmptyList[(Name[F], ArrowType)], AbilitiesState[F])] =

View File

@ -14,7 +14,7 @@ import cats.syntax.functor._
case class AbilityIdExpr[F[_]](ability: Ability[F], id: Value[F]) extends Expr[F] { case class AbilityIdExpr[F[_]](ability: Ability[F], id: Value[F]) extends Expr[F] {
def program[Alg[_]](implicit A: AbilitiesAlgebra[F, Alg], V: ValuesAlgebra[F, Alg]): Prog[Alg, Gen] = def program[Alg[_]](implicit A: AbilitiesAlgebra[F, Alg], V: ValuesAlgebra[F, Alg]): Prog[Alg, Gen] =
V.ensureIsString(id) >> A.setServiceId(ability, id) as Gen.noop V.ensureIsString(id) >> A.setServiceId(ability, id) as Gen(s"Ability id is set for ${ability.value}")
} }

View File

@ -14,8 +14,8 @@ case class AliasExpr[F[_]](name: CustomTypeToken[F], target: TypeToken[F]) exten
def program[Alg[_]](implicit T: TypesAlgebra[F, Alg]): Prog[Alg, Gen] = def program[Alg[_]](implicit T: TypesAlgebra[F, Alg]): Prog[Alg, Gen] =
T.resolveType(target).flatMap { T.resolveType(target).flatMap {
case Some(t) => T.defineAlias(name, t).as(Gen.noop) case Some(t) => T.defineAlias(name, t) as Gen(s"Alias ${name.value} defined")
case None => Free.pure(Gen.noop) case None => Free.pure(Gen(s"Alias ${name.value} can't be defined"))
} }
} }

View File

@ -15,8 +15,8 @@ case class ArrowTypeExpr[F[_]](name: Name[F], `type`: ArrowTypeToken[F]) extends
def program[Alg[_]](implicit T: TypesAlgebra[F, Alg], A: AbilitiesAlgebra[F, Alg]): Prog[Alg, Gen] = def program[Alg[_]](implicit T: TypesAlgebra[F, Alg], A: AbilitiesAlgebra[F, Alg]): Prog[Alg, Gen] =
T.resolveArrowDef(`type`).flatMap { T.resolveArrowDef(`type`).flatMap {
case Some(t) => A.defineArrow(name, t).as(Gen.noop) case Some(t) => A.defineArrow(name, t) as Gen(s"Arrow $name defined")
case None => Free.pure(Gen.noop) case None => Free.pure(Gen(s"Arrow $name can't be defined"))
} }
} }

View File

@ -38,7 +38,8 @@ case class CoalgebraExpr[F[_]](
Free.pure[Alg, Boolean](false) Free.pure[Alg, Boolean](false)
)(resType => N.define(exportVar, resType)) )(resType => N.define(exportVar, resType))
// TODO: if it's a service, get service id, etc // TODO: if it's a service, get service id, etc
) as Gen("Coalgebra expression") ) as Gen(s"(call peer (${ability.map(_.value).getOrElse("func")} ${funcName.value}) [${args
.mkString(", ")}]${variable.map(" " + _).getOrElse("")})")
case None => case None =>
Free.pure(Gen("Coalgebra expression errored")) Free.pure(Gen("Coalgebra expression errored"))
} }

View File

@ -20,8 +20,8 @@ case class DataStructExpr[F[_]](name: CustomTypeToken[F]) extends Expr[F] {
Prog after T Prog after T
.purgeFields(name) .purgeFields(name)
.flatMap { .flatMap {
case Some(fields) => T.defineDataType(name, fields).as(Gen("Data struct created")) case Some(fields) => T.defineDataType(name, fields) as Gen(s"Data struct ${name.value} created")
case None => Free.pure(Gen.noop) case None => Free.pure(Gen(s"Data struct ${name.value} can't be created"))
} }
} }

View File

@ -14,8 +14,8 @@ case class FieldTypeExpr[F[_]](name: Name[F], `type`: DataTypeToken[F]) extends
def program[Alg[_]](implicit T: TypesAlgebra[F, Alg]): Prog[Alg, Gen] = def program[Alg[_]](implicit T: TypesAlgebra[F, Alg]): Prog[Alg, Gen] =
T.resolveType(`type`).flatMap { T.resolveType(`type`).flatMap {
case Some(t) => T.defineField(name, t).as(Gen.noop) case Some(t) => T.defineField(name, t) as Gen(s"Field ${name.value} defined")
case None => Free.pure(Gen.noop) case None => Free.pure(Gen(s"Field ${name.value} can't be defined"))
} }
} }

View File

@ -53,7 +53,8 @@ case class FuncExpr[F[_]](name: Name[F], args: List[Arg[F]], ret: Option[DataTyp
(funcArrow: ArrowType, bodyGen: Gen) => (funcArrow: ArrowType, bodyGen: Gen) =>
// Erase arguments and internal variables // Erase arguments and internal variables
A.endScope() >> N.endScope() >> N.define(name, funcArrow, isRoot = true) as Gen( A.endScope() >> N.endScope() >> N.define(name, funcArrow, isRoot = true) as Gen(
"Function defined, wrap + " + bodyGen s"func ${name.value}:",
bodyGen :: Nil
) )
) )

View File

@ -21,7 +21,7 @@ case class OnExpr[F[_]](peerId: Value[F]) extends Expr[F] {
): Prog[Alg, Gen] = ): Prog[Alg, Gen] =
Prog.around( Prog.around(
V.ensureIsString(peerId) >> P.onPeerId(peerId) >> A.beginScope(peerId), V.ensureIsString(peerId) >> P.onPeerId(peerId) >> A.beginScope(peerId),
(_: Unit, ops: Gen) => A.endScope() >> P.erasePeerId() as Gen("OnScope finished for" + ops) (_: Unit, ops: Gen) => A.endScope() >> P.erasePeerId() as ops
) )
} }

View File

@ -1,7 +1,11 @@
package aqua.ast.expr package aqua.ast.expr
import aqua.ast.Expr import aqua.ast.{Expr, Gen, Prog}
case class RootExpr[F[_]]() extends Expr[F] {} case class RootExpr[F[_]]() extends Expr[F] {
def program[Alg[_]]: Prog[Alg, Gen] =
Prog.noop
}
object RootExpr object RootExpr

View File

@ -29,11 +29,11 @@ case class ServiceExpr[F[_]](name: Ability[F], id: Option[Value[F]]) extends Exp
(A.purgeArrows(name) <* A.endScope()).flatMap { (A.purgeArrows(name) <* A.endScope()).flatMap {
case Some(nel) => case Some(nel) =>
A.defineService(name, nel.map(kv => kv._1.value -> kv._2).toNem) >> A.defineService(name, nel.map(kv => kv._1.value -> kv._2).toNem) >>
id.fold(Free.pure[Alg, Gen](Gen.noop))(idV => id.fold(Free.pure[Alg, Gen](Gen(s"Service ${name.value} created")))(idV =>
V.ensureIsString(idV) >> A.setServiceId(name, idV) as Gen.noop V.ensureIsString(idV) >> A.setServiceId(name, idV) as Gen(s"Service ${name.value} created with ID")
) )
case None => case None =>
Gen.noop.lift Gen(s"Cannot create service ${name.value}").lift
} }
) )