mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 22:50:18 +00:00
Generators WIP
This commit is contained in:
parent
a80c8cd571
commit
35a3c4fc86
@ -5,4 +5,10 @@ service Local("local"):
|
||||
func tryGen(in1: u32, in2: string) -> bool:
|
||||
on in2:
|
||||
Local.onIn(in2)
|
||||
Local.gt(in1, 25)
|
||||
Local.gt(in1, 25)
|
||||
|
||||
func generateComplex(value: string) -> bool:
|
||||
on "smth":
|
||||
Local "other"
|
||||
b <- tryGen(23, value)
|
||||
Local.onIn("Should be on root")
|
@ -25,7 +25,6 @@ import cats.data.Validated.{Invalid, Valid}
|
||||
import cats.data.{EitherK, NonEmptyList, State, ValidatedNel}
|
||||
import cats.Eval
|
||||
import cats.free.Free
|
||||
import cats.syntax.flatMap._
|
||||
import cats.syntax.apply._
|
||||
import cats.syntax.semigroup._
|
||||
import monocle.Lens
|
||||
|
@ -1,10 +1,11 @@
|
||||
package aqua.ast
|
||||
|
||||
import aqua.ast.algebra.types.ArrowType
|
||||
import cats.Semigroup
|
||||
import cats.free.Free
|
||||
|
||||
case class Gen(log: String, children: List[Gen] = Nil) {
|
||||
import scala.collection.immutable.Queue
|
||||
|
||||
sealed trait Gen {
|
||||
def lift[F[_]]: Free[F, Gen] = Free.pure(this)
|
||||
}
|
||||
|
||||
@ -12,11 +13,41 @@ object Gen {
|
||||
|
||||
implicit object GenSemigroup extends Semigroup[Gen] {
|
||||
|
||||
override def combine(x: Gen, y: Gen): Gen =
|
||||
x.copy(children = y :: x.children)
|
||||
override def combine(x: Gen, y: Gen): Gen = {
|
||||
println(Console.BLUE + x + " " + Console.YELLOW + y + Console.RESET)
|
||||
(x, y) match {
|
||||
case (x: ScriptGen, y: ScriptGen) => y.copy(funcs = y.funcs.enqueueAll(x.funcs))
|
||||
case (x: FuncGen, y: FuncGen) => ScriptGen(Queue(x, y))
|
||||
case (x: FuncGen, y: ScriptGen) => y.copy(funcs = y.funcs.enqueue(x))
|
||||
case (_, y: FuncBodyGen) => y.copy(op = SeqGen(x, y.op))
|
||||
case (_, y: ServiceCallGen) => SeqGen(x, y)
|
||||
case (_, y: ParGen) => ParGen(Some(x), y.right)
|
||||
|
||||
case (NoopGen, _) => y
|
||||
case (_, NoopGen) => x
|
||||
|
||||
case (_, y) =>
|
||||
println(Console.RED + s"drop x: ${x} in favor of y: $y" + Console.RESET)
|
||||
y
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def noop = new Gen("noop")
|
||||
|
||||
case class Arrow(`type`: ArrowType, gen: Gen)
|
||||
def noop: Gen = NoopGen
|
||||
def error: Gen = NoopGen
|
||||
}
|
||||
|
||||
case object NoopGen extends Gen
|
||||
|
||||
case class SeqGen(left: Gen, right: Gen) extends Gen
|
||||
|
||||
case class ServiceCallGen(peerId: String, serviceId: String, fnName: String, args: List[String], result: Option[String])
|
||||
extends Gen
|
||||
|
||||
case class FuncBodyGen(op: Gen) extends Gen
|
||||
|
||||
case class FuncGen(name: String, body: FuncBodyGen) extends Gen
|
||||
|
||||
case class ScriptGen(funcs: Queue[FuncGen]) extends Gen
|
||||
|
||||
case class ParGen(left: Option[Gen], right: Gen) extends Gen
|
||||
|
@ -25,8 +25,8 @@ object Prog {
|
||||
implicit def leaf[Alg[_], A](prog: Free[Alg, A]): Prog[Alg, A] =
|
||||
RunAfter(prog)
|
||||
|
||||
def after[Alg[_], A](prog: Free[Alg, A]): Prog[Alg, A] =
|
||||
RunAfter(prog)
|
||||
def after[Alg[_], A](prog: A => Free[Alg, A]): Prog[Alg, A] =
|
||||
RunAround(Free.pure(()), (_: Unit, a: A) => prog(a))
|
||||
|
||||
def around[Alg[_], R, A](before: Free[Alg, R], after: (R, A) => Free[Alg, A]): Prog[Alg, A] =
|
||||
RunAround(before, after)
|
||||
|
@ -7,7 +7,6 @@ import cats.data.State
|
||||
import cats.~>
|
||||
import monocle.Lens
|
||||
import monocle.macros.GenLens
|
||||
import monocle.macros.syntax.all._
|
||||
import cats.syntax.functor._
|
||||
import cats.syntax.flatMap._
|
||||
|
||||
@ -27,7 +26,8 @@ class NamesInterpreter[F[_], X](implicit lens: Lens[X, NamesState[F]], error: Re
|
||||
case rn: ReadName[F] =>
|
||||
readName(rn.name.value).flatTap {
|
||||
case Some(_) => State.pure(())
|
||||
case None => report(rn.name, "Undefined name")
|
||||
case None =>
|
||||
getState.flatMap(st => report(rn.name, "Undefined name, available: " + st.allNames.mkString(", ")))
|
||||
}
|
||||
case ra: ReadArrow[F] =>
|
||||
readName(ra.name.value).flatMap {
|
||||
@ -36,15 +36,22 @@ class NamesInterpreter[F[_], X](implicit lens: Lens[X, NamesState[F]], error: Re
|
||||
case Some(t) =>
|
||||
report(ra.name, s"Arrow type expected, got: $t").as(Option.empty[ArrowType])
|
||||
case None =>
|
||||
report(ra.name, "Undefined name").as(Option.empty[ArrowType])
|
||||
getState.flatMap(st =>
|
||||
report(ra.name, "Undefined name, available: " + st.allNames.mkString(", ")).as(Option.empty[ArrowType])
|
||||
)
|
||||
|
||||
}
|
||||
case dn: DefineName[F] =>
|
||||
readName(dn.name.value).flatMap {
|
||||
case Some(_) => report(dn.name, "This name was already defined in the scope").as(false)
|
||||
case None =>
|
||||
mapStackHead(
|
||||
if (dn.isRoot) modify(_.focus(_.rootNames).index(dn.name.value).replace(dn.`type`)).as(true)
|
||||
else report(dn.name, "Cannot define a variable in the root scope").as(false)
|
||||
if (dn.isRoot)
|
||||
modify(st => st.copy(rootNames = st.rootNames.updated(dn.name.value, dn.`type`)))
|
||||
.as(true)
|
||||
else
|
||||
report(dn.name, "Cannot define a variable in the root scope")
|
||||
.as(false)
|
||||
)(fr => fr.addName(dn.name.value, dn.`type`) -> true)
|
||||
}
|
||||
case bs: BeginScope[F] =>
|
||||
@ -54,7 +61,9 @@ class NamesInterpreter[F[_], X](implicit lens: Lens[X, NamesState[F]], error: Re
|
||||
}).asInstanceOf[State[X, A]]
|
||||
}
|
||||
|
||||
case class NamesState[F[_]](stack: List[NamesFrame[F]] = Nil, rootNames: Map[String, Type] = Map.empty)
|
||||
case class NamesState[F[_]](stack: List[NamesFrame[F]] = Nil, rootNames: Map[String, Type] = Map.empty) {
|
||||
def allNames: LazyList[String] = LazyList.from(stack).flatMap(_.names.keys).appendedAll(rootNames.keys)
|
||||
}
|
||||
|
||||
case class NamesFrame[F[_]](token: Token[F], names: Map[String, Type] = Map.empty) {
|
||||
def addName(n: String, t: Type): NamesFrame[F] = copy[F](names = names.updated(n, t))
|
||||
|
@ -1,6 +1,6 @@
|
||||
package aqua.ast.expr
|
||||
|
||||
import aqua.ast.{Expr, Gen, Prog}
|
||||
import aqua.ast.{Expr, Gen, NoopGen, Prog}
|
||||
import aqua.ast.algebra.ValuesAlgebra
|
||||
import aqua.ast.algebra.abilities.AbilitiesAlgebra
|
||||
import aqua.parser.lexer.Token._
|
||||
@ -14,7 +14,7 @@ import cats.syntax.functor._
|
||||
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] =
|
||||
V.ensureIsString(id) >> A.setServiceId(ability, id) as Gen(s"Ability id is set for ${ability.value}")
|
||||
V.ensureIsString(id) >> A.setServiceId(ability, id) as Gen.noop
|
||||
|
||||
}
|
||||
|
||||
|
@ -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] =
|
||||
T.resolveType(target).flatMap {
|
||||
case Some(t) => T.defineAlias(name, t) as Gen(s"Alias ${name.value} defined")
|
||||
case None => Free.pure(Gen(s"Alias ${name.value} can't be defined"))
|
||||
case Some(t) => T.defineAlias(name, t) as Gen.noop
|
||||
case None => Gen.error.lift
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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] =
|
||||
T.resolveArrowDef(`type`).flatMap {
|
||||
case Some(t) => A.defineArrow(name, t) as Gen(s"Arrow $name defined")
|
||||
case None => Free.pure(Gen(s"Arrow $name can't be defined"))
|
||||
case Some(t) => A.defineArrow(name, t) as Gen.noop
|
||||
case None => Gen.error.lift
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package aqua.ast.expr
|
||||
|
||||
import aqua.ast.{Expr, Gen, Prog}
|
||||
import aqua.ast.{Expr, Gen, Prog, ServiceCallGen}
|
||||
import aqua.ast.algebra.ValuesAlgebra
|
||||
import aqua.ast.algebra.abilities.AbilitiesAlgebra
|
||||
import aqua.ast.algebra.names.NamesAlgebra
|
||||
@ -38,10 +38,15 @@ case class CoalgebraExpr[F[_]](
|
||||
Free.pure[Alg, Boolean](false)
|
||||
)(resType => N.define(exportVar, resType))
|
||||
// TODO: if it's a service, get service id, etc
|
||||
) as Gen(s"(call peer (${ability.map(_.value).getOrElse("func")} ${funcName.value}) [${args
|
||||
.mkString(", ")}]${variable.map(" " + _).getOrElse("")})")
|
||||
) as (ServiceCallGen(
|
||||
peerId = "peerId",
|
||||
serviceId = "#" + ability.map(_.value).getOrElse("???"),
|
||||
fnName = funcName.value,
|
||||
args = args.map(_.toString),
|
||||
result = variable.map(_.value)
|
||||
): Gen)
|
||||
case None =>
|
||||
Free.pure(Gen("Coalgebra expression errored"))
|
||||
Gen.error.lift[Alg]
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ case class DataStructExpr[F[_]](name: CustomTypeToken[F]) extends Expr[F] {
|
||||
N: NamesAlgebra[F, Alg],
|
||||
T: TypesAlgebra[F, Alg]
|
||||
): Prog[Alg, Gen] =
|
||||
Prog after T
|
||||
.purgeFields(name)
|
||||
.flatMap {
|
||||
case Some(fields) => T.defineDataType(name, fields) as Gen(s"Data struct ${name.value} created")
|
||||
case None => Free.pure(Gen(s"Data struct ${name.value} can't be created"))
|
||||
Prog.after((_: Gen) =>
|
||||
T.purgeFields(name).flatMap {
|
||||
case Some(fields) => T.defineDataType(name, fields) as Gen.noop // TODO it's not air gen, but ts gen
|
||||
case None => Gen.error.lift
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
@ -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] =
|
||||
T.resolveType(`type`).flatMap {
|
||||
case Some(t) => T.defineField(name, t) as Gen(s"Field ${name.value} defined")
|
||||
case None => Free.pure(Gen(s"Field ${name.value} can't be defined"))
|
||||
case Some(t) => T.defineField(name, t) as Gen.noop
|
||||
case None => Gen.error.lift
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package aqua.ast.expr
|
||||
|
||||
import aqua.ast.{Expr, Gen, Prog}
|
||||
import aqua.ast.{Expr, FuncBodyGen, FuncGen, Gen, Prog}
|
||||
import aqua.ast.algebra.abilities.AbilitiesAlgebra
|
||||
import aqua.ast.algebra.names.NamesAlgebra
|
||||
import aqua.ast.algebra.scope.PeerIdAlgebra
|
||||
@ -52,9 +52,9 @@ case class FuncExpr[F[_]](name: Name[F], args: List[Arg[F]], ret: Option[DataTyp
|
||||
.map(argsAndRes => ArrowType(argsAndRes._1, argsAndRes._2)),
|
||||
(funcArrow: ArrowType, bodyGen: Gen) =>
|
||||
// Erase arguments and internal variables
|
||||
A.endScope() >> N.endScope() >> N.define(name, funcArrow, isRoot = true) as Gen(
|
||||
s"func ${name.value}:",
|
||||
bodyGen :: Nil
|
||||
A.endScope() >> N.endScope() >> N.define(name, funcArrow, isRoot = true) as FuncGen(
|
||||
name.value,
|
||||
FuncBodyGen(bodyGen)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -1,18 +1,16 @@
|
||||
package aqua.ast.expr
|
||||
|
||||
import aqua.ast.{Expr, Gen, Prog}
|
||||
import aqua.ast.{Expr, Gen, ParGen, Prog}
|
||||
import aqua.parser.lexer.Token._
|
||||
import aqua.parser.lift.LiftParser
|
||||
import aqua.parser.lift.LiftParser._
|
||||
import cats.Comonad
|
||||
import cats.free.Free
|
||||
import cats.parse.Parser
|
||||
|
||||
case class ParExpr[F[_]](point: F[Unit]) extends Expr[F] {
|
||||
|
||||
// TODO: implement par marker
|
||||
def program[Alg[_]]: Prog[Alg, Gen] =
|
||||
Free.pure[Alg, Gen](Gen("Par"))
|
||||
Prog.after[Alg, Gen](g => ParGen(left = None, right = g).lift)
|
||||
}
|
||||
|
||||
object ParExpr extends Expr.AndThen(OnExpr, CoalgebraExpr) {
|
||||
|
@ -1,11 +1,14 @@
|
||||
package aqua.ast.expr
|
||||
|
||||
import aqua.ast.{Expr, Gen, Prog}
|
||||
import aqua.ast.{Expr, Gen, Prog, ScriptGen}
|
||||
import cats.syntax.semigroup._
|
||||
|
||||
import scala.collection.immutable.Queue
|
||||
|
||||
case class RootExpr[F[_]]() extends Expr[F] {
|
||||
|
||||
def program[Alg[_]]: Prog[Alg, Gen] =
|
||||
Prog.noop
|
||||
Prog.after(a => (a |+| ScriptGen(Queue.empty)).lift)
|
||||
}
|
||||
|
||||
object RootExpr
|
||||
|
@ -29,11 +29,11 @@ case class ServiceExpr[F[_]](name: Ability[F], id: Option[Value[F]]) extends Exp
|
||||
(A.purgeArrows(name) <* A.endScope()).flatMap {
|
||||
case Some(nel) =>
|
||||
A.defineService(name, nel.map(kv => kv._1.value -> kv._2).toNem) >>
|
||||
id.fold(Free.pure[Alg, Gen](Gen(s"Service ${name.value} created")))(idV =>
|
||||
V.ensureIsString(idV) >> A.setServiceId(name, idV) as Gen(s"Service ${name.value} created with ID")
|
||||
id.fold(Free.pure[Alg, Gen](Gen.noop))(idV =>
|
||||
V.ensureIsString(idV) >> A.setServiceId(name, idV) as Gen.noop
|
||||
)
|
||||
case None =>
|
||||
Gen(s"Cannot create service ${name.value}").lift
|
||||
Gen.error.lift
|
||||
|
||||
}
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user