mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 06:30:17 +00:00
bump changes
This commit is contained in:
parent
df2e794a99
commit
deb56c3021
@ -2,11 +2,23 @@ service Console("run-console"):
|
||||
print(s: string)
|
||||
|
||||
func main():
|
||||
ss: *string
|
||||
dd: *string
|
||||
peerId = "peerId"
|
||||
relay = "relay"
|
||||
parsec s <- ss on peerId via relay:
|
||||
Console.print(s)
|
||||
for d <- dd par:
|
||||
Console.print(d)
|
||||
-- NewConsole = Console.??id??("new id")
|
||||
-- NewConsole.print("")
|
||||
|
||||
Console "new id"
|
||||
NewAb = Ab(print = Console.print)
|
||||
|
||||
|
||||
Console.print("sfre")
|
||||
|
||||
for i <- incr:
|
||||
Console "inside for id"
|
||||
Console.print("sfre")
|
||||
|
||||
|
||||
Console "new id"
|
||||
Console.print("sfre")
|
||||
|
||||
Console "inside for id"
|
||||
-- Console -> ConsoleNew
|
||||
Console.print("sfre")
|
||||
|
@ -18,7 +18,7 @@ object MakeAbilityRawInliner extends RawInliner[AbilityRaw] {
|
||||
fields: NonEmptyMap[String, (ValueModel, Inline)]
|
||||
): State[S, Unit] = {
|
||||
for {
|
||||
res <- fields.toNel.traverse {
|
||||
_ <- fields.toNel.traverse {
|
||||
case (n, (Ability(abilityName, _, _), _)) =>
|
||||
val leftName = AbilityType.fullName(name, n)
|
||||
Exports[S].copyWithAbilityPrefix(abilityName, leftName)
|
||||
|
@ -10,3 +10,8 @@ case class ArrowRaw(
|
||||
ret: List[ValueRaw],
|
||||
body: RawTag.Tree
|
||||
) extends Raw
|
||||
|
||||
// func -internal-():
|
||||
// AssignemntTag(res1, CallArrowRaw("serviceId"))
|
||||
// res1 <- CallArrowRaw("serviceId")
|
||||
// <- res1
|
||||
|
@ -1,6 +1,5 @@
|
||||
package aqua.raw.arrow
|
||||
|
||||
import aqua.raw.value.ValueRaw
|
||||
import aqua.raw.RawPart
|
||||
import aqua.types.Type
|
||||
|
||||
|
@ -277,15 +277,6 @@ object EmptyTag extends NoExecTag {
|
||||
override def mapValues(f: ValueRaw => ValueRaw): RawTag = this
|
||||
}
|
||||
|
||||
case class AbilityIdTag(
|
||||
value: ValueRaw,
|
||||
service: String
|
||||
) extends NoExecTag {
|
||||
|
||||
override def mapValues(f: ValueRaw => ValueRaw): RawTag =
|
||||
AbilityIdTag(value.map(f), service)
|
||||
}
|
||||
|
||||
case class PushToStreamTag(operand: ValueRaw, exportTo: Call.Export) extends RawTag {
|
||||
|
||||
override def exportsVarNames: Set[String] = Set(exportTo.name)
|
||||
|
@ -95,6 +95,17 @@ case class ApplyGateRaw(name: String, streamType: StreamType, idx: ValueRaw) ext
|
||||
override def varNames: Set[String] = Set(name) ++ idx.varNames
|
||||
}
|
||||
|
||||
case class ServiceFuncRaw(name: String, baseType: ArrowType) extends ValueRaw {
|
||||
override def map(f: ValueRaw => ValueRaw): ValueRaw = f(this)
|
||||
|
||||
override def renameVars(map: Map[String, String]): ValueRaw =
|
||||
copy(map.getOrElse(name, name))
|
||||
|
||||
override def toString: String = s"var{$name: " + baseType + s"}"
|
||||
|
||||
override def varNames: Set[String] = Set(name)
|
||||
}
|
||||
|
||||
case class VarRaw(name: String, baseType: Type) extends ValueRaw {
|
||||
|
||||
override def map(f: ValueRaw => ValueRaw): ValueRaw = f(this)
|
||||
@ -164,8 +175,10 @@ case class MakeStructRaw(fields: NonEmptyMap[String, ValueRaw], structType: Stru
|
||||
copy(fields = fields.map(_.renameVars(map)))
|
||||
}
|
||||
|
||||
case class AbilityRaw(fieldsAndArrows: NonEmptyMap[String, ValueRaw], abilityType: AbilityType)
|
||||
extends ValueRaw {
|
||||
case class AbilityRaw(
|
||||
fieldsAndArrows: NonEmptyMap[String, ValueRaw],
|
||||
abilityType: AbilityType
|
||||
) extends ValueRaw {
|
||||
|
||||
override def baseType: Type = abilityType
|
||||
|
||||
@ -234,6 +247,27 @@ object ApplyUnaryOpRaw {
|
||||
}
|
||||
}
|
||||
|
||||
case class ServiceCallDefinitionRaw(
|
||||
name: String,
|
||||
baseType: ArrowType,
|
||||
serviceId: ValueRaw
|
||||
) extends ValueRaw {
|
||||
override def `type`: Type = baseType.codomain.uncons.map(_._1).getOrElse(baseType)
|
||||
|
||||
override def map(f: ValueRaw => ValueRaw): ValueRaw =
|
||||
this
|
||||
|
||||
override def varNames: Set[String] = Set.empty
|
||||
|
||||
override def renameVars(map: Map[String, String]): ValueRaw =
|
||||
copy(
|
||||
serviceId = serviceId.renameVars(map)
|
||||
)
|
||||
|
||||
override def toString: String =
|
||||
s"(service calldef ($serviceId $name) $baseType)"
|
||||
}
|
||||
|
||||
case class CallArrowRaw(
|
||||
// TODO: ability should hold a type, not name
|
||||
ability: Option[String],
|
||||
|
@ -2,10 +2,9 @@ package aqua.model
|
||||
|
||||
import aqua.raw.arrow.FuncRaw
|
||||
import aqua.raw.ops.CallArrowRawTag
|
||||
import aqua.raw.value.ValueRaw
|
||||
import aqua.raw.value.CallArrowRaw
|
||||
import aqua.raw.value.{AbilityRaw, CallArrowRaw, LiteralRaw, ValueRaw, VarRaw}
|
||||
import aqua.raw.{ConstantRaw, RawContext, RawPart, ServiceRaw, TypeRaw}
|
||||
import aqua.types.{StructType, Type}
|
||||
import aqua.types.{AbilityType, StructType, Type}
|
||||
import cats.Monoid
|
||||
import cats.data.NonEmptyMap
|
||||
import cats.data.Chain
|
||||
@ -140,7 +139,7 @@ object AquaContext extends Logging {
|
||||
.get(rawContext)
|
||||
.fold {
|
||||
logger.trace(s"Compiling ${rawContext.module}, cache has ${cache.size} entries")
|
||||
|
||||
println("raw parts: " + rawContext.parts)
|
||||
val (newCtx, newCache) = rawContext.parts
|
||||
.foldLeft[(AquaContext, Cache)] {
|
||||
// Laziness unefficiency happens here
|
||||
@ -165,11 +164,23 @@ object AquaContext extends Logging {
|
||||
// Actually this should have no effect, as constants are resolved by semantics
|
||||
val (pctx, pcache) = fromRawContext(partContext, ctxCache)
|
||||
logger.trace("Got " + c.name + " from raw")
|
||||
val values = c.value match {
|
||||
// it could be only for services with default service ids
|
||||
// case AbilityRaw(fieldsAndArrows, abilityType, Some(LiteralRaw(v, _))) =>
|
||||
// fieldsAndArrows.flatMap {
|
||||
// case VarRaw(n, t) =>
|
||||
// Some(CallArrowRaw(None, AbilityType.fullName(abilityType.name, n), ))
|
||||
// case _ => None
|
||||
// }
|
||||
case _ =>
|
||||
if (c.allowOverrides && pctx.values.contains(c.name)) Map.empty
|
||||
else Map(c.name -> ValueModel.fromRaw(c.value).resolveWith(pctx.allValues))
|
||||
}
|
||||
|
||||
val add =
|
||||
blank
|
||||
.copy(values =
|
||||
if (c.allowOverrides && pctx.values.contains(c.name)) Map.empty
|
||||
else Map(c.name -> ValueModel.fromRaw(c.value).resolveWith(pctx.allValues))
|
||||
values
|
||||
)
|
||||
|
||||
(ctx |+| add, pcache)
|
||||
|
@ -48,7 +48,9 @@ object ValueModel {
|
||||
VarModel(name, t)
|
||||
case LiteralRaw(value, t) =>
|
||||
LiteralModel(value, t)
|
||||
case _ => ???
|
||||
case p =>
|
||||
println("catch: " + p)
|
||||
???
|
||||
}
|
||||
|
||||
object Ability {
|
||||
|
@ -20,7 +20,7 @@ case class ArrowExpr[F[_]](arrowTypeExpr: ArrowTypeToken[F])
|
||||
object ArrowExpr extends Expr.AndIndented {
|
||||
|
||||
val funcChildren: List[Expr.Lexem] =
|
||||
AbilityIdExpr ::
|
||||
ServiceIdExpr ::
|
||||
PushToStreamExpr ::
|
||||
ForExpr ::
|
||||
Expr.defer(OnExpr) ::
|
||||
|
@ -1,7 +1,7 @@
|
||||
package aqua.parser.expr.func
|
||||
|
||||
import aqua.parser.Expr
|
||||
import aqua.parser.expr.func.AbilityIdExpr
|
||||
import aqua.parser.expr.func.ServiceIdExpr
|
||||
import aqua.parser.lexer.Token.*
|
||||
import aqua.parser.lexer.{Ability, NamedTypeToken, ValueToken}
|
||||
import aqua.parser.lift.LiftParser
|
||||
@ -10,19 +10,19 @@ import cats.{Comonad, ~>}
|
||||
import aqua.parser.lift.Span
|
||||
import aqua.parser.lift.Span.{P0ToSpan, PToSpan}
|
||||
|
||||
case class AbilityIdExpr[F[_]](ability: NamedTypeToken[F], id: ValueToken[F])
|
||||
extends Expr[F](AbilityIdExpr, ability) {
|
||||
case class ServiceIdExpr[F[_]](ability: NamedTypeToken[F], id: ValueToken[F])
|
||||
extends Expr[F](ServiceIdExpr, ability) {
|
||||
|
||||
def mapK[K[_]: Comonad](fk: F ~> K): AbilityIdExpr[K] =
|
||||
def mapK[K[_]: Comonad](fk: F ~> K): ServiceIdExpr[K] =
|
||||
copy(ability.copy(fk(ability.name)), id.mapK(fk))
|
||||
|
||||
}
|
||||
|
||||
object AbilityIdExpr extends Expr.Leaf {
|
||||
object ServiceIdExpr extends Expr.Leaf {
|
||||
|
||||
override val p: P[AbilityIdExpr[Span.S]] =
|
||||
override val p: P[ServiceIdExpr[Span.S]] =
|
||||
((NamedTypeToken.dotted <* ` `) ~ ValueToken.`value`).map { case (ability, id) =>
|
||||
AbilityIdExpr(ability, id)
|
||||
ServiceIdExpr(ability, id)
|
||||
}
|
||||
|
||||
}
|
@ -118,8 +118,8 @@ trait AquaSpec extends EitherValues {
|
||||
def parseUse(str: String): UseFromExpr[Id] =
|
||||
UseFromExpr.p.parseAll(str).value.mapK(spanToId)
|
||||
|
||||
def parseAbId(str: String): AbilityIdExpr[Id] =
|
||||
AbilityIdExpr.p.parseAll(str).value.mapK(spanToId)
|
||||
def parseAbId(str: String): ServiceIdExpr[Id] =
|
||||
ServiceIdExpr.p.parseAll(str).value.mapK(spanToId)
|
||||
|
||||
def parseOn(str: String): OnExpr[Id] =
|
||||
OnExpr.p.parseAll(str).value.mapK(spanToId)
|
||||
|
@ -2,7 +2,7 @@ package aqua.parser
|
||||
|
||||
import aqua.AquaSpec
|
||||
import aqua.parser.expr.*
|
||||
import aqua.parser.expr.func.{AbilityIdExpr, ArrowExpr, CallArrowExpr, IfExpr, OnExpr, ReturnExpr}
|
||||
import aqua.parser.expr.func.{ServiceIdExpr, ArrowExpr, CallArrowExpr, IfExpr, OnExpr, ReturnExpr}
|
||||
import aqua.parser.lexer.{
|
||||
ArrowTypeToken,
|
||||
BasicTypeToken,
|
||||
@ -123,7 +123,7 @@ class FuncExprSpec extends AnyFlatSpec with Matchers with Inside with Inspectors
|
||||
)
|
||||
)
|
||||
)
|
||||
ifBody(1).head.mapK(spanToId) should be(AbilityIdExpr(toNamedType("Peer"), toStr("some id")))
|
||||
ifBody(1).head.mapK(spanToId) should be(ServiceIdExpr(toNamedType("Peer"), toStr("some id")))
|
||||
ifBody(2).head.mapK(spanToId) should be(
|
||||
CallArrowExpr(Nil, CallArrowToken("call", List(toBool(true))))
|
||||
)
|
||||
|
@ -1,31 +1,31 @@
|
||||
package aqua.parser
|
||||
|
||||
import aqua.AquaSpec
|
||||
import aqua.parser.expr.func.AbilityIdExpr
|
||||
import aqua.parser.expr.func.ServiceIdExpr
|
||||
import aqua.parser.lexer.LiteralToken
|
||||
import aqua.types.LiteralType
|
||||
import cats.Id
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
|
||||
class AbilityIdExprSpec extends AnyFlatSpec with Matchers with AquaSpec {
|
||||
class ServiceIdExprSpec extends AnyFlatSpec with Matchers with AquaSpec {
|
||||
import AquaSpec._
|
||||
|
||||
"abilities" should "be parsed" in {
|
||||
parseAbId("Ab a") should be(
|
||||
AbilityIdExpr[Id](toNamedType("Ab"), toVar("a"))
|
||||
ServiceIdExpr[Id](toNamedType("Ab"), toVar("a"))
|
||||
)
|
||||
|
||||
parseAbId("Ab \"a\"") should be(
|
||||
AbilityIdExpr[Id](toNamedType("Ab"), LiteralToken[Id]("\"a\"", LiteralType.string))
|
||||
ServiceIdExpr[Id](toNamedType("Ab"), LiteralToken[Id]("\"a\"", LiteralType.string))
|
||||
)
|
||||
|
||||
parseAbId("Ab 1") should be(
|
||||
AbilityIdExpr[Id](toNamedType("Ab"), toNumber(1))
|
||||
ServiceIdExpr[Id](toNamedType("Ab"), toNumber(1))
|
||||
)
|
||||
|
||||
parseAbId("Ab a.id") should be(
|
||||
AbilityIdExpr[Id](toNamedType("Ab"), toVarLambda("a", List("id")))
|
||||
ServiceIdExpr[Id](toNamedType("Ab"), toVarLambda("a", List("id")))
|
||||
)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package aqua.parser.head
|
||||
|
||||
import aqua.AquaSpec
|
||||
import aqua.parser.expr.func.AbilityIdExpr
|
||||
import aqua.parser.expr.func.ServiceIdExpr
|
||||
import aqua.parser.lexer.{LiteralToken, Token}
|
||||
import aqua.parser.lift.LiftParser.Implicits.*
|
||||
import aqua.types.LiteralType
|
||||
|
@ -1,7 +1,7 @@
|
||||
package aqua.parser.head
|
||||
|
||||
import aqua.AquaSpec
|
||||
import aqua.parser.expr.func.AbilityIdExpr
|
||||
import aqua.parser.expr.func.ServiceIdExpr
|
||||
import aqua.parser.lexer.{LiteralToken, Token}
|
||||
import aqua.parser.lift.LiftParser.Implicits.*
|
||||
import aqua.types.LiteralType
|
||||
|
@ -1,7 +1,7 @@
|
||||
package aqua.parser.head
|
||||
|
||||
import aqua.AquaSpec
|
||||
import aqua.parser.expr.func.AbilityIdExpr
|
||||
import aqua.parser.expr.func.ServiceIdExpr
|
||||
import aqua.parser.lexer.{LiteralToken, Token}
|
||||
import aqua.types.LiteralType
|
||||
import cats.Id
|
||||
|
@ -1,7 +1,7 @@
|
||||
package aqua.parser.head
|
||||
|
||||
import aqua.AquaSpec
|
||||
import aqua.parser.expr.func.AbilityIdExpr
|
||||
import aqua.parser.expr.func.ServiceIdExpr
|
||||
import aqua.parser.lexer.{LiteralToken, Token}
|
||||
import aqua.parser.lift.LiftParser.Implicits.*
|
||||
import aqua.types.LiteralType
|
||||
|
@ -27,7 +27,7 @@ object ExprSem {
|
||||
L: LocationsAlgebra[S, G]
|
||||
): Prog[G, Raw] =
|
||||
expr match {
|
||||
case expr: AbilityIdExpr[S] => new AbilityIdSem(expr).program[G]
|
||||
case expr: ServiceIdExpr[S] => new ServiceIdSem(expr).program[G]
|
||||
case expr: AssignmentExpr[S] => new AssignmentSem(expr).program[G]
|
||||
case expr: PushToStreamExpr[S] => new PushToStreamSem(expr).program[G]
|
||||
case expr: AliasExpr[S] => new AliasSem(expr).program[G]
|
||||
|
@ -1,21 +1,119 @@
|
||||
package aqua.semantics.expr
|
||||
|
||||
import aqua.parser.expr.ServiceExpr
|
||||
import aqua.raw.{Raw, ServiceRaw}
|
||||
import aqua.raw.arrow.{ArrowRaw, FuncRaw}
|
||||
import aqua.raw.ops.CallArrowRawTag
|
||||
import aqua.raw.value.{AbilityRaw, CallArrowRaw, ValueRaw, VarRaw}
|
||||
import aqua.raw.{ConstantRaw, Raw, RawPart, ServiceRaw, TypeRaw}
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.rules.ValuesAlgebra
|
||||
import aqua.semantics.rules.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.rules.definitions.DefinitionsAlgebra
|
||||
import aqua.semantics.rules.names.NamesAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
import aqua.types.{AbilityType, ArrowType}
|
||||
import cats.syntax.apply.*
|
||||
import cats.syntax.flatMap.*
|
||||
import cats.syntax.functor.*
|
||||
import cats.syntax.applicative.*
|
||||
import cats.syntax.traverse.*
|
||||
import cats.Monad
|
||||
import cats.data.Chain
|
||||
|
||||
class ServiceSem[S[_]](val expr: ServiceExpr[S]) extends AnyVal {
|
||||
|
||||
def createAbilityValue[Alg[_]: Monad](id: ValueRaw, abilityType: AbilityType)(implicit
|
||||
A: AbilitiesAlgebra[S, Alg],
|
||||
N: NamesAlgebra[S, Alg],
|
||||
T: TypesAlgebra[S, Alg],
|
||||
V: ValuesAlgebra[S, Alg],
|
||||
D: DefinitionsAlgebra[S, Alg]
|
||||
) = {}
|
||||
|
||||
// service AbServType("defaultId"):
|
||||
// ...
|
||||
|
||||
|
||||
// AbServType(func1 = ...'defaultId', func2 = ...'defaultId')
|
||||
// AbServType.func1()
|
||||
|
||||
// VarRaw(Serv.-default-id-, "defaultId")
|
||||
// Serv "new id"
|
||||
// VarRaw(Serv.-default-id-, "new id")
|
||||
|
||||
/*
|
||||
ability Ab:
|
||||
fff: string -> string
|
||||
eee: string -> string
|
||||
|
||||
service Serv:
|
||||
fff: string -> string
|
||||
|
||||
service Eserv:
|
||||
eee: string -> string
|
||||
|
||||
func nested{Ab}:
|
||||
...
|
||||
|
||||
someNewFunc{AbVal}():
|
||||
Serv "freferf"
|
||||
AbVal.fff()
|
||||
|
||||
AbVal.eee()
|
||||
|
||||
func main():
|
||||
|
||||
|
||||
Serv "aaa"
|
||||
Serv.fff()
|
||||
|
||||
Eserv "bbb"
|
||||
|
||||
Serv "zzz"
|
||||
Serv.fff()
|
||||
|
||||
nested{Serv}()
|
||||
AbVal = Ab(fff = Serv.fff, Eserv.eee)
|
||||
someNewFunc{AbVal}()
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// ...
|
||||
/*
|
||||
func main():
|
||||
AbServType "some id"
|
||||
AbServType(func1 = ...'some id', func2 = ...'some id')
|
||||
|
||||
CallServiceModel('some id')
|
||||
|
||||
AbServType "some id2"
|
||||
AbServType(func1 = ...'some id2', func2 = ...'some id2')
|
||||
|
||||
VarRaw(name, arrowType) -> Arrows FuncRaw(name, arrowType)
|
||||
FuncRaw(name, arrowType, body = ServiceCall)
|
||||
*/
|
||||
|
||||
private def toFuncRaw(name: String, abilityName: String, serviceId: ValueRaw, t: ArrowType): FuncRaw = {
|
||||
val args = t.domain.toLabelledList().map(st => VarRaw(st._1, st._2))
|
||||
val rett = t.codomain.toList.headOption
|
||||
val ret = rett.map(t => VarRaw("ret", t))
|
||||
val raw = CallArrowRaw(None, name, args, t, Some(serviceId))
|
||||
val body = ret match {
|
||||
case Some(vr) =>
|
||||
val callExpr = aqua.raw.ops.Call.Export(vr.name, vr.baseType)
|
||||
CallArrowRawTag(callExpr :: Nil, raw)
|
||||
|
||||
case None =>
|
||||
CallArrowRawTag(Nil, raw)
|
||||
|
||||
}
|
||||
|
||||
val arrow = ArrowRaw(t, ret.toList, body.leaf)
|
||||
val fullName = AbilityType.fullName(abilityName, name)
|
||||
FuncRaw(fullName, arrow)
|
||||
}
|
||||
|
||||
def program[Alg[_]: Monad](implicit
|
||||
A: AbilitiesAlgebra[S, Alg],
|
||||
N: NamesAlgebra[S, Alg],
|
||||
@ -23,34 +121,34 @@ class ServiceSem[S[_]](val expr: ServiceExpr[S]) extends AnyVal {
|
||||
V: ValuesAlgebra[S, Alg],
|
||||
D: DefinitionsAlgebra[S, Alg]
|
||||
): Prog[Alg, Raw] =
|
||||
Prog.after(
|
||||
_ =>
|
||||
D.purgeArrows(expr.name).flatMap {
|
||||
case Some(nel) =>
|
||||
val arrows = nel.map(kv => kv._1.value -> (kv._1, kv._2)).toNem
|
||||
for {
|
||||
defaultId <- expr.id
|
||||
.map(v => V.valueToRaw(v))
|
||||
.getOrElse(None.pure[Alg])
|
||||
defineResult <- A.defineService(
|
||||
expr.name,
|
||||
arrows,
|
||||
defaultId
|
||||
)
|
||||
_ <- (expr.id zip defaultId)
|
||||
.fold(().pure[Alg])(idV =>
|
||||
(V.ensureIsString(idV._1) >> A.setServiceId(expr.name, idV._1, idV._2)).map(_ =>
|
||||
()
|
||||
)
|
||||
)
|
||||
} yield
|
||||
if (defineResult) {
|
||||
ServiceRaw(expr.name.value, arrows.map(_._2), defaultId)
|
||||
} else Raw.empty("Service not created due to validation errors")
|
||||
Prog.after(_ =>
|
||||
D.purgeArrows(expr.name).flatMap {
|
||||
case Some(nel) =>
|
||||
val arrows = nel.map(kv => kv._1.value -> kv._2).toNem
|
||||
val abType = AbilityType(expr.name.value, arrows)
|
||||
for {
|
||||
_ <- T.defineNamedType(expr.name, abType)
|
||||
defaultId <- expr.id
|
||||
.map(v => V.valueToRaw(v))
|
||||
.getOrElse(None.pure[Alg])
|
||||
_ <- expr.id.traverse(id => V.ensureIsString(id))
|
||||
|
||||
case None =>
|
||||
Raw.error("Service has no arrows, fails").pure[Alg]
|
||||
serviceArrows = defaultId match {
|
||||
case Some(did) =>
|
||||
val funcs = arrows.mapBoth {
|
||||
case (funcName, t) => funcName -> toFuncRaw(funcName, expr.name.value, did, t)
|
||||
}
|
||||
funcs.toNel.toList.map(_._2)
|
||||
case None => Nil
|
||||
}
|
||||
} yield {
|
||||
println("serviceArrows: " + serviceArrows)
|
||||
val tr = TypeRaw(expr.name.value, abType)
|
||||
RawPart.Parts(Chain.fromSeq(serviceArrows) :+ tr)
|
||||
}
|
||||
case None =>
|
||||
Raw.error("Service has no arrows, fails").pure[Alg]
|
||||
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package aqua.semantics.expr.func
|
||||
|
||||
import aqua.parser.expr.func.ServiceIdExpr
|
||||
import aqua.raw.Raw
|
||||
import aqua.raw.ops.AbilityIdTag
|
||||
import aqua.parser.expr.func.AbilityIdExpr
|
||||
import aqua.raw.ops.EmptyTag
|
||||
import aqua.semantics.Prog
|
||||
import aqua.semantics.rules.ValuesAlgebra
|
||||
import aqua.semantics.rules.abilities.AbilitiesAlgebra
|
||||
@ -11,7 +11,7 @@ import cats.syntax.applicative.*
|
||||
import cats.syntax.flatMap.*
|
||||
import cats.syntax.functor.*
|
||||
|
||||
class AbilityIdSem[S[_]](val expr: AbilityIdExpr[S]) extends AnyVal {
|
||||
class ServiceIdSem[S[_]](val expr: ServiceIdExpr[S]) extends AnyVal {
|
||||
|
||||
def program[Alg[_]: Monad](implicit
|
||||
A: AbilitiesAlgebra[S, Alg],
|
||||
@ -21,10 +21,7 @@ class AbilityIdSem[S[_]](val expr: AbilityIdExpr[S]) extends AnyVal {
|
||||
expr.id
|
||||
) >>= {
|
||||
case Some(id) =>
|
||||
A.setServiceId(expr.ability, expr.id, id) as (AbilityIdTag(
|
||||
id,
|
||||
expr.ability.value
|
||||
).funcOpLeaf: Raw)
|
||||
A.setServiceId(expr.ability, expr.id, id) as (EmptyTag.funcOpLeaf: Raw)
|
||||
case _ => Raw.error("Cannot resolve ability ID").pure[Alg]
|
||||
}
|
||||
}
|
@ -4,11 +4,13 @@ import aqua.parser.lexer.*
|
||||
import aqua.parser.lexer.InfixToken.{BoolOp, CmpOp, EqOp, MathOp, Op as InfOp}
|
||||
import aqua.parser.lexer.PrefixToken.Op as PrefOp
|
||||
import aqua.raw.value.*
|
||||
import aqua.raw.ServiceRaw
|
||||
import aqua.raw.arrow.{ArrowRaw, FuncRaw}
|
||||
import aqua.raw.ops.{AssignmentTag, CallArrowRawTag}
|
||||
import aqua.semantics.rules.abilities.AbilitiesAlgebra
|
||||
import aqua.semantics.rules.names.NamesAlgebra
|
||||
import aqua.semantics.rules.types.TypesAlgebra
|
||||
import aqua.types.*
|
||||
|
||||
import cats.Monad
|
||||
import cats.data.Chain
|
||||
import cats.syntax.applicative.*
|
||||
@ -48,6 +50,8 @@ class ValuesAlgebra[S[_], Alg[_]: Monad](implicit
|
||||
def resolveType(v: ValueToken[S]): Alg[Option[Type]] =
|
||||
valueToRaw(v).map(_.map(_.`type`))
|
||||
|
||||
//
|
||||
|
||||
private def resolveSingleProperty(rootType: Type, op: PropertyOp[S]): Alg[Option[PropertyRaw]] =
|
||||
op match {
|
||||
case op: IntoField[S] =>
|
||||
@ -81,11 +85,23 @@ class ValuesAlgebra[S[_], Alg[_]: Monad](implicit
|
||||
LiteralRaw(l.value, t).some.pure[Alg]
|
||||
|
||||
case VarToken(name) =>
|
||||
N.read(name).flatMap {
|
||||
N.read(name, false).flatMap {
|
||||
case Some(t) =>
|
||||
VarRaw(name.value, t).some.pure[Alg]
|
||||
case None =>
|
||||
None.pure[Alg]
|
||||
A.getServiceByName(name).flatMap {
|
||||
case Some(ServiceRaw(sName, arrows, Some(did))) =>
|
||||
val t = AbilityType(sName, arrows)
|
||||
|
||||
N.define(name, t).map(_ => VarRaw(name.value, t).some)
|
||||
case _ =>
|
||||
// to report an error
|
||||
N.read(name).flatMap {
|
||||
case Some(t) => VarRaw(name.value, t).some.pure[Alg]
|
||||
case None => None.pure[Alg]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case prop @ PropertyToken(value, properties) =>
|
||||
@ -121,10 +137,10 @@ class ValuesAlgebra[S[_], Alg[_]: Monad](implicit
|
||||
StructType(typeName.value, rf.map(_.`type`)),
|
||||
Some(MakeStructRaw(rf, struct))
|
||||
)
|
||||
case scope @ AbilityType(_, _) =>
|
||||
case ability @ AbilityType(_, _) =>
|
||||
(
|
||||
AbilityType(typeName.value, rf.map(_.`type`)),
|
||||
Some(AbilityRaw(rf, scope))
|
||||
Some(AbilityRaw(rf, ability))
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -339,7 +355,7 @@ class ValuesAlgebra[S[_], Alg[_]: Monad](implicit
|
||||
callArrowFromAbility(ab.asName, at, callArrow.funcName).pure
|
||||
case _ =>
|
||||
(A.getArrow(ab, callArrow.funcName), A.getServiceId(ab)).mapN {
|
||||
case (Some(at), Right(sid)) =>
|
||||
case (Some(at), Right(sid, name)) =>
|
||||
CallArrowRaw
|
||||
.service(
|
||||
abilityName = ab.value,
|
||||
|
@ -1,6 +1,7 @@
|
||||
package aqua.semantics.rules.abilities
|
||||
|
||||
import aqua.parser.lexer.{Ability, NamedTypeToken, Name, Token, ValueToken}
|
||||
import aqua.parser.lexer.{Ability, Name, NamedTypeToken, Token, ValueToken}
|
||||
import aqua.raw.ServiceRaw
|
||||
import aqua.raw.value.ValueRaw
|
||||
import aqua.types.ArrowType
|
||||
import cats.InjectK
|
||||
@ -19,6 +20,9 @@ trait AbilitiesAlgebra[S[_], Alg[_]] {
|
||||
def setServiceId(name: NamedTypeToken[S], id: ValueToken[S], vm: ValueRaw): Alg[Boolean]
|
||||
|
||||
def getServiceId(name: NamedTypeToken[S]): Alg[Either[Boolean, ValueRaw]]
|
||||
def getServiceIdByName(name: String): Alg[Option[ValueRaw]]
|
||||
|
||||
def getServiceByName(name: Name[S]): Alg[Option[ServiceRaw]]
|
||||
|
||||
def beginScope(token: Token[S]): Alg[Unit]
|
||||
|
||||
|
@ -6,7 +6,7 @@ import aqua.raw.{RawContext, ServiceRaw}
|
||||
import aqua.semantics.Levenshtein
|
||||
import aqua.semantics.rules.errors.ReportErrors
|
||||
import aqua.semantics.rules.locations.LocationsAlgebra
|
||||
import aqua.semantics.rules.{StackInterpreter, abilities}
|
||||
import aqua.semantics.rules.{abilities, StackInterpreter}
|
||||
import aqua.types.ArrowType
|
||||
import cats.data.{NonEmptyMap, State}
|
||||
import cats.syntax.functor.*
|
||||
@ -41,24 +41,28 @@ class AbilitiesInterpreter[S[_], X](implicit
|
||||
|
||||
}
|
||||
case None =>
|
||||
arrows.toNel.map(_._2).collect {
|
||||
case (n, arr) if arr.codomain.length > 1 =>
|
||||
report(n, "Service functions cannot have multiple results")
|
||||
}.sequence.flatMap{ _ =>
|
||||
modify(s =>
|
||||
s.copy(
|
||||
services = s.services
|
||||
.updated(name.value, ServiceRaw(name.value, arrows.map(_._2), defaultId)),
|
||||
definitions = s.definitions.updated(name.value, name)
|
||||
)
|
||||
).flatMap { _ =>
|
||||
locations.addTokenWithFields(
|
||||
name.value,
|
||||
name,
|
||||
arrows.toNel.toList.map(t => t._1 -> t._2._1)
|
||||
)
|
||||
}.as(true)
|
||||
}
|
||||
arrows.toNel
|
||||
.map(_._2)
|
||||
.collect {
|
||||
case (n, arr) if arr.codomain.length > 1 =>
|
||||
report(n, "Service functions cannot have multiple results")
|
||||
}
|
||||
.sequence
|
||||
.flatMap { _ =>
|
||||
modify(s =>
|
||||
s.copy(
|
||||
services = s.services
|
||||
.updated(name.value, ServiceRaw(name.value, arrows.map(_._2), defaultId)),
|
||||
definitions = s.definitions.updated(name.value, name)
|
||||
)
|
||||
).flatMap { _ =>
|
||||
locations.addTokenWithFields(
|
||||
name.value,
|
||||
name,
|
||||
arrows.toNel.toList.map(t => t._1 -> t._2._1)
|
||||
)
|
||||
}.as(true)
|
||||
}
|
||||
}
|
||||
|
||||
// adds location from token to its definition
|
||||
@ -116,6 +120,22 @@ class AbilitiesInterpreter[S[_], X](implicit
|
||||
report(name, "Service with this name is not registered, can't set its ID").as(false)
|
||||
}
|
||||
|
||||
def getServiceIdByName(name: String): SX[Option[ValueRaw]] =
|
||||
getService(name).flatMap {
|
||||
case Some(_) =>
|
||||
getState.map(st =>
|
||||
st.stack
|
||||
.flatMap(_.serviceIds.get(name).map(_._2))
|
||||
.headOption orElse st.rootServiceIds
|
||||
.get(
|
||||
name
|
||||
)
|
||||
.map(_._2) orElse st.services.get(name).flatMap(_.defaultId)
|
||||
)
|
||||
case None =>
|
||||
State.pure(None)
|
||||
}
|
||||
|
||||
override def getServiceId(name: NamedTypeToken[S]): SX[Either[Boolean, ValueRaw]] =
|
||||
getService(name.value).flatMap {
|
||||
case Some(_) =>
|
||||
@ -147,6 +167,9 @@ class AbilitiesInterpreter[S[_], X](implicit
|
||||
}
|
||||
}
|
||||
|
||||
def getServiceByName(name: Name[S]): SX[Option[ServiceRaw]] =
|
||||
getService(name.value)
|
||||
|
||||
override def beginScope(token: Token[S]): SX[Unit] =
|
||||
stackInt.beginScope(AbilitiesState.Frame[S](token))
|
||||
|
||||
|
@ -10,7 +10,11 @@ trait NamesAlgebra[S[_], Alg[_]] {
|
||||
|
||||
def readArrow(name: Name[S]): Alg[Option[ArrowType]]
|
||||
|
||||
def define(name: Name[S], `type`: Type): Alg[Boolean]
|
||||
/**
|
||||
*
|
||||
* @param canOverride internal flag that is used for overriding services by serviceId
|
||||
*/
|
||||
def define(name: Name[S], `type`: Type, canOverride: Boolean = false): Alg[Boolean]
|
||||
|
||||
def derive(name: Name[S], `type`: Type, derivedFrom: Set[String]): Alg[Boolean]
|
||||
|
||||
|
@ -28,7 +28,7 @@ class NamesInterpreter[S[_], X](implicit
|
||||
|
||||
private def readName(name: String): SX[Option[Type]] =
|
||||
getState.map { st =>
|
||||
st.stack.collectFirst {
|
||||
st.stack.collectFirst {
|
||||
case frame if frame.names.contains(name) => frame.names(name)
|
||||
case frame if frame.arrows.contains(name) => frame.arrows(name)
|
||||
} orElse st.rootArrows.get(name) orElse st.rootValues.get(name)
|
||||
@ -84,17 +84,19 @@ class NamesInterpreter[S[_], X](implicit
|
||||
.headOption orElse st.rootArrows.get(name)
|
||||
}
|
||||
|
||||
override def define(name: Name[S], `type`: Type): SX[Boolean] =
|
||||
override def define(name: Name[S], `type`: Type, canOverride: Boolean = false): SX[Boolean] =
|
||||
readName(name.value).flatMap {
|
||||
case Some(_) =>
|
||||
case Some(_) if !canOverride =>
|
||||
getState.map(_.definitions.get(name.value).exists(_ == name)).flatMap {
|
||||
case true => State.pure(false)
|
||||
case false => report(name, "This name was already defined in the scope").as(false)
|
||||
}
|
||||
case None =>
|
||||
case _ =>
|
||||
mapStackHead(
|
||||
report(name, "Cannot define a variable in the root scope")
|
||||
.as(false)
|
||||
getState.map { st =>
|
||||
st.rootValues.updated(name.value, `type`)
|
||||
true
|
||||
}
|
||||
)(fr => fr.addName(name, `type`) -> true).flatTap(_ => locations.addToken(name.value, name))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user