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