mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 22:50:18 +00:00
Simplified CoalgebraModel
This commit is contained in:
parent
48a5ab2fa5
commit
7dde8a5d07
@ -4,7 +4,7 @@ import DataView.InitPeerId
|
||||
|
||||
case class AirContext(
|
||||
data: Map[String, DataView] = Map.empty,
|
||||
arrows: Map[String, ArrowGen.Callable] = Map.empty,
|
||||
arrows: Map[String, ArrowCallable] = Map.empty,
|
||||
peerId: DataView = InitPeerId,
|
||||
vars: Set[String] = Set.empty,
|
||||
instrCounter: Int = 0
|
||||
|
29
src/main/scala/aqua/generator/ArrowCallable.scala
Normal file
29
src/main/scala/aqua/generator/ArrowCallable.scala
Normal file
@ -0,0 +1,29 @@
|
||||
package aqua.generator
|
||||
|
||||
sealed trait ArrowCallable {
|
||||
def toCallGen(args: List[DataView], result: Option[String]): AirGen
|
||||
}
|
||||
|
||||
class FuncCallable(argNames: List[String], retValue: Option[DataView], bodyGen: FuncBodyGen) extends ArrowCallable {
|
||||
|
||||
override def toCallGen(args: List[DataView], result: Option[String]): AirGen =
|
||||
bodyGen.op
|
||||
.wrap(c =>
|
||||
(
|
||||
c.copy(data = c.data ++ argNames.zip(args)),
|
||||
_.copy(data = c.data ++ result.zip(retValue))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
class SrvCallable(srvId: DataView, fnName: String) extends ArrowCallable {
|
||||
|
||||
override def toCallGen(args: List[DataView], result: Option[String]): AirGen =
|
||||
ServiceCallGen(srvId, fnName, args, result)
|
||||
}
|
||||
|
||||
class SrvCallableOnPeer(peerId: DataView, srvId: DataView, fnName: String) extends ArrowCallable {
|
||||
|
||||
override def toCallGen(args: List[DataView], result: Option[String]): AirGen =
|
||||
ServiceCallGen(srvId, fnName, args, result).wrap(ctx => (ctx.copy(peerId = peerId), _.copy(peerId = ctx.peerId)))
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
package aqua.generator
|
||||
|
||||
import aqua.semantics.algebra.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.algebra.types.ArrowType
|
||||
import DataView.InitPeerId
|
||||
import aqua.parser.lexer.{IntoArray, IntoField, LambdaOp, Literal, Name, Value, VarLambda}
|
||||
import cats.free.Free
|
||||
|
||||
abstract class ArrowGen(val `type`: ArrowType) {
|
||||
|
||||
def gen[F[_], Alg[_]](args: List[Value[F]], result: Option[Name[F]])(implicit
|
||||
A: AbilitiesAlgebra[F, Alg]
|
||||
): Free[Alg, AirGen]
|
||||
}
|
||||
|
||||
object ArrowGen {
|
||||
|
||||
private def opsToLens[F[_]](ops: List[LambdaOp[F]]): String =
|
||||
ops match {
|
||||
case Nil => ""
|
||||
case (_: IntoArray[F]) :: tail => "[@" + opsToLens(tail) + "]"
|
||||
case (f: IntoField[F]) :: tail => "." + f.value + opsToLens(tail)
|
||||
}
|
||||
|
||||
def valueToData[F[_]](v: Value[F]): DataView =
|
||||
v match {
|
||||
case l: Literal[F] => DataView.StringScalar(l.value)
|
||||
case VarLambda(name, Nil) => DataView.Variable(name.value)
|
||||
case VarLambda(name, ops) => DataView.VarLens(name.value, opsToLens(ops))
|
||||
}
|
||||
|
||||
private def argsToData[F[_]](args: List[Value[F]]): List[DataView] = args.map(valueToData)
|
||||
|
||||
trait Callable {
|
||||
def toCallGen(args: List[DataView], result: Option[String]): AirGen
|
||||
}
|
||||
|
||||
class FuncCallable(argNames: List[String], retValue: Option[DataView], bodyGen: FuncBodyGen) extends Callable {
|
||||
|
||||
override def toCallGen(args: List[DataView], result: Option[String]): AirGen =
|
||||
bodyGen.op
|
||||
.wrap(c =>
|
||||
(
|
||||
c.copy(data = c.data ++ argNames.zip(args)),
|
||||
_.copy(data = c.data ++ result.zip(retValue))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
class SrvCallable(srvId: DataView, fnName: String) extends Callable {
|
||||
|
||||
override def toCallGen(args: List[DataView], result: Option[String]): AirGen =
|
||||
ServiceCallGen(srvId, fnName, args, result)
|
||||
}
|
||||
|
||||
class SrvCallableOnPeer(peerId: DataView, srvId: DataView, fnName: String) extends Callable {
|
||||
|
||||
override def toCallGen(args: List[DataView], result: Option[String]): AirGen =
|
||||
ServiceCallGen(srvId, fnName, args, result).wrap(ctx => (ctx.copy(peerId = peerId), _.copy(peerId = ctx.peerId)))
|
||||
}
|
||||
|
||||
def func(`type`: ArrowType, argNames: List[String], retValue: Option[DataView], bodyGen: FuncBodyGen): ArrowGen =
|
||||
new ArrowGen(`type`) {
|
||||
|
||||
override def gen[F[_], Alg[_]](args: List[Value[F]], result: Option[Name[F]])(implicit
|
||||
A: AbilitiesAlgebra[F, Alg]
|
||||
): Free[Alg, AirGen] =
|
||||
Free.pure[Alg, AirGen](
|
||||
new FuncCallable(argNames, retValue, bodyGen).toCallGen(argsToData(args), result.map(_.value))
|
||||
)
|
||||
}
|
||||
|
||||
def service(name: String, fnName: String, `type`: ArrowType): ArrowGen =
|
||||
new ArrowGen(`type`) {
|
||||
|
||||
override def gen[F[_], Alg[_]](args: List[Value[F]], result: Option[Name[F]])(implicit
|
||||
A: AbilitiesAlgebra[F, Alg]
|
||||
): Free[Alg, AirGen] =
|
||||
// TODO it's really weird that we're losing token here
|
||||
A.getServiceId(name).map {
|
||||
case Some(sid) =>
|
||||
new SrvCallable(valueToData(sid), fnName).toCallGen(argsToData(args), result.map(_.value))
|
||||
case None =>
|
||||
NullGen
|
||||
}
|
||||
}
|
||||
|
||||
def arg(name: String, `type`: ArrowType): ArrowGen =
|
||||
new ArrowGen(`type`) {
|
||||
|
||||
override def gen[F[_], Alg[_]](args: List[Value[F]], result: Option[Name[F]])(implicit
|
||||
A: AbilitiesAlgebra[F, Alg]
|
||||
): Free[Alg, AirGen] =
|
||||
Free.pure[Alg, AirGen](
|
||||
new AirGen {
|
||||
|
||||
override def generate(ctx: AirContext): (AirContext, Air) = {
|
||||
println(Console.YELLOW + ctx + Console.RESET)
|
||||
ctx.arrows(name).toCallGen(argsToData(args), result.map(_.value)).generate(ctx)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
@ -106,14 +106,23 @@ case class ServiceCallGen(
|
||||
|
||||
case class FuncBodyGen(op: AirGen) extends Gen
|
||||
|
||||
case class FuncGen(name: String, air: Eval[Air], body: FuncBodyGen) extends Gen {
|
||||
def generateAir: Air = air.memoize.value
|
||||
case class FuncGen(
|
||||
name: String,
|
||||
air: Map[String, ArrowCallable] => Eval[Air],
|
||||
body: FuncBodyGen,
|
||||
callable: FuncCallable
|
||||
) extends Gen {
|
||||
def generateAir(acc: Map[String, ArrowCallable]): Air = air(acc).value
|
||||
}
|
||||
|
||||
case class ScriptGen(funcs: Queue[FuncGen]) extends Gen {
|
||||
|
||||
def generateAir: Queue[String] =
|
||||
funcs.map(_.generateAir.show)
|
||||
funcs
|
||||
.foldLeft((Map.empty[String, ArrowCallable], Queue.empty[String])) { case ((funcsAcc, outputAcc), func) =>
|
||||
funcsAcc.updated(func.name, func.callable) -> outputAcc.enqueue(func.generateAir(funcsAcc).show)
|
||||
}
|
||||
._2
|
||||
}
|
||||
|
||||
case class ParGen(left: Option[AirGen], right: AirGen) extends AirGen {
|
||||
|
7
src/main/scala/aqua/model/AbilityModel.scala
Normal file
7
src/main/scala/aqua/model/AbilityModel.scala
Normal file
@ -0,0 +1,7 @@
|
||||
package aqua.model
|
||||
|
||||
import aqua.generator.DataView
|
||||
|
||||
sealed trait AbilityModel
|
||||
|
||||
case class ServiceModel(name: String, id: DataView) extends AbilityModel
|
21
src/main/scala/aqua/model/CoalgebraModel.scala
Normal file
21
src/main/scala/aqua/model/CoalgebraModel.scala
Normal file
@ -0,0 +1,21 @@
|
||||
package aqua.model
|
||||
|
||||
import aqua.generator.{AirContext, AirGen, DataView, SrvCallable}
|
||||
import aqua.semantics.Type
|
||||
|
||||
case class CoalgebraModel(
|
||||
ability: Option[AbilityModel],
|
||||
funcName: String,
|
||||
args: List[(DataView, Type)],
|
||||
exportTo: Option[String]
|
||||
) extends OpModel {
|
||||
|
||||
def arrowGen: AirGen =
|
||||
ability match {
|
||||
case Some(ServiceModel(_, id)) =>
|
||||
new SrvCallable(id, funcName).toCallGen(args.map(_._1), exportTo)
|
||||
case None =>
|
||||
(ctx: AirContext) => ctx.arrows(funcName).toCallGen(args.map(_._1), exportTo).generate(ctx)
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package aqua.model
|
||||
|
||||
import aqua.generator.DataView.InitPeerId
|
||||
import aqua.generator.{AirContext, ArrowGen, DataView, FuncBodyGen, FuncGen}
|
||||
import aqua.semantics.algebra.types.{ArrowType, DataType}
|
||||
import aqua.generator.{AirContext, DataView, FuncBodyGen, FuncCallable, FuncGen, SrvCallableOnPeer}
|
||||
import aqua.semantics.{ArrowType, DataType}
|
||||
import cats.Eval
|
||||
|
||||
case class FuncModel(
|
||||
@ -15,23 +15,29 @@ case class FuncModel(
|
||||
def gen: FuncGen =
|
||||
FuncGen(
|
||||
name,
|
||||
Eval.later {
|
||||
body.op
|
||||
.generate(
|
||||
AirContext(
|
||||
data = args.collect { //TODO preload these variables
|
||||
case (an, Left(_)) =>
|
||||
an -> DataView.Variable(an)
|
||||
}.toMap,
|
||||
arrows = args.collect { case (an, Right(_)) =>
|
||||
an -> new ArrowGen.SrvCallableOnPeer(InitPeerId, DataView.StringScalar("callback"), an)
|
||||
}.toMap,
|
||||
vars = args.map(_._1).toSet
|
||||
acc =>
|
||||
Eval.later {
|
||||
body.op
|
||||
.generate(
|
||||
AirContext(
|
||||
data = args.collect { //TODO preload these variables
|
||||
case (an, Left(_)) =>
|
||||
an -> DataView.Variable(an)
|
||||
}.toMap,
|
||||
arrows = acc ++ args.collect { case (an, Right(_)) =>
|
||||
an -> new SrvCallableOnPeer(InitPeerId, DataView.StringScalar("callback"), an)
|
||||
}.toMap,
|
||||
vars = args.map(_._1).toSet
|
||||
)
|
||||
)
|
||||
)
|
||||
._2
|
||||
},
|
||||
body
|
||||
._2
|
||||
},
|
||||
body,
|
||||
new FuncCallable(
|
||||
args.map(_._1),
|
||||
ret,
|
||||
body
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
3
src/main/scala/aqua/model/OpModel.scala
Normal file
3
src/main/scala/aqua/model/OpModel.scala
Normal file
@ -0,0 +1,3 @@
|
||||
package aqua.model
|
||||
|
||||
trait OpModel {}
|
5
src/main/scala/aqua/model/SeqModel.scala
Normal file
5
src/main/scala/aqua/model/SeqModel.scala
Normal file
@ -0,0 +1,5 @@
|
||||
package aqua.model
|
||||
|
||||
import cats.data.NonEmptyList
|
||||
|
||||
case class SeqModel(ops: NonEmptyList[OpModel]) extends OpModel
|
@ -1,9 +1,9 @@
|
||||
package aqua.parser.lexer
|
||||
|
||||
import aqua.semantics.algebra.types.ScalarType
|
||||
import aqua.parser.lexer.Token._
|
||||
import aqua.parser.lift.LiftParser
|
||||
import aqua.parser.lift.LiftParser._
|
||||
import aqua.semantics.ScalarType
|
||||
import cats.{Comonad, Functor}
|
||||
import cats.parse.{Parser => P}
|
||||
import cats.syntax.functor._
|
||||
@ -36,9 +36,8 @@ object BasicTypeToken {
|
||||
|
||||
def `basictypedef`[F[_]: LiftParser: Comonad]: P[BasicTypeToken[F]] =
|
||||
P.oneOf(
|
||||
ScalarType.all.map(n ⇒ P.string(n.name).as(n)).toList
|
||||
)
|
||||
.lift
|
||||
ScalarType.all.map(n ⇒ P.string(n.name).as(n)).toList
|
||||
).lift
|
||||
.map(BasicTypeToken(_))
|
||||
}
|
||||
|
||||
@ -64,8 +63,8 @@ object ArrowTypeToken {
|
||||
def `arrowdef`[F[_]: LiftParser: Comonad]: P[ArrowTypeToken[F]] =
|
||||
(comma0(DataTypeToken.`datatypedef`).with1 ~ ` -> `.lift ~
|
||||
(DataTypeToken.`datatypedef`
|
||||
.map(Some(_)) | P.string("()").as(None))).map {
|
||||
case ((args, point), res) ⇒ ArrowTypeToken(point, args, res)
|
||||
.map(Some(_)) | P.string("()").as(None))).map { case ((args, point), res) ⇒
|
||||
ArrowTypeToken(point, args, res)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
package aqua.parser.lexer
|
||||
|
||||
import aqua.semantics.algebra.types.LiteralType
|
||||
import aqua.parser.lexer.Token._
|
||||
import aqua.parser.lift.LiftParser
|
||||
import aqua.parser.lift.LiftParser._
|
||||
import aqua.semantics.LiteralType
|
||||
import cats.{Comonad, Functor}
|
||||
import cats.parse.{Numbers, Parser => P}
|
||||
import cats.syntax.functor._
|
||||
@ -25,8 +25,8 @@ object Value {
|
||||
val notLambdaSymbols = Set(' ', ',', '\n', ')', ':')
|
||||
|
||||
def varLambda[F[_]: LiftParser: Comonad]: P[VarLambda[F]] =
|
||||
(Name.p[F] ~ LambdaOp.ops[F].?).map {
|
||||
case (n, l) ⇒ VarLambda(n, l.fold[List[LambdaOp[F]]](Nil)(_.toList))
|
||||
(Name.p[F] ~ LambdaOp.ops[F].?).map { case (n, l) ⇒
|
||||
VarLambda(n, l.fold[List[LambdaOp[F]]](Nil)(_.toList))
|
||||
}
|
||||
|
||||
def bool[F[_]: LiftParser: Functor: Comonad]: P[Literal[F]] =
|
||||
|
@ -3,10 +3,10 @@ package aqua.semantics
|
||||
import aqua.generator.Gen
|
||||
import aqua.parser.Expr
|
||||
import aqua.parser.expr._
|
||||
import aqua.semantics.algebra.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.algebra.names.NamesAlgebra
|
||||
import aqua.semantics.algebra.scope.PeerIdAlgebra
|
||||
import aqua.semantics.algebra.types.TypesAlgebra
|
||||
import aqua.semantics.rules.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.rules.names.NamesAlgebra
|
||||
import aqua.semantics.rules.scope.PeerIdAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
import aqua.semantics.expr._
|
||||
|
||||
object ExprSem {
|
||||
|
@ -3,11 +3,11 @@ package aqua.semantics
|
||||
import aqua.generator.Gen
|
||||
import aqua.parser.lexer.Token
|
||||
import aqua.parser.{Ast, Expr}
|
||||
import aqua.semantics.algebra.ReportError
|
||||
import aqua.semantics.algebra.abilities.{AbilitiesAlgebra, AbilitiesInterpreter, AbilitiesState, AbilityOp}
|
||||
import aqua.semantics.algebra.names.{NameOp, NamesAlgebra, NamesInterpreter, NamesState}
|
||||
import aqua.semantics.algebra.scope.{PeerIdAlgebra, PeerIdInterpreter, PeerIdOp, PeerIdState}
|
||||
import aqua.semantics.algebra.types.{TypeOp, TypesAlgebra, TypesInterpreter, TypesState}
|
||||
import aqua.semantics.rules.ReportError
|
||||
import aqua.semantics.rules.abilities.{AbilitiesAlgebra, AbilitiesInterpreter, AbilitiesState, AbilityOp}
|
||||
import aqua.semantics.rules.names.{NameOp, NamesAlgebra, NamesInterpreter, NamesState}
|
||||
import aqua.semantics.rules.scope.{PeerIdAlgebra, PeerIdInterpreter, PeerIdOp, PeerIdState}
|
||||
import aqua.semantics.rules.types.{TypeOp, TypesAlgebra, TypesInterpreter, TypesState}
|
||||
import cats.Eval
|
||||
import cats.arrow.FunctionK
|
||||
import cats.data.Validated.{Invalid, Valid}
|
||||
@ -27,15 +27,14 @@ object Semantics {
|
||||
N: NamesAlgebra[F, G],
|
||||
P: PeerIdAlgebra[F, G],
|
||||
T: TypesAlgebra[F, G]
|
||||
): (Expr[F], List[Free[G, Gen]]) => Eval[Free[G, Gen]] = {
|
||||
case (expr, inners) =>
|
||||
Eval later ExprSem
|
||||
.getProg[F, G](expr)
|
||||
.apply(
|
||||
inners
|
||||
.reduceLeftOption[Free[G, Gen]]((a, b) => (a, b).mapN(_ |+| _))
|
||||
.getOrElse(Free.pure(Gen.noop))
|
||||
)
|
||||
): (Expr[F], List[Free[G, Gen]]) => Eval[Free[G, Gen]] = { case (expr, inners) =>
|
||||
Eval later ExprSem
|
||||
.getProg[F, G](expr)
|
||||
.apply(
|
||||
inners
|
||||
.reduceLeftOption[Free[G, Gen]]((a, b) => (a, b).mapN(_ |+| _))
|
||||
.getOrElse(Free.pure(Gen.noop))
|
||||
)
|
||||
}
|
||||
|
||||
type Alg0[F[_], A] = EitherK[AbilityOp[F, *], NameOp[F, *], A]
|
||||
@ -85,9 +84,8 @@ object Semantics {
|
||||
def validate[F[_]](ast: Ast[F]): ValidatedNel[(Token[F], String), Gen] =
|
||||
(transpile[F] _ andThen interpret[F])(ast)
|
||||
.run(CompilerState[F]())
|
||||
.map {
|
||||
case (state, gen) =>
|
||||
NonEmptyList.fromList(state.errors.toList).fold[ValidatedNel[(Token[F], String), Gen]](Valid(gen))(Invalid(_))
|
||||
.map { case (state, gen) =>
|
||||
NonEmptyList.fromList(state.errors.toList).fold[ValidatedNel[(Token[F], String), Gen]](Valid(gen))(Invalid(_))
|
||||
}
|
||||
.value
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package aqua.semantics.algebra.types
|
||||
package aqua.semantics
|
||||
|
||||
import cats.PartialOrder
|
||||
import cats.data.NonEmptyMap
|
||||
@ -48,7 +48,7 @@ object ScalarType {
|
||||
}
|
||||
}
|
||||
|
||||
case class LiteralType private (oneOf: Set[ScalarType], name: String) extends Type {
|
||||
case class LiteralType private (oneOf: Set[ScalarType], name: String) extends DataType {
|
||||
override def toString: String = name
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package aqua.semantics.expr
|
||||
import aqua.generator.Gen
|
||||
import aqua.parser.expr.AbilityIdExpr
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.algebra.ValuesAlgebra
|
||||
import aqua.semantics.algebra.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.rules.ValuesAlgebra
|
||||
import aqua.semantics.rules.abilities.AbilitiesAlgebra
|
||||
|
||||
import cats.syntax.flatMap._
|
||||
import cats.syntax.functor._
|
||||
|
@ -3,7 +3,7 @@ package aqua.semantics.expr
|
||||
import aqua.generator.Gen
|
||||
import aqua.parser.expr.AliasExpr
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.algebra.types.TypesAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
import cats.syntax.functor._
|
||||
|
||||
class AliasSem[F[_]](val expr: AliasExpr[F]) extends AnyVal {
|
||||
|
@ -3,8 +3,8 @@ package aqua.semantics.expr
|
||||
import aqua.generator.Gen
|
||||
import aqua.parser.expr.ArrowTypeExpr
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.algebra.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.algebra.types.TypesAlgebra
|
||||
import aqua.semantics.rules.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
import cats.syntax.functor._
|
||||
|
||||
class ArrowTypeSem[F[_]](val expr: ArrowTypeExpr[F]) extends AnyVal {
|
||||
|
@ -1,39 +1,83 @@
|
||||
package aqua.semantics.expr
|
||||
|
||||
import aqua.generator.Gen
|
||||
import aqua.generator.{DataView, Gen}
|
||||
import aqua.model.{CoalgebraModel, ServiceModel}
|
||||
import aqua.parser.expr.CoalgebraExpr
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.algebra.ValuesAlgebra
|
||||
import aqua.semantics.algebra.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.algebra.names.NamesAlgebra
|
||||
import aqua.semantics.algebra.types.TypesAlgebra
|
||||
import aqua.semantics.{ArrowType, Prog, Type}
|
||||
import aqua.semantics.rules.ValuesAlgebra
|
||||
import aqua.semantics.rules.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.rules.names.NamesAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
import cats.free.Free
|
||||
import cats.syntax.flatMap._
|
||||
import cats.syntax.functor._
|
||||
import cats.syntax.apply._
|
||||
|
||||
class CoalgebraSem[F[_]](val expr: CoalgebraExpr[F]) extends AnyVal {
|
||||
|
||||
import expr._
|
||||
|
||||
private def freeUnit[Alg[_]]: Free[Alg, Unit] = Free.pure[Alg, Unit](())
|
||||
|
||||
private def checkArgsRes[Alg[_]](
|
||||
at: ArrowType
|
||||
)(implicit N: NamesAlgebra[F, Alg], V: ValuesAlgebra[F, Alg]): Free[Alg, List[(DataView, Type)]] =
|
||||
V.checkArguments(at, args) >> variable
|
||||
.fold(freeUnit[Alg])(exportVar =>
|
||||
at.res.fold(
|
||||
// TODO: error! we're trying to export variable, but function has no export type
|
||||
freeUnit[Alg]
|
||||
)(resType => N.define(exportVar, resType).void)
|
||||
) >> args.foldLeft(Free.pure[Alg, List[(DataView, Type)]](Nil)) { case (acc, v) =>
|
||||
(acc, V.resolveType(v)).mapN((a, b) => a ++ b.map(ValuesAlgebra.valueToData(v) -> _))
|
||||
}
|
||||
|
||||
private def toModel[Alg[_]](implicit
|
||||
N: NamesAlgebra[F, Alg],
|
||||
A: AbilitiesAlgebra[F, Alg],
|
||||
T: TypesAlgebra[F, Alg],
|
||||
V: ValuesAlgebra[F, Alg]
|
||||
): Free[Alg, Option[CoalgebraModel]] =
|
||||
ability match {
|
||||
case Some(ab) =>
|
||||
(A.getArrow(ab, funcName), A.getServiceId(ab)).mapN {
|
||||
case (Some(at), Some(sid)) =>
|
||||
Option(at -> sid) // Here we assume that Ability is a Service that must be resolved
|
||||
case _ => None
|
||||
}.flatMap(_.fold(Free.pure[Alg, Option[CoalgebraModel]](None)) { case (arrowType, serviceId) =>
|
||||
checkArgsRes(arrowType)
|
||||
.map(argsResolved =>
|
||||
CoalgebraModel(
|
||||
ability = Some(ServiceModel(ab.value, ValuesAlgebra.valueToData(serviceId))),
|
||||
funcName = funcName.value,
|
||||
args = argsResolved,
|
||||
exportTo = variable.map(_.value)
|
||||
)
|
||||
)
|
||||
.map(Option(_))
|
||||
})
|
||||
case None =>
|
||||
N.readArrow(funcName)
|
||||
.flatMap(_.fold(Free.pure[Alg, Option[CoalgebraModel]](None)) { arrowType =>
|
||||
checkArgsRes(arrowType)
|
||||
.map(argsResolved =>
|
||||
CoalgebraModel(
|
||||
ability = None,
|
||||
funcName = funcName.value,
|
||||
args = argsResolved,
|
||||
exportTo = variable.map(_.value)
|
||||
)
|
||||
)
|
||||
.map(Option(_))
|
||||
})
|
||||
}
|
||||
|
||||
def program[Alg[_]](implicit
|
||||
N: NamesAlgebra[F, Alg],
|
||||
A: AbilitiesAlgebra[F, Alg],
|
||||
T: TypesAlgebra[F, Alg],
|
||||
V: ValuesAlgebra[F, Alg]
|
||||
): Prog[Alg, Gen] =
|
||||
ability
|
||||
.fold(N.readArrow(funcName))(A.getArrow(_, funcName))
|
||||
.flatMap {
|
||||
case Some(at) =>
|
||||
V.checkArguments(at.`type`, args) >> variable
|
||||
.fold(Free.pure[Alg, Boolean](true))(exportVar =>
|
||||
at.`type`.res.fold(
|
||||
// TODO: error! we're trying to export variable, but function has no export type
|
||||
Free.pure[Alg, Boolean](false)
|
||||
)(resType => N.define(exportVar, resType))
|
||||
) >> at.gen[F, Alg](args, variable).widen[Gen]
|
||||
case None =>
|
||||
Gen.error.lift[Alg]
|
||||
}
|
||||
toModel[Alg].map(_.fold(Gen.noop)(_.arrowGen))
|
||||
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ package aqua.semantics.expr
|
||||
import aqua.generator.Gen
|
||||
import aqua.parser.expr.DataStructExpr
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.algebra.names.NamesAlgebra
|
||||
import aqua.semantics.algebra.types.TypesAlgebra
|
||||
import aqua.semantics.rules.names.NamesAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
import cats.syntax.functor._
|
||||
|
||||
class DataStructSem[F[_]](val expr: DataStructExpr[F]) extends AnyVal {
|
||||
|
@ -3,7 +3,7 @@ package aqua.semantics.expr
|
||||
import aqua.generator.Gen
|
||||
import aqua.parser.expr.FieldTypeExpr
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.algebra.types.TypesAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
import cats.syntax.functor._
|
||||
|
||||
class FieldTypeSem[F[_]](val expr: FieldTypeExpr[F]) extends AnyVal {
|
||||
|
@ -1,15 +1,15 @@
|
||||
package aqua.semantics.expr
|
||||
|
||||
import aqua.generator.{AirGen, ArrowGen, FuncBodyGen, Gen}
|
||||
import aqua.generator.{AirGen, FuncBodyGen, Gen}
|
||||
import aqua.model.FuncModel
|
||||
import aqua.parser.expr.FuncExpr
|
||||
import aqua.parser.lexer.Arg
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.algebra.ValuesAlgebra
|
||||
import aqua.semantics.algebra.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.algebra.names.NamesAlgebra
|
||||
import aqua.semantics.algebra.scope.PeerIdAlgebra
|
||||
import aqua.semantics.algebra.types.{ArrowType, DataType, Type, TypesAlgebra}
|
||||
import aqua.semantics.{ArrowType, DataType, Prog, Type}
|
||||
import aqua.semantics.rules.ValuesAlgebra
|
||||
import aqua.semantics.rules.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.rules.names.NamesAlgebra
|
||||
import aqua.semantics.rules.scope.PeerIdAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
import cats.Applicative
|
||||
import cats.free.Free
|
||||
import cats.syntax.flatMap._
|
||||
@ -39,7 +39,7 @@ class FuncSem[F[_]](val expr: FuncExpr[F]) extends AnyVal {
|
||||
f.flatMap(acc =>
|
||||
T.resolveType(argType).flatMap {
|
||||
case Some(t: ArrowType) =>
|
||||
N.defineArrow(argName, ArrowGen.arg(argName.value, t), isRoot = false).as(acc.enqueue(t))
|
||||
N.defineArrow(argName, t, isRoot = false).as(acc.enqueue(t))
|
||||
case Some(t) =>
|
||||
N.define(argName, t).as(acc.enqueue(t))
|
||||
case None =>
|
||||
@ -83,13 +83,13 @@ class FuncSem[F[_]](val expr: FuncExpr[F]) extends AnyVal {
|
||||
case (n, dt: DataType) => n -> Left(dt)
|
||||
case (n, at: ArrowType) => n -> Right(at)
|
||||
},
|
||||
ret = retValue.map(ArrowGen.valueToData),
|
||||
ret = retValue.map(ValuesAlgebra.valueToData),
|
||||
body = FuncBodyGen(bg)
|
||||
)
|
||||
|
||||
N.defineArrow(
|
||||
name,
|
||||
ArrowGen.func(funcArrow, argNames, retValue.map(ArrowGen.valueToData), FuncBodyGen(bg)),
|
||||
funcArrow,
|
||||
isRoot = true
|
||||
) as model.gen
|
||||
case _ => Gen.noop.lift
|
||||
|
@ -1,11 +1,11 @@
|
||||
package aqua.semantics.expr
|
||||
|
||||
import aqua.generator.{AirGen, ArrowGen, Gen}
|
||||
import aqua.generator.{AirGen, Gen}
|
||||
import aqua.parser.expr.OnExpr
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.algebra.ValuesAlgebra
|
||||
import aqua.semantics.algebra.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.algebra.scope.PeerIdAlgebra
|
||||
import aqua.semantics.rules.ValuesAlgebra
|
||||
import aqua.semantics.rules.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.rules.scope.PeerIdAlgebra
|
||||
import cats.syntax.flatMap._
|
||||
import cats.syntax.functor._
|
||||
|
||||
@ -21,7 +21,7 @@ class OnSem[F[_]](val expr: OnExpr[F]) extends AnyVal {
|
||||
(_: Unit, ops: Gen) =>
|
||||
A.endScope() >> P.erasePeerId() as (ops match {
|
||||
case air: AirGen =>
|
||||
air.wrap(c => (c.copy(peerId = ArrowGen.valueToData(expr.peerId)), _.copy(peerId = c.peerId)))
|
||||
air.wrap(c => (c.copy(peerId = ValuesAlgebra.valueToData(expr.peerId)), _.copy(peerId = c.peerId)))
|
||||
case _ => ops
|
||||
})
|
||||
)
|
||||
|
@ -3,7 +3,7 @@ package aqua.semantics.expr
|
||||
import aqua.generator.Gen
|
||||
import aqua.parser.expr.ReturnExpr
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.algebra.ValuesAlgebra
|
||||
import aqua.semantics.rules.ValuesAlgebra
|
||||
import cats.syntax.functor._
|
||||
|
||||
class ReturnSem[F[_]](val expr: ReturnExpr[F]) extends AnyVal {
|
||||
|
@ -1,12 +1,12 @@
|
||||
package aqua.semantics.expr
|
||||
|
||||
import aqua.generator.{ArrowGen, Gen}
|
||||
import aqua.generator.Gen
|
||||
import aqua.parser.expr.ServiceExpr
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.algebra.ValuesAlgebra
|
||||
import aqua.semantics.algebra.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.algebra.names.NamesAlgebra
|
||||
import aqua.semantics.algebra.types.TypesAlgebra
|
||||
import aqua.semantics.rules.ValuesAlgebra
|
||||
import aqua.semantics.rules.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.rules.names.NamesAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
import cats.free.Free
|
||||
import cats.syntax.apply._
|
||||
import cats.syntax.flatMap._
|
||||
@ -27,7 +27,7 @@ class ServiceSem[F[_]](val expr: ServiceExpr[F]) extends AnyVal {
|
||||
case Some(nel) =>
|
||||
A.defineService(
|
||||
expr.name,
|
||||
nel.map(kv => kv._1.value -> ArrowGen.service(expr.name.value, kv._1.value, kv._2)).toNem
|
||||
nel.map(kv => kv._1.value -> kv._2).toNem
|
||||
) >>
|
||||
expr.id.fold(Free.pure[Alg, Gen](Gen.noop))(idV =>
|
||||
V.ensureIsString(idV) >> A.setServiceId(expr.name, idV) as Gen.noop
|
||||
|
@ -1,4 +1,4 @@
|
||||
package aqua.semantics.algebra
|
||||
package aqua.semantics.rules
|
||||
|
||||
import aqua.parser.lexer.Token
|
||||
|
@ -1,4 +1,4 @@
|
||||
package aqua.semantics.algebra
|
||||
package aqua.semantics.rules
|
||||
|
||||
import aqua.parser.lexer.Token
|
||||
import cats.data.State
|
@ -1,8 +1,10 @@
|
||||
package aqua.semantics.algebra
|
||||
package aqua.semantics.rules
|
||||
|
||||
import aqua.semantics.algebra.names.NamesAlgebra
|
||||
import aqua.semantics.algebra.types.{ArrowType, LiteralType, Type, TypesAlgebra}
|
||||
import aqua.parser.lexer.{Literal, Token, Value, VarLambda}
|
||||
import aqua.generator.DataView
|
||||
import aqua.semantics.rules.names.NamesAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
import aqua.parser.lexer.{IntoArray, IntoField, LambdaOp, Literal, Token, Value, VarLambda}
|
||||
import aqua.semantics.{ArrowType, LiteralType, Type}
|
||||
import cats.free.Free
|
||||
import cats.syntax.apply._
|
||||
|
||||
@ -52,22 +54,37 @@ class ValuesAlgebra[F[_], Alg[_]](implicit N: NamesAlgebra[F, Alg], T: TypesAlge
|
||||
.zip(arr.args)
|
||||
.foldLeft(
|
||||
Free.pure[Alg, Boolean](true)
|
||||
) {
|
||||
case (f, (ft, t)) =>
|
||||
(
|
||||
f,
|
||||
ft.flatMap {
|
||||
case None => Free.pure(false)
|
||||
case Some((tkn, valType)) =>
|
||||
T.ensureTypeMatches(tkn, t, valType)
|
||||
}
|
||||
).mapN(_ && _)
|
||||
) { case (f, (ft, t)) =>
|
||||
(
|
||||
f,
|
||||
ft.flatMap {
|
||||
case None => Free.pure(false)
|
||||
case Some((tkn, valType)) =>
|
||||
T.ensureTypeMatches(tkn, t, valType)
|
||||
}
|
||||
).mapN(_ && _)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object ValuesAlgebra {
|
||||
|
||||
private def opsToLens[F[_]](ops: List[LambdaOp[F]]): String =
|
||||
ops match {
|
||||
case Nil => ""
|
||||
case (_: IntoArray[F]) :: tail => "[@" + opsToLens(tail) + "]"
|
||||
case (f: IntoField[F]) :: tail => "." + f.value + opsToLens(tail)
|
||||
}
|
||||
|
||||
def valueToData[F[_]](v: Value[F]): DataView =
|
||||
v match {
|
||||
case l: Literal[F] => DataView.StringScalar(l.value)
|
||||
case VarLambda(name, Nil) => DataView.Variable(name.value)
|
||||
case VarLambda(name, ops) => DataView.VarLens(name.value, opsToLens(ops))
|
||||
}
|
||||
|
||||
private def argsToData[F[_]](args: List[Value[F]]): List[DataView] = args.map(valueToData)
|
||||
|
||||
implicit def deriveValuesAlgebra[F[_], Alg[_]](implicit
|
||||
N: NamesAlgebra[F, Alg],
|
||||
T: TypesAlgebra[F, Alg]
|
@ -1,8 +1,7 @@
|
||||
package aqua.semantics.algebra.abilities
|
||||
package aqua.semantics.rules.abilities
|
||||
|
||||
import aqua.semantics.algebra.types.ArrowType
|
||||
import aqua.generator.ArrowGen
|
||||
import aqua.parser.lexer.{Ability, Name, Token, Value}
|
||||
import aqua.semantics.ArrowType
|
||||
import cats.InjectK
|
||||
import cats.data.{NonEmptyList, NonEmptyMap}
|
||||
import cats.free.Free
|
||||
@ -15,16 +14,16 @@ class AbilitiesAlgebra[F[_], Alg[_]](implicit A: InjectK[AbilityOp[F, *], Alg])
|
||||
def purgeArrows(token: Token[F]): Free[Alg, Option[NonEmptyList[(Name[F], ArrowType)]]] =
|
||||
Free.liftInject[Alg](PurgeArrows[F](token))
|
||||
|
||||
def defineService(name: Ability[F], arrows: NonEmptyMap[String, ArrowGen]): Free[Alg, Boolean] =
|
||||
def defineService(name: Ability[F], arrows: NonEmptyMap[String, ArrowType]): Free[Alg, Boolean] =
|
||||
Free.liftInject[Alg](DefineService[F](name, arrows))
|
||||
|
||||
def getArrow(name: Ability[F], arrow: Name[F]): Free[Alg, Option[ArrowGen]] =
|
||||
def getArrow(name: Ability[F], arrow: Name[F]): Free[Alg, Option[ArrowType]] =
|
||||
Free.liftInject[Alg](GetArrow[F](name, arrow))
|
||||
|
||||
def setServiceId(name: Ability[F], id: Value[F]): Free[Alg, Boolean] =
|
||||
Free.liftInject[Alg](SetServiceId[F](name, id))
|
||||
|
||||
def getServiceId(name: String): Free[Alg, Option[Value[F]]] =
|
||||
def getServiceId(name: Ability[F]): Free[Alg, Option[Value[F]]] =
|
||||
Free.liftInject[Alg](GetServiceId[F](name))
|
||||
|
||||
def beginScope(token: Token[F]): Free[Alg, Unit] =
|
@ -1,21 +1,19 @@
|
||||
package aqua.semantics.algebra.abilities
|
||||
package aqua.semantics.rules.abilities
|
||||
|
||||
import aqua.semantics.algebra.{ReportError, StackInterpreter}
|
||||
import aqua.semantics.algebra.types.ArrowType
|
||||
import aqua.generator.ArrowGen
|
||||
import aqua.parser.lexer.{Ability, Name, Token, Value}
|
||||
import aqua.semantics.rules.{ReportError, StackInterpreter}
|
||||
import aqua.parser.lexer.{Name, Token, Value}
|
||||
import aqua.semantics.ArrowType
|
||||
import cats.data.{NonEmptyList, NonEmptyMap, State}
|
||||
import cats.~>
|
||||
import cats.syntax.functor._
|
||||
import monocle.Lens
|
||||
import monocle.macros.GenLens
|
||||
import monocle.macros.syntax.all._
|
||||
|
||||
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))
|
||||
with (AbilityOp[F, *] ~> State[X, *]) {
|
||||
|
||||
private def getService(name: String): S[Option[NonEmptyMap[String, ArrowGen]]] =
|
||||
private def getService(name: String): S[Option[NonEmptyMap[String, ArrowType]]] =
|
||||
getState.map(_.services.get(name))
|
||||
|
||||
override def apply[A](fa: AbilityOp[F, A]): State[X, A] =
|
||||
@ -42,10 +40,10 @@ class AbilitiesInterpreter[F[_], X](implicit lens: Lens[X, AbilitiesState[F]], e
|
||||
report(
|
||||
ga.arrow,
|
||||
s"Service found, but arrow is undefined, available: ${arrows.value.keys.toNonEmptyList.toList.mkString(", ")}"
|
||||
).as(Option.empty[ArrowGen])
|
||||
).as(Option.empty[ArrowType])
|
||||
)(a => State.pure(Some(a)))
|
||||
case None =>
|
||||
report(ga.name, "Ability with this name is undefined").as(Option.empty[ArrowGen])
|
||||
report(ga.name, "Ability with this name is undefined").as(Option.empty[ArrowType])
|
||||
}
|
||||
|
||||
case s: SetServiceId[F] =>
|
||||
@ -61,17 +59,10 @@ class AbilitiesInterpreter[F[_], X](implicit lens: Lens[X, AbilitiesState[F]], e
|
||||
|
||||
case s: GetServiceId[F] =>
|
||||
getState.flatMap(st =>
|
||||
st.stack.flatMap(_.serviceIds.get(s.name)).headOption orElse st.rootServiceIds.get(s.name) match {
|
||||
st.stack.flatMap(_.serviceIds.get(s.name.value)).headOption orElse st.rootServiceIds.get(s.name.value) match {
|
||||
case None =>
|
||||
st.stack.headOption
|
||||
.map(_.token)
|
||||
.fold(
|
||||
// TODO this should be an impossible error
|
||||
State.pure[X, Option[Value[F]]](Option.empty[Value[F]])
|
||||
)(t =>
|
||||
report(t, s"Service ID unresolved, use `${s.name} id` expression to set it")
|
||||
.as(Option.empty[Value[F]])
|
||||
)
|
||||
report(s.name, s"Service ID unresolved, use `${s.name} id` expression to set it")
|
||||
.as(Option.empty[Value[F]])
|
||||
|
||||
case v => State.pure(v)
|
||||
}
|
||||
@ -99,7 +90,7 @@ class AbilitiesInterpreter[F[_], X](implicit lens: Lens[X, AbilitiesState[F]], e
|
||||
|
||||
case class AbilitiesState[F[_]](
|
||||
stack: List[AbilityStackFrame[F]] = Nil,
|
||||
services: Map[String, NonEmptyMap[String, ArrowGen]] = Map.empty,
|
||||
services: Map[String, NonEmptyMap[String, ArrowType]] = Map.empty,
|
||||
rootServiceIds: Map[String, Value[F]] = Map.empty[String, Value[F]]
|
||||
) {
|
||||
|
@ -1,8 +1,7 @@
|
||||
package aqua.semantics.algebra.abilities
|
||||
package aqua.semantics.rules.abilities
|
||||
|
||||
import aqua.semantics.algebra.types.ArrowType
|
||||
import aqua.generator.ArrowGen
|
||||
import aqua.parser.lexer.{Ability, Name, Token, Value}
|
||||
import aqua.semantics.ArrowType
|
||||
import cats.data.{NonEmptyList, NonEmptyMap}
|
||||
|
||||
sealed trait AbilityOp[F[_], T]
|
||||
@ -11,13 +10,13 @@ case class DefineArrow[F[_]](arrow: Name[F], `type`: ArrowType) extends AbilityO
|
||||
|
||||
case class PurgeArrows[F[_]](token: Token[F]) extends AbilityOp[F, Option[NonEmptyList[(Name[F], ArrowType)]]]
|
||||
|
||||
case class DefineService[F[_]](name: Ability[F], arrows: NonEmptyMap[String, ArrowGen]) extends AbilityOp[F, Boolean]
|
||||
case class DefineService[F[_]](name: Ability[F], arrows: NonEmptyMap[String, ArrowType]) extends AbilityOp[F, Boolean]
|
||||
|
||||
case class GetArrow[F[_]](name: Ability[F], arrow: Name[F]) extends AbilityOp[F, Option[ArrowGen]]
|
||||
case class GetArrow[F[_]](name: Ability[F], arrow: Name[F]) extends AbilityOp[F, Option[ArrowType]]
|
||||
|
||||
case class SetServiceId[F[_]](name: Ability[F], id: Value[F]) extends AbilityOp[F, Boolean]
|
||||
|
||||
case class GetServiceId[F[_]](name: String) extends AbilityOp[F, Option[Value[F]]]
|
||||
case class GetServiceId[F[_]](name: Ability[F]) extends AbilityOp[F, Option[Value[F]]]
|
||||
|
||||
case class BeginScope[F[_]](token: Token[F]) extends AbilityOp[F, Unit]
|
||||
|
@ -1,18 +1,17 @@
|
||||
package aqua.semantics.algebra.names
|
||||
package aqua.semantics.rules.names
|
||||
|
||||
import aqua.semantics.algebra.types.Type
|
||||
import aqua.generator.ArrowGen
|
||||
import aqua.parser.lexer.{Name, Token}
|
||||
import aqua.semantics.{ArrowType, Type}
|
||||
|
||||
sealed trait NameOp[F[_], T]
|
||||
|
||||
case class ReadName[F[_]](name: Name[F]) extends NameOp[F, Option[Type]]
|
||||
|
||||
case class ReadArrow[F[_]](name: Name[F]) extends NameOp[F, Option[ArrowGen]]
|
||||
case class ReadArrow[F[_]](name: Name[F]) extends NameOp[F, Option[ArrowType]]
|
||||
|
||||
case class DefineName[F[_]](name: Name[F], `type`: Type) extends NameOp[F, Boolean]
|
||||
|
||||
case class DefineArrow[F[_]](name: Name[F], gen: ArrowGen, isRoot: Boolean) extends NameOp[F, Boolean]
|
||||
case class DefineArrow[F[_]](name: Name[F], gen: ArrowType, isRoot: Boolean) extends NameOp[F, Boolean]
|
||||
|
||||
case class BeginScope[F[_]](token: Token[F]) extends NameOp[F, Unit]
|
||||
|
@ -1,8 +1,7 @@
|
||||
package aqua.semantics.algebra.names
|
||||
package aqua.semantics.rules.names
|
||||
|
||||
import aqua.semantics.algebra.types.{ArrowType, Type}
|
||||
import aqua.generator.ArrowGen
|
||||
import aqua.parser.lexer.{Name, Token}
|
||||
import aqua.semantics.{ArrowType, Type}
|
||||
import cats.InjectK
|
||||
import cats.free.Free
|
||||
|
||||
@ -11,13 +10,13 @@ class NamesAlgebra[F[_], Alg[_]](implicit V: InjectK[NameOp[F, *], Alg]) {
|
||||
def read(name: Name[F]): Free[Alg, Option[Type]] =
|
||||
Free.liftInject[Alg](ReadName(name))
|
||||
|
||||
def readArrow(name: Name[F]): Free[Alg, Option[ArrowGen]] =
|
||||
def readArrow(name: Name[F]): Free[Alg, Option[ArrowType]] =
|
||||
Free.liftInject[Alg](ReadArrow(name))
|
||||
|
||||
def define(name: Name[F], `type`: Type): Free[Alg, Boolean] =
|
||||
Free.liftInject[Alg](DefineName(name, `type`))
|
||||
|
||||
def defineArrow(name: Name[F], gen: ArrowGen, isRoot: Boolean): Free[Alg, Boolean] =
|
||||
def defineArrow(name: Name[F], gen: ArrowType, isRoot: Boolean): Free[Alg, Boolean] =
|
||||
Free.liftInject[Alg](DefineArrow(name, gen, isRoot))
|
||||
|
||||
def beginScope(token: Token[F]): Free[Alg, Unit] =
|
@ -1,9 +1,8 @@
|
||||
package aqua.semantics.algebra.names
|
||||
package aqua.semantics.rules.names
|
||||
|
||||
import aqua.semantics.algebra.types.Type
|
||||
import aqua.semantics.algebra.{ReportError, StackInterpreter}
|
||||
import aqua.generator.ArrowGen
|
||||
import aqua.semantics.rules.{ReportError, StackInterpreter}
|
||||
import aqua.parser.lexer.Token
|
||||
import aqua.semantics.{ArrowType, Type}
|
||||
import cats.data.State
|
||||
import cats.~>
|
||||
import monocle.Lens
|
||||
@ -19,11 +18,11 @@ class NamesInterpreter[F[_], X](implicit lens: Lens[X, NamesState[F]], error: Re
|
||||
getState.map { st =>
|
||||
st.stack.collectFirst {
|
||||
case frame if frame.names.contains(name) => frame.names(name)
|
||||
case frame if frame.arrows.contains(name) => frame.arrows(name).`type`
|
||||
} orElse st.rootArrows.get(name).map(_.`type`)
|
||||
case frame if frame.arrows.contains(name) => frame.arrows(name)
|
||||
} orElse st.rootArrows.get(name)
|
||||
}
|
||||
|
||||
def readArrow(name: String): S[Option[ArrowGen]] =
|
||||
def readArrow(name: String): S[Option[ArrowType]] =
|
||||
getState.map { st =>
|
||||
st.stack.flatMap(_.arrows.get(name)).headOption orElse st.rootArrows.get(name)
|
||||
}
|
||||
@ -42,7 +41,7 @@ class NamesInterpreter[F[_], X](implicit lens: Lens[X, NamesState[F]], error: Re
|
||||
case None =>
|
||||
getState.flatMap(st =>
|
||||
report(ra.name, "Undefined arrow, available: " + st.allNames.mkString(", "))
|
||||
.as(Option.empty[ArrowGen])
|
||||
.as(Option.empty[ArrowType])
|
||||
)
|
||||
}
|
||||
|
||||
@ -75,7 +74,7 @@ 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, rootArrows: Map[String, ArrowGen] = Map.empty) {
|
||||
case class NamesState[F[_]](stack: List[NamesFrame[F]] = Nil, rootArrows: Map[String, ArrowType] = Map.empty) {
|
||||
|
||||
def allNames: LazyList[String] =
|
||||
LazyList.from(stack).flatMap(s => s.names.keys ++ s.arrows.keys).appendedAll(rootArrows.keys)
|
||||
@ -87,8 +86,8 @@ case class NamesState[F[_]](stack: List[NamesFrame[F]] = Nil, rootArrows: Map[St
|
||||
case class NamesFrame[F[_]](
|
||||
token: Token[F],
|
||||
names: Map[String, Type] = Map.empty,
|
||||
arrows: Map[String, ArrowGen] = Map.empty
|
||||
arrows: Map[String, ArrowType] = Map.empty
|
||||
) {
|
||||
def addName(n: String, t: Type): NamesFrame[F] = copy[F](names = names.updated(n, t))
|
||||
def addArrow(n: String, g: ArrowGen): NamesFrame[F] = copy[F](arrows = arrows.updated(n, g))
|
||||
def addArrow(n: String, g: ArrowType): NamesFrame[F] = copy[F](arrows = arrows.updated(n, g))
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package aqua.semantics.algebra.scope
|
||||
package aqua.semantics.rules.scope
|
||||
|
||||
import aqua.parser.lexer.Value
|
||||
import cats.InjectK
|
@ -1,6 +1,6 @@
|
||||
package aqua.semantics.algebra.scope
|
||||
package aqua.semantics.rules.scope
|
||||
|
||||
import aqua.semantics.algebra.{ReportError, StackInterpreter}
|
||||
import aqua.semantics.rules.{ReportError, StackInterpreter}
|
||||
import aqua.parser.lexer.Value
|
||||
import cats.data.State
|
||||
import cats.~>
|
@ -1,4 +1,4 @@
|
||||
package aqua.semantics.algebra.scope
|
||||
package aqua.semantics.rules.scope
|
||||
|
||||
import aqua.parser.lexer.Value
|
||||
|
@ -1,6 +1,7 @@
|
||||
package aqua.semantics.algebra.types
|
||||
package aqua.semantics.rules.types
|
||||
|
||||
import aqua.parser.lexer.{ArrowDef, ArrowTypeToken, CustomTypeToken, LambdaOp, Name, Token, TypeToken}
|
||||
import aqua.semantics.{ArrowType, Type}
|
||||
import cats.data.{NonEmptyList, NonEmptyMap}
|
||||
|
||||
sealed trait TypeOp[F[_], T]
|
@ -1,6 +1,7 @@
|
||||
package aqua.semantics.algebra.types
|
||||
package aqua.semantics.rules.types
|
||||
|
||||
import aqua.parser.lexer.{ArrowDef, ArrowTypeToken, CustomTypeToken, LambdaOp, Name, Token, TypeToken}
|
||||
import aqua.semantics.{ArrowType, Type}
|
||||
import cats.InjectK
|
||||
import cats.data.{NonEmptyList, NonEmptyMap}
|
||||
import cats.free.Free
|
@ -1,6 +1,6 @@
|
||||
package aqua.semantics.algebra.types
|
||||
package aqua.semantics.rules.types
|
||||
|
||||
import aqua.semantics.algebra.ReportError
|
||||
import aqua.semantics.rules.ReportError
|
||||
import aqua.parser.lexer.{
|
||||
ArrayTypeToken,
|
||||
ArrowTypeToken,
|
||||
@ -13,6 +13,7 @@ import aqua.parser.lexer.{
|
||||
Token,
|
||||
TypeToken
|
||||
}
|
||||
import aqua.semantics.{ArrayType, ArrowType, DataType, ProductType, Type}
|
||||
import cats.data.Validated.{Invalid, Valid}
|
||||
import cats.data.{NonEmptyList, NonEmptyMap, State, ValidatedNel}
|
||||
import cats.~>
|
||||
@ -49,8 +50,8 @@ class TypesInterpreter[F[_], X](implicit lens: Lens[X, TypesState[F]], error: Re
|
||||
case Valid(t) => State.pure[X, Option[ArrowType]](Some(t))
|
||||
case Invalid(errs) =>
|
||||
errs
|
||||
.foldLeft[S[Option[ArrowType]]](State.pure(None)) {
|
||||
case (n, (tkn, hint)) => report(tkn, hint) >> n
|
||||
.foldLeft[S[Option[ArrowType]]](State.pure(None)) { case (n, (tkn, hint)) =>
|
||||
report(tkn, hint) >> n
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,17 +103,17 @@ case class TypesState[F[_]](
|
||||
def resolveTypeToken(tt: TypeToken[F]): Option[Type] =
|
||||
tt match {
|
||||
case ArrayTypeToken(_, dtt) =>
|
||||
resolveTypeToken(dtt).collect {
|
||||
case it: DataType => ArrayType(it)
|
||||
resolveTypeToken(dtt).collect { case it: DataType =>
|
||||
ArrayType(it)
|
||||
}
|
||||
case ctt: CustomTypeToken[F] => strict.get(ctt.value)
|
||||
case btt: BasicTypeToken[F] => Some(btt.value)
|
||||
case ArrowTypeToken(_, args, res) =>
|
||||
val strictArgs = args.map(resolveTypeToken).collect {
|
||||
case Some(dt: DataType) => dt
|
||||
val strictArgs = args.map(resolveTypeToken).collect { case Some(dt: DataType) =>
|
||||
dt
|
||||
}
|
||||
val strictRes = res.flatMap(resolveTypeToken).collect {
|
||||
case dt: DataType => dt
|
||||
val strictRes = res.flatMap(resolveTypeToken).collect { case dt: DataType =>
|
||||
dt
|
||||
}
|
||||
Option.when(strictRes.isDefined == res.isDefined && strictArgs.length == args.length)(
|
||||
ArrowType(strictArgs, strictRes)
|
@ -1,6 +1,5 @@
|
||||
package aqua.parser
|
||||
|
||||
import aqua.semantics.algebra.types.LiteralType
|
||||
import aqua.parser.expr.{AbilityIdExpr, CoalgebraExpr, FuncExpr, OnExpr}
|
||||
import aqua.parser.lexer.{Ability, IntoField, Literal, Name, VarLambda}
|
||||
import cats.data.NonEmptyList
|
||||
@ -8,6 +7,7 @@ import org.scalatest.EitherValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import aqua.parser.lift.LiftParser.Implicits.idLiftParser
|
||||
import aqua.semantics.LiteralType
|
||||
import cats.Id
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
@ -1,7 +1,6 @@
|
||||
package aqua.parser
|
||||
|
||||
import aqua.semantics.algebra.types.ScalarType.{bool, u64}
|
||||
import aqua.semantics.algebra.types.{LiteralType, ScalarType}
|
||||
import aqua.semantics.ScalarType.{bool, u64}
|
||||
import aqua.parser.expr.FuncExpr
|
||||
import aqua.parser.lexer.{
|
||||
Ability,
|
||||
@ -19,13 +18,14 @@ import org.scalatest.EitherValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import aqua.parser.lift.LiftParser.Implicits.idLiftParser
|
||||
import aqua.semantics.ScalarType
|
||||
import cats.Id
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
class FuncSpec extends AnyFlatSpec with Matchers with EitherValues {
|
||||
|
||||
import aqua.semantics.algebra.types.ScalarType.{string, u32}
|
||||
import aqua.semantics.ScalarType.{string, u32}
|
||||
|
||||
implicit def scToBt(sc: ScalarType): BasicTypeToken[Id] = BasicTypeToken[Id](sc)
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
package aqua.parser.lexer
|
||||
|
||||
import aqua.semantics.algebra.types.ScalarType
|
||||
import org.scalatest.EitherValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import aqua.parser.lift.LiftParser.Implicits.idLiftParser
|
||||
import aqua.semantics.ScalarType
|
||||
import cats.Id
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
@ -1,10 +1,10 @@
|
||||
package aqua.parser.lexer
|
||||
|
||||
import aqua.semantics.algebra.types.LiteralType
|
||||
import org.scalatest.EitherValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import aqua.parser.lift.LiftParser.Implicits.idLiftParser
|
||||
import aqua.semantics.LiteralType
|
||||
import cats.Id
|
||||
|
||||
class ValueSpec extends AnyFlatSpec with Matchers with EitherValues {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package aqua.semantics
|
||||
|
||||
import aqua.parser.expr.ArrowTypeExpr
|
||||
import aqua.semantics.algebra.types.ScalarType
|
||||
import aqua.parser.lexer.{ArrowTypeToken, BasicTypeToken, CustomTypeToken, DataTypeToken, Name}
|
||||
import org.scalatest.EitherValues
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
|
@ -1,16 +1,16 @@
|
||||
package aqua.semantics.algebra
|
||||
package aqua.semantics.rules
|
||||
|
||||
import aqua.semantics.algebra.types.{ArrayType, ArrowType, DataType, LiteralType, ProductType, Type}
|
||||
import aqua.semantics.{ArrayType, ArrowType, DataType, LiteralType, ProductType, Type}
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import cats.syntax.partialOrder._
|
||||
import aqua.semantics.algebra.types.Type.typesPartialOrder
|
||||
import aqua.semantics.Type.typesPartialOrder
|
||||
import cats.data.NonEmptyMap
|
||||
import cats.kernel.PartialOrder
|
||||
|
||||
class TypeSpec extends AnyFlatSpec with Matchers {
|
||||
|
||||
import aqua.semantics.algebra.types.ScalarType._
|
||||
import aqua.semantics.ScalarType._
|
||||
|
||||
def `[]`(t: DataType): DataType = ArrayType(t)
|
||||
|
Loading…
Reference in New Issue
Block a user