NameState refactoring

This commit is contained in:
DieMyst 2023-08-24 11:30:41 +02:00
parent bf0b51fa5b
commit df2e794a99
8 changed files with 35 additions and 46 deletions

View File

@ -81,6 +81,8 @@ class AquaCompilerSpec extends AnyFlatSpec with Matchers {
Map.empty Map.empty
) )
println(res)
res.isValid should be(true) res.isValid should be(true)
val Validated.Valid(ctxs) = res val Validated.Valid(ctxs) = res

View File

@ -41,7 +41,7 @@ class LspSemantics[S[_]] extends Semantics[S, LspContext[S]] {
val initState = rawState.copy( val initState = rawState.copy(
names = rawState.names.copy( names = rawState.names.copy(
rootArrows = rawState.names.rootArrows ++ init.rootArrows, rootArrows = rawState.names.rootArrows ++ init.rootArrows,
constants = rawState.names.constants ++ init.constants rootValues = rawState.names.rootValues ++ init.constants
), ),
abilities = rawState.abilities.copy( abilities = rawState.abilities.copy(
definitions = rawState.abilities.definitions ++ init.abDefinitions definitions = rawState.abilities.definitions ++ init.abDefinitions
@ -74,7 +74,7 @@ class LspSemantics[S[_]] extends Semantics[S, LspContext[S]] {
LspContext( LspContext(
raw = ctx, raw = ctx,
rootArrows = state.names.rootArrows, rootArrows = state.names.rootArrows,
constants = state.names.constants, constants = state.names.rootValues,
abDefinitions = state.abilities.definitions, abDefinitions = state.abilities.definitions,
locations = state.locations.allLocations, locations = state.locations.allLocations,
importTokens = importTokens, importTokens = importTokens,

View File

@ -1,18 +1,14 @@
package aqua.model.inline.raw package aqua.model.inline.raw
import aqua.model.inline.Inline.parDesugarPrefixOpt
import aqua.model.{CallServiceModel, FuncArrow, MetaModel, SeqModel, ValueModel, VarModel}
import aqua.model.inline.{ArrowInliner, Inline, TagInliner}
import aqua.model.inline.RawValueInliner.{callToModel, valueToModel} import aqua.model.inline.RawValueInliner.{callToModel, valueToModel}
import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.inline.state.{Arrows, Exports, Mangler}
import aqua.model.inline.{ArrowInliner, Inline, TagInliner}
import aqua.model.*
import aqua.raw.ops.Call import aqua.raw.ops.Call
import aqua.types.ArrowType
import aqua.raw.value.CallArrowRaw import aqua.raw.value.CallArrowRaw
import cats.data.{Chain, State} import cats.data.{Chain, State}
import scribe.Logging import scribe.Logging
import scala.collection.immutable.ListMap
object CallArrowRawInliner extends RawInliner[CallArrowRaw] with Logging { object CallArrowRawInliner extends RawInliner[CallArrowRaw] with Logging {
private[inline] def unfoldArrow[S: Mangler: Exports: Arrows]( private[inline] def unfoldArrow[S: Mangler: Exports: Arrows](

View File

@ -1,6 +1,5 @@
package aqua.model package aqua.model
import aqua.raw.Raw
import aqua.raw.arrow.FuncRaw import aqua.raw.arrow.FuncRaw
import aqua.raw.ops.RawTag import aqua.raw.ops.RawTag
import aqua.raw.value.ValueRaw import aqua.raw.value.ValueRaw

View File

@ -19,10 +19,10 @@ class ConstantSem[S[_]](val expr: ConstantExpr[S]) extends AnyVal {
T: TypesAlgebra[S, Alg] T: TypesAlgebra[S, Alg]
): Prog[Alg, Raw] = { ): Prog[Alg, Raw] = {
for { for {
defined <- N.constantDefined(expr.name) defined <- N.read(expr.name, false)
v <- V.valueToRaw(expr.value) v <- V.valueToRaw(expr.value)
model <- (defined, v.map(v => v -> v.`type`), expr.skipIfAlreadyDefined) match { model <- (defined, v.map(v => v -> v.`type`), expr.skipIfAlreadyDefined) match {
case (Some(definedType), Some((vm, actualType)), true) => case (Some(definedType), Some((_, actualType)), true) =>
T.ensureTypeMatches(expr.value, definedType, actualType).map { T.ensureTypeMatches(expr.value, definedType, actualType).map {
case true => case true =>
Raw.empty(s"Constant with name ${expr.name} was already defined, skipping") Raw.empty(s"Constant with name ${expr.name} was already defined, skipping")
@ -34,7 +34,7 @@ class ConstantSem[S[_]](val expr: ConstantExpr[S]) extends AnyVal {
case (_, None, _) => case (_, None, _) =>
Raw.error(s"There is no such variable ${expr.value}").pure[Alg] Raw.error(s"There is no such variable ${expr.value}").pure[Alg]
case (_, Some(t), _) => case (_, Some(t), _) =>
N.defineConstant(expr.name, t._2) as (ConstantRaw( N.defineRootValue(expr.name, t._2) as (ConstantRaw(
expr.name.value, expr.name.value,
t._1, t._1,
expr.skipIfAlreadyDefined expr.skipIfAlreadyDefined

View File

@ -8,9 +8,6 @@ trait NamesAlgebra[S[_], Alg[_]] {
def read(name: Name[S], mustBeDefined: Boolean = true): Alg[Option[Type]] def read(name: Name[S], mustBeDefined: Boolean = true): Alg[Option[Type]]
// TODO can be implemented via read?
def constantDefined(name: Name[S]): Alg[Option[Type]]
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] def define(name: Name[S], `type`: Type): Alg[Boolean]
@ -19,7 +16,7 @@ trait NamesAlgebra[S[_], Alg[_]] {
def getDerivedFrom(fromNames: List[Set[String]]): Alg[List[Set[String]]] def getDerivedFrom(fromNames: List[Set[String]]): Alg[List[Set[String]]]
def defineConstant(name: Name[S], `type`: Type): Alg[Boolean] def defineRootValue(name: Name[S], `type`: Type): Alg[Boolean]
def defineArrow(name: Name[S], gen: ArrowType, isRoot: Boolean): Alg[Boolean] def defineArrow(name: Name[S], gen: ArrowType, isRoot: Boolean): Alg[Boolean]

View File

@ -28,36 +28,30 @@ 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.constants.get(name) orElse 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.rootArrows.get(name) orElse st.rootValues.get(name)
} }
override def read(name: Name[S], mustBeDefined: Boolean = true): SX[Option[Type]] = override def read(name: Name[S], mustBeDefined: Boolean = true): SX[Option[Type]] =
OptionT(constantDefined(name)) readName(name.value).flatTap {
.orElseF(readName(name.value)) case None if mustBeDefined =>
.value getState.flatMap(st =>
.flatTap { report(
case None if mustBeDefined => name,
getState.flatMap(st => Levenshtein
report( .genMessage(
name, s"Name '${name.value}' isn't found in scope",
Levenshtein name.value,
.genMessage( st.allNames.toList
s"Name '${name.value}' isn't found in scope", )
name.value,
st.allNames.toList
)
)
) )
case Some(_) => )
locations.pointLocation(name.value, name) case Some(_) =>
case _ => State.pure(()) locations.pointLocation(name.value, name)
} case _ => State.pure(())
}
override def constantDefined(name: Name[S]): SX[Option[Type]] =
getState.map(_.constants.get(name.value))
def readArrow(name: Name[S]): SX[Option[ArrowType]] = def readArrow(name: Name[S]): SX[Option[ArrowType]] =
readArrowHelper(name.value).flatMap { readArrowHelper(name.value).flatMap {
@ -116,14 +110,14 @@ class NamesInterpreter[S[_], X](implicit
fr -> fromNames.map(ns => fr.derivedFrom.view.filterKeys(ns).values.foldLeft(ns)(_ ++ _)) fr -> fromNames.map(ns => fr.derivedFrom.view.filterKeys(ns).values.foldLeft(ns)(_ ++ _))
) )
override def defineConstant(name: Name[S], `type`: Type): SX[Boolean] = override def defineRootValue(name: Name[S], `type`: Type): SX[Boolean] =
readName(name.value).flatMap { readName(name.value).flatMap {
case Some(_) => case Some(_) =>
report(name, "This name was already defined in the scope").as(false) report(name, "This name was already defined in the scope").as(false)
case None => case None =>
modify(st => modify(st =>
st.copy( st.copy(
constants = st.constants.updated(name.value, `type`) rootValues = st.rootValues.updated(name.value, `type`)
) )
).as(true) ).as(true)
}.flatTap(_ => locations.addToken(name.value, name)) }.flatTap(_ => locations.addToken(name.value, name))

View File

@ -9,7 +9,8 @@ import cats.syntax.functor.*
case class NamesState[S[_]]( case class NamesState[S[_]](
stack: List[NamesState.Frame[S]] = Nil, stack: List[NamesState.Frame[S]] = Nil,
rootArrows: Map[String, ArrowType] = Map.empty[String, ArrowType], rootArrows: Map[String, ArrowType] = Map.empty[String, ArrowType],
constants: Map[String, Type] = Map.empty[String, Type], // can be constants or services as abilities
rootValues: Map[String, Type] = Map.empty[String, Type],
definitions: Map[String, Name[S]] = Map.empty[String, Name[S]] definitions: Map[String, Name[S]] = Map.empty[String, Name[S]]
) { ) {
@ -18,7 +19,7 @@ case class NamesState[S[_]](
.from(stack) .from(stack)
.flatMap(s => s.names.keys ++ s.arrows.keys) .flatMap(s => s.names.keys ++ s.arrows.keys)
.appendedAll(rootArrows.keys) .appendedAll(rootArrows.keys)
.appendedAll(constants.keys) .appendedAll(rootValues.keys)
def allArrows: LazyList[String] = def allArrows: LazyList[String] =
LazyList.from(stack).flatMap(_.arrows.keys).appendedAll(rootArrows.keys) LazyList.from(stack).flatMap(_.arrows.keys).appendedAll(rootArrows.keys)
@ -53,7 +54,7 @@ object NamesState {
stack = Nil, stack = Nil,
rootArrows = x.rootArrows ++ y.rootArrows, rootArrows = x.rootArrows ++ y.rootArrows,
definitions = x.definitions ++ y.definitions, definitions = x.definitions ++ y.definitions,
constants = x.constants ++ y.constants rootValues = x.rootValues ++ y.rootValues
) )
} }
@ -62,6 +63,6 @@ object NamesState {
rootArrows = context.allFuncs.map { case (s, fc) => rootArrows = context.allFuncs.map { case (s, fc) =>
(s, fc.arrow.`type`) (s, fc.arrow.`type`)
}, },
constants = context.allValues.map { case (s, vm) => (s, vm.`type`) } rootValues = context.allValues.map { case (s, vm) => (s, vm.`type`) }
) )
} }