Add fail expr and fail tag

This commit is contained in:
InversionSpaces 2023-06-22 11:05:45 +00:00
parent 46705754e6
commit 1c1d87b603
7 changed files with 82 additions and 4 deletions

View File

@ -265,7 +265,7 @@ case class CanonicalizeTag(operand: ValueRaw, exportTo: Call.Export) extends Raw
override def renameExports(map: Map[String, String]): RawTag =
copy(exportTo = exportTo.mapName(n => map.getOrElse(n, n)))
override def toString: String = s"(can $operand $exportTo)"
override def toString: String = s"(canon $operand $exportTo)"
}
case class JoinTag(operands: NonEmptyList[ValueRaw]) extends RawTag {
@ -275,3 +275,12 @@ case class JoinTag(operands: NonEmptyList[ValueRaw]) extends RawTag {
override def toString: String = s"(join ${operands.toList.mkString(" ")})"
}
case class FailTag(error: ValueRaw) extends RawTag {
override def mapValues(f: ValueRaw => ValueRaw): RawTag =
FailTag(f(error))
override def toString(): String =
s"(fail $error)"
}

View File

@ -113,6 +113,8 @@ object Transform extends Logging {
conf.respFuncName
)
println(func.body.show)
for {
// Pre transform and inline the function
model <- funcToModelTree(func, preTransformer)

View File

@ -32,6 +32,7 @@ object ArrowExpr extends Expr.AndIndented {
Expr.defer(ParExpr) ::
Expr.defer(CoExpr) ::
Expr.defer(JoinExpr) ::
Expr.defer(FailExpr) ::
DeclareStreamExpr ::
Expr.defer(ClosureExpr) ::
AssignmentExpr ::

View File

@ -0,0 +1,26 @@
package aqua.parser.expr.func
import aqua.parser.Expr
import aqua.parser.lexer.ValueToken
import aqua.parser.lift.Span.S
import aqua.parser.lexer.Token.*
import cats.Comonad
import cats.arrow.FunctionK
import cats.parse.Parser
final case class FailExpr[F[_]](
value: ValueToken[F]
) extends Expr[F](FailExpr, value) {
override def mapK[K[_]: Comonad](fk: FunctionK[F, K]): Expr[K] =
FailExpr[K](value.mapK(fk))
}
object FailExpr extends Expr.Leaf {
override def p: Parser[Expr[S]] =
(`fail` *> ` ` *> ValueToken.`value`).map(FailExpr.apply)
}

View File

@ -65,6 +65,7 @@ object Token {
val `par`: P[Unit] = P.string("par")
val `co`: P[Unit] = P.string("co")
val `join`: P[Unit] = P.string("join")
val `fail`: P[Unit] = P.string("fail")
val `copy`: P[Unit] = P.string("copy")
val `:` : P[Unit] = P.char(':')
val ` : ` : P[Unit] = P.char(':').surroundedBy(` `.?)
@ -117,9 +118,11 @@ object Token {
val `/s*` : P0[Unit] = ` \n+`.backtrack | ` *`.void
val namedArg: P[(String, ValueToken[S])] =
P.defer(`name`.between(` *`, `/s*`) ~
`=`.between(` *`, `/s*`).void ~
ValueToken.`value`.between(` *`, `/s*`)).map { case ((name, _), vt) =>
P.defer(
`name`.between(` *`, `/s*`) ~
`=`.between(` *`, `/s*`).void ~
ValueToken.`value`.between(` *`, `/s*`)
).map { case ((name, _), vt) =>
(name, vt)
}

View File

@ -48,6 +48,7 @@ object ExprSem {
case expr: ElseOtherwiseExpr[S] => new ElseOtherwiseSem(expr).program[G]
case expr: ParExpr[S] => new ParSem(expr).program[G]
case expr: CoExpr[S] => new CoSem(expr).program[G]
case expr: FailExpr[S] => new FailSem(expr).program[G]
case expr: JoinExpr[S] => new JoinSem(expr).program[G]
case expr: ReturnExpr[S] => new ReturnSem(expr).program[G]
case expr: ServiceExpr[S] => new ServiceSem(expr).program[G]

View File

@ -0,0 +1,36 @@
package aqua.semantics.expr.func
import aqua.parser.expr.func.FailExpr
import aqua.semantics.rules.ValuesAlgebra
import aqua.semantics.rules.types.TypesAlgebra
import aqua.semantics.Prog
import aqua.raw.Raw
import aqua.types.ScalarType
import aqua.raw.ops.FailTag
import cats.Monad
import cats.syntax.flatMap.*
import cats.syntax.functor.*
import cats.syntax.traverse.*
class FailSem[S[_]](val expr: FailExpr[S]) extends AnyVal {
def program[Alg[_]: Monad](implicit
V: ValuesAlgebra[S, Alg],
T: TypesAlgebra[S, Alg]
): Prog[Alg, Raw] = for {
maybeValue <- V.valueToRaw(expr.value)
result <- maybeValue.traverse(vr =>
T.ensureTypeMatches(
token = expr.value,
expected = ScalarType.string,
givenType = vr.`type`
).map(isStr =>
if (isStr) FailTag(vr).funcOpLeaf
else Raw.error("Argument of `fail` is not a string")
)
)
} yield result.getOrElse(
Raw.error("Resolution for `fail` argument failed")
)
}