170 pass constants as arguments (#171)

This commit is contained in:
Dima 2021-06-15 20:44:55 +03:00 committed by GitHub
parent 221cc5ca33
commit 29af3e7875
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 39 deletions

View File

@ -53,6 +53,6 @@ jobs:
cd aqua-playground
npm i
cd ..
sbt "cli/run -i aqua-playground/aqua/examples -o aqua-playground/src/compiled/examples -m aqua-playground/node_modules"
sbt "cli/run -i aqua-playground/aqua/examples -o aqua-playground/src/compiled/examples -m aqua-playground/node_modules -c \"uniqueConst = 1\" -c \"anotherConst = \\\"ab\\\"\""
cd aqua-playground
npm run examples

View File

@ -1,12 +1,16 @@
package aqua
import cats.Functor
import aqua.model.LiteralModel
import aqua.model.transform.Constant
import aqua.parser.expr.ConstantExpr
import aqua.parser.lift.LiftParser
import cats.data.Validated.{Invalid, Valid}
import cats.data.{Validated, ValidatedNel}
import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.effect.ExitCode
import cats.effect.std.Console
import cats.syntax.functor._
import cats.syntax.traverse._
import cats.{Comonad, Functor}
import com.monovore.decline.Opts.help
import com.monovore.decline.enumeratum._
import com.monovore.decline.{Opts, Visibility}
@ -91,6 +95,28 @@ object AppOps {
}
.withDefault(LazyList.empty)
def constantOpts[F[_]: LiftParser: Comonad]: Opts[List[Constant]] =
Opts
.options[String]("const", "Constant that will be used in an aqua code", "c")
.mapValidated { strs =>
val parsed = strs.map(s => ConstantExpr.onlyLiteral.parseAll(s))
println(parsed)
val errors = parsed.collect { case Left(er) =>
er
}
NonEmptyList
.fromList(errors)
.fold(
Validated.validNel[String, List[Constant]](parsed.collect { case Right(v) =>
Constant(v._1.value, LiteralModel(v._2.value, v._2.ts))
})
) { errors =>
Validated.invalid(errors.map(_.toString))
}
}
.withDefault(List.empty)
val compileToAir: Opts[Boolean] =
Opts
.flag("air", "Generate .air file instead of typescript", "a")

View File

@ -1,6 +1,8 @@
package aqua
import aqua.model.transform.BodyConfig
import aqua.parser.lift.LiftParser.Implicits.idLiftParser
import cats.Id
import cats.data.Validated
import cats.effect._
import cats.effect.std.{Console => ConsoleEff}
@ -42,37 +44,42 @@ object AquaCli extends IOApp with LogSupport {
noXorWrapper,
wrapWithOption(helpOpt),
wrapWithOption(versionOpt),
logLevelOpt
).mapN { case (input, imports, output, toAir, toJs, noRelay, noXor, h, v, logLevel) =>
WLogger.setDefaultLogLevel(LogLevel.toLogLevel(logLevel))
WLogger.setDefaultFormatter(CustomLogFormatter)
logLevelOpt,
constantOpts[Id]
).mapN {
case (input, imports, output, toAir, toJs, noRelay, noXor, h, v, logLevel, constants) =>
WLogger.setDefaultLogLevel(LogLevel.toLogLevel(logLevel))
WLogger.setDefaultFormatter(CustomLogFormatter)
// if there is `--help` or `--version` flag - show help and version
// otherwise continue program execution
h.map(_ => helpAndExit) orElse v.map(_ => versionAndExit) getOrElse {
val target = if (toAir) AquaCompiler.AirTarget else if (toJs) AquaCompiler.JavaScriptTarget else AquaCompiler.TypescriptTarget
val bc = {
val bc = BodyConfig(wrapWithXor = !noXor)
bc.copy(relayVarName = bc.relayVarName.filterNot(_ => noRelay))
}
info(s"Aqua Compiler ${versionStr}")
AquaCompiler
.compileFilesTo[F](
input,
imports,
output,
target,
bc
)
.map {
case Validated.Invalid(errs) =>
errs.map(println)
ExitCode.Error
case Validated.Valid(results) =>
results.map(println)
ExitCode.Success
// if there is `--help` or `--version` flag - show help and version
// otherwise continue program execution
h.map(_ => helpAndExit) orElse v.map(_ => versionAndExit) getOrElse {
val target =
if (toAir) AquaCompiler.AirTarget
else if (toJs) AquaCompiler.JavaScriptTarget
else AquaCompiler.TypescriptTarget
val bc = {
val bc = BodyConfig(wrapWithXor = !noXor, constants = constants)
bc.copy(relayVarName = bc.relayVarName.filterNot(_ => noRelay))
}
}
info(s"Aqua Compiler ${versionStr}")
AquaCompiler
.compileFilesTo[F](
input,
imports,
output,
target,
bc
)
.map {
case Validated.Invalid(errs) =>
errs.map(println)
ExitCode.Error
case Validated.Valid(results) =>
results.map(println)
ExitCode.Success
}
}
}
}

View File

@ -3,6 +3,8 @@ package aqua.model.transform
import aqua.model.{AquaContext, LiteralModel, ValueModel, VarModel}
import cats.kernel.Monoid
case class Constant(name: String, value: ValueModel)
case class BodyConfig(
getDataService: String = "getDataSrv",
callbackService: String = "callbackSrv",
@ -10,7 +12,8 @@ case class BodyConfig(
errorFuncName: String = "error",
respFuncName: String = "response",
relayVarName: Option[String] = Some("-relay-"),
wrapWithXor: Boolean = true
wrapWithXor: Boolean = true,
constants: List[Constant] = Nil
) {
val errorId: ValueModel = LiteralModel.quote(errorFuncName)
@ -18,12 +21,14 @@ case class BodyConfig(
val callbackSrvId: ValueModel = LiteralModel.quote(callbackService)
val dataSrvId: ValueModel = LiteralModel.quote(getDataService)
// TODO: add constants to BodyConfig, and register there
implicit val aquaContextMonoid: Monoid[AquaContext] =
implicit val aquaContextMonoid: Monoid[AquaContext] = {
val constantsMap = constants.map(c => c.name -> c.value).toMap
AquaContext
.implicits(
AquaContext.blank.copy(values = Map(VarModel.lastError.name -> VarModel.lastError))
AquaContext.blank
.copy(values = Map(VarModel.lastError.name -> VarModel.lastError) ++ constantsMap)
)
.aquaContextMonoid
}
}

View File

@ -2,7 +2,7 @@ package aqua.parser.expr
import aqua.parser.Expr
import aqua.parser.lexer.Token._
import aqua.parser.lexer.{Name, Value}
import aqua.parser.lexer.{Literal, Name, Value}
import aqua.parser.lift.LiftParser
import cats.Comonad
import cats.parse.{Parser => P}
@ -15,11 +15,16 @@ case class ConstantExpr[F[_]](
object ConstantExpr extends Expr.Leaf {
override def p[F[_]: LiftParser: Comonad]: P[ConstantExpr[F]] = {
override def p[F[_]: LiftParser: Comonad]: P[ConstantExpr[F]] =
((((`const` *> ` ` *> Name
.p[F] <* ` `) ~ `?`.?).with1 <* `=` <* ` `) ~ Value.`value`).map {
case ((name, mark), value) =>
ConstantExpr(name, value, mark.nonEmpty)
}
}
def onlyLiteral[F[_]: LiftParser: Comonad]: P[(Name[F], Literal[F])] =
((((Name
.p[F] <* ` `) ~ `?`.?).with1 <* `=` <* ` `) ~ Value.literal).map { case ((name, _), value) =>
(name, value)
}
}