diff --git a/api/api/.jvm/src/main/scala/aqua/api/Test.scala b/api/api/.jvm/src/main/scala/aqua/api/Test.scala index 1734ddb1..1dc13f8d 100644 --- a/api/api/.jvm/src/main/scala/aqua/api/Test.scala +++ b/api/api/.jvm/src/main/scala/aqua/api/Test.scala @@ -1,18 +1,41 @@ package aqua.api -import cats.effect.{IO, IOApp} + +import aqua.api.TargetType.{JavaScriptType, TypeScriptType} import aqua.backend.js.JavaScriptBackend import aqua.backend.ts.TypeScriptBackend -import aqua.api.TargetType.JavaScriptType +import aqua.compiler.AquaCompiled +import aqua.files.FileModuleId +import cats.data.Chain +import cats.effect.{IO, IOApp} +import fs2.io.file.{Files, Path} +import cats.data.Validated.{Valid, Invalid} +import fs2.{Stream, text} object Test extends IOApp.Simple { + override def run: IO[Unit] = { - val input = - """func getNumber(number: u32) -> u32: - | <- number - |""".stripMargin - APICompilation.compileString(input, Nil, AquaAPIConfig(targetType = JavaScriptType), JavaScriptBackend()).map { - res => - println(res) - } + APICompilation + .compilePath( + "./aqua-src/antithesis.aqua", + "./aqua" :: Nil, + AquaAPIConfig(targetType = TypeScriptType), + TypeScriptBackend(false, "IFluenceClient$$") + ) + .flatMap { + case Valid(res: Chain[AquaCompiled[FileModuleId]]) => + val content = res.get(0).get.compiled.head.content + + val targetPath = Path("./target/antithesis.ts") + Stream.emit(content) + .through(text.utf8.encode) + .through(Files[IO].writeAll(targetPath)) + .attempt + + .compile + .last.map(_ => println(s"File: ${targetPath.absolute.normalize}")) + case Invalid(e) => + IO.pure(println(e)) + + } } } diff --git a/build.sbt b/build.sbt index 64ecf83b..191d3e8b 100644 --- a/build.sbt +++ b/build.sbt @@ -38,56 +38,6 @@ val commons = Seq( commons -lazy val cli = crossProject(JSPlatform, JVMPlatform) - .withoutSuffixFor(JVMPlatform) - .crossType(CrossType.Pure) - .in(file("cli/cli")) - .enablePlugins(GraalVMNativeImagePlugin) - .settings(commons) - .settings( - Compile / mainClass := Some("aqua.AquaCli"), - graalVMNativeImageOptions ++= Seq( - "--no-fallback", - "--diagnostics-mode", - "--initialize-at-build-time", - "--initialize-at-run-time=scala.util.Random$", - "-H:-DeleteLocalSymbols", - "-H:+PreserveFramePointer", - "-H:+ReportExceptionStackTraces", - "-H:+DashboardHeap", - "-H:+DashboardCode", - "-H:+DashboardPointsTo", - "-H:+DashboardAll" - ) ++ sys.env - .get("COMPILE_STATIC") - .filter(_.trim.toLowerCase() == "true") - .map(_ => Seq("--static")) - .getOrElse(Seq.empty), - libraryDependencies ++= Seq( - "com.monovore" %%% "decline" % declineV, - "com.monovore" %%% "decline-effect" % declineV - ) - ) - .dependsOn(compiler, `backend-air`, `backend-ts`, io, definitions, logging, constants, `aqua-run`) - -lazy val cliJS = cli.js - .settings( - Compile / fastOptJS / artifactPath := baseDirectory.value / "../../cli-npm" / "aqua.js", - Compile / fullOptJS / artifactPath := baseDirectory.value / "../../cli-npm" / "aqua.js", - scalaJSLinkerConfig ~= (_.withModuleKind(ModuleKind.ESModule)), - scalaJSUseMainModuleInitializer := true - ) - .dependsOn(`js-exports`, `js-imports`) - -lazy val cliJVM = cli.jvm - .settings( - Compile / run / mainClass := Some("aqua.AquaCli"), - assembly / mainClass := Some("aqua.AquaCli"), - assembly / assemblyJarName := "aqua-" + version.value + ".jar", - libraryDependencies ++= Seq( - ) - ) - lazy val `aqua-run` = crossProject(JSPlatform, JVMPlatform) .withoutSuffixFor(JVMPlatform) .crossType(CrossType.Pure) @@ -149,7 +99,7 @@ lazy val `aqua-api` = crossProject(JSPlatform, JVMPlatform) .crossType(CrossType.Pure) .in(file("api/api")) .settings(commons) - .dependsOn(`aqua-run`, `backend-api`) + .dependsOn(`aqua-run`, `backend-api`, io) lazy val `aqua-apiJS` = `aqua-api`.js .settings( diff --git a/model/inline/src/main/scala/aqua/model/inline/Inline.scala b/model/inline/src/main/scala/aqua/model/inline/Inline.scala index 1c56eb26..dc33856d 100644 --- a/model/inline/src/main/scala/aqua/model/inline/Inline.scala +++ b/model/inline/src/main/scala/aqua/model/inline/Inline.scala @@ -80,6 +80,13 @@ private[inline] object Inline { case _ => ParModel.wrap(ops).some } + def seqDesugarPrefix(ops: List[OpModel.Tree]): Option[OpModel.Tree] = + ops match { + case Nil => none + case x :: Nil => x.some + case _ => SeqModel.wrap(ops).some + } + def parDesugarPrefixOpt(ops: Option[OpModel.Tree]*): Option[OpModel.Tree] = parDesugarPrefix(ops.toList.flatten) } diff --git a/model/inline/src/main/scala/aqua/model/inline/TagInliner.scala b/model/inline/src/main/scala/aqua/model/inline/TagInliner.scala index 38fc8f74..70cbf948 100644 --- a/model/inline/src/main/scala/aqua/model/inline/TagInliner.scala +++ b/model/inline/src/main/scala/aqua/model/inline/TagInliner.scala @@ -1,26 +1,24 @@ package aqua.model.inline -import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.model.* +import aqua.model.inline.Inline.{parDesugarPrefixOpt, seqDesugarPrefix} import aqua.model.inline.RawValueInliner.collectionToModel import aqua.model.inline.raw.CallArrowRawInliner -import aqua.raw.value.ApplyBinaryOpRaw.Op as BinOp +import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.raw.ops.* import aqua.raw.value.* -import aqua.types.{BoxType, CanonStreamType, DataType, StreamType} -import aqua.model.inline.Inline.parDesugarPrefixOpt - -import cats.syntax.traverse.* +import aqua.raw.value.ApplyBinaryOpRaw.Op as BinOp +import aqua.types.{BoxType, CanonStreamType, StreamType} +import cats.data.{Chain, State, StateT} +import cats.instances.list.* import cats.syntax.applicative.* -import cats.syntax.flatMap.* import cats.syntax.apply.* +import cats.syntax.bifunctor.* +import cats.syntax.flatMap.* import cats.syntax.functor.* import cats.syntax.option.* -import cats.instances.list.* -import cats.data.{Chain, State, StateT} -import cats.syntax.show.* -import cats.syntax.bifunctor.* -import scribe.{log, Logging} +import cats.syntax.traverse.* +import scribe.Logging /** * [[TagInliner]] prepares a [[RawTag]] for futher processing by converting [[ValueRaw]]s into [[ValueModel]]s. @@ -33,8 +31,7 @@ import scribe.{log, Logging} */ object TagInliner extends Logging { - import RawValueInliner.{callToModel, valueListToModel, valueToModel} - + import RawValueInliner.{valueListToModel, valueToModel} import aqua.model.inline.Inline.parDesugarPrefix /** @@ -204,7 +201,7 @@ object TagInliner extends Logging { ) } yield TagInlined.Mapping( toModel = toModel, - prefix = parDesugarPrefix(viaF.prependedAll(pif)) + prefix = seqDesugarPrefix(viaF.prependedAll(pif)) ) case IfTag(valueRaw) => diff --git a/model/inline/src/main/scala/aqua/model/inline/raw/ApplyGateRawInliner.scala b/model/inline/src/main/scala/aqua/model/inline/raw/ApplyGateRawInliner.scala index 0b3f4b49..29fd7c03 100644 --- a/model/inline/src/main/scala/aqua/model/inline/raw/ApplyGateRawInliner.scala +++ b/model/inline/src/main/scala/aqua/model/inline/raw/ApplyGateRawInliner.scala @@ -1,18 +1,19 @@ package aqua.model.inline.raw -import aqua.model.* +import aqua.model.{EmptyModel, *} import aqua.model.inline.Inline import aqua.model.inline.state.{Arrows, Exports, Mangler} import aqua.raw.value.{ApplyGateRaw, LiteralRaw, VarRaw} import aqua.model.inline.RawValueInliner.unfold import aqua.types.{ArrayType, CanonStreamType, ScalarType, StreamType} - import cats.data.State import cats.data.Chain import cats.syntax.monoid.* import cats.syntax.option.* import scribe.Logging +import scala.util.Try + object ApplyGateRawInliner extends RawInliner[ApplyGateRaw] with Logging { /** @@ -61,10 +62,10 @@ object ApplyGateRawInliner extends RawInliner[ApplyGateRaw] with Logging { val resultCanon = VarModel(canonName, CanonStreamType(streamType.element)) - val incrVar = VarModel(idxIncrName, ScalarType.u32) + val (incrVar, incrOp) = increment(idxModel, idxIncrName) RestrictionModel(varSTest.name, streamType).wrap( - increment(idxModel, incrVar), + incrOp, ForModel(iter.name, VarModel(streamName, streamType), ForModel.Mode.Never.some).wrap( PushToStreamModel( iter, @@ -132,13 +133,30 @@ object ApplyGateRawInliner extends RawInliner[ApplyGateRaw] with Logging { } - private def increment(v: ValueModel, result: VarModel) = - CallServiceModel( - LiteralModel("\"math\"", ScalarType.string), - "add", - CallModel( - v :: LiteralModel.fromRaw(LiteralRaw.number(1)) :: Nil, - CallModel.Export(result.name, result.`type`) :: Nil - ) - ).leaf + private def increment(v: ValueModel, name: String): (ValueModel, OpModel.Tree) = { + val incrVar = VarModel(name, ScalarType.u32) + val incrValue = v match { + case LiteralModel(value, _) => + Try(value.toInt + 1).toOption.map(LiteralModel.number).getOrElse(incrVar) + case _ => + incrVar + } + incrValue match { + case _: LiteralModel => + (incrValue, EmptyModel.leaf) + case _ => + ( + incrVar, + CallServiceModel( + LiteralModel("\"math\"", ScalarType.string), + "add", + CallModel( + incrVar :: LiteralModel.fromRaw(LiteralRaw.number(1)) :: Nil, + CallModel.Export(incrVar.name, incrVar.`type`) :: Nil + ) + ).leaf + ) + } + + } } diff --git a/model/res/src/test/scala/aqua/res/ResBuilder.scala b/model/res/src/test/scala/aqua/res/ResBuilder.scala index 7c38cb6a..b9fe4293 100644 --- a/model/res/src/test/scala/aqua/res/ResBuilder.scala +++ b/model/res/src/test/scala/aqua/res/ResBuilder.scala @@ -9,7 +9,7 @@ import cats.syntax.option.* object ResBuilder { - def join(stream: VarModel, onIdx: ValueModel, peer: ValueModel) = { + def join(stream: VarModel, onIdxV: ValueModel, peer: ValueModel) = { val testVM = VarModel(stream.name + "_test", stream.`type`) val testStreamType = stream.`type`.asInstanceOf[StreamType] // Unsafe val iter = VarModel(stream.name + "_fold_var", ScalarType.string) @@ -18,30 +18,37 @@ object ResBuilder { val arrayRes = VarModel(stream.name + "_gate", ArrayType(ScalarType.string)) val idx = VarModel(stream.name + "_incr", ScalarType.u32) + val (onIdx, idxTree) = onIdxV match { + case LiteralModel(v, t) => + (Some(LiteralModel.number(v.toInt + 1)), Nil) + case _ => + (None, CallServiceRes( + LiteralModel("\"math\"", ScalarType.string), + "add", + CallRes( + onIdxV :: LiteralModel.fromRaw(LiteralRaw.number(1)) :: Nil, + Some(CallModel.Export(idx.name, idx.`type`)) + ), + peer + ).leaf :: Nil) + } + RestrictionRes(testVM.name, testStreamType).wrap( - CallServiceRes( - LiteralModel("\"math\"", ScalarType.string), - "add", - CallRes( - onIdx :: LiteralModel.fromRaw(LiteralRaw.number(1)) :: Nil, - Some(CallModel.Export(idx.name, idx.`type`)) - ), - peer - ).leaf, + idxTree ::: FoldRes(iter.name, stream, ForModel.Mode.Never.some).wrap( ApRes(iter, CallModel.Export(testVM.name, testVM.`type`)).leaf, CanonRes(testVM, peer, CallModel.Export(canon.name, canon.`type`)).leaf, XorRes.wrap( MatchMismatchRes( canon.copy(properties = Chain.one(FunctorModel("length", ScalarType.u32))), - idx, + onIdx.getOrElse(idx), true ).leaf, NextRes(iter.name).leaf ) - ), - CanonRes(testVM, peer, CallModel.Export(canonRes.name, canonRes.`type`)).leaf, - ApRes(canonRes, CallModel.Export(arrayRes.name, arrayRes.`type`)).leaf + ) :: + CanonRes(testVM, peer, CallModel.Export(canonRes.name, canonRes.`type`)).leaf :: + ApRes(canonRes, CallModel.Export(arrayRes.name, arrayRes.`type`)).leaf :: Nil ) }