diff --git a/build.sbt b/build.sbt index d3a64cd..ae287c5 100644 --- a/build.sbt +++ b/build.sbt @@ -7,16 +7,19 @@ lazy val root = (project in file(".")) libraryDependencies += "org.typelevel" %% "cats-core" % "2.9.0", libraryDependencies += "org.typelevel" %% "cats-effect" % "3.5.0", libraryDependencies += "com.monovore" %% "decline" % "2.4.1", - libraryDependencies += ("org.scalameta" %% "scalafmt-core" % "3.7.4").cross( - CrossVersion.for3Use2_13 - ), + // libraryDependencies += ("org.scalameta" %% "scalafmt-core" % "3.7.4").cross( + // CrossVersion.for3Use2_13 + // ), libraryDependencies += "org.typelevel" %% "cats-parse" % "0.3.9", libraryDependencies += "io.circe" %% "circe-core" % circeVersion, libraryDependencies += "io.circe" %% "circe-generic" % circeVersion, libraryDependencies += "io.circe" %% "circe-parser" % circeVersion, - libraryDependencies += ("com.lihaoyi" %% "fansi" % "0.4.0").cross( - CrossVersion.for3Use2_13 // needed because scalafmt is 2.13 - ), + // libraryDependencies += ("com.lihaoyi" %% "fansi" % "0.4.0").cross( + // CrossVersion.for3Use2_13 // needed because scalafmt is 2.13 + // ), + libraryDependencies += ("com.lihaoyi" %% "fansi" % "0.4.0"), + // REScala deps + libraryDependencies += ("de.tu-darmstadt.stg" %% "rescala" % "0.33.0"), // optics dependencies libraryDependencies ++= Seq( "dev.optics" %% "monocle-core" % "3.2.0" diff --git a/src/main/scala/lore/DSL/DSL.scala b/src/main/scala/lore/DSL/DSL.scala new file mode 100644 index 0000000..eecc3e2 --- /dev/null +++ b/src/main/scala/lore/DSL/DSL.scala @@ -0,0 +1,66 @@ +package lore.DSL +import scala.quoted.* +import rescala.default._ +import lore.Parser + +type Source[A] = Var[A] +type Derived[A] = Signal[A] + +object Source: + inline def apply[A](inline expr: A) = Var(expr) + +object Derived: + inline def apply[A](inline expr: A) = Signal { expr } + +// S = source type, A = argument type +// case class Interaction( +// req: List[String], +// ens: List[Boolean], +// exec: List[Any] +// ) +// class InteractionWithModifiesAndExecutes[A]( +// modifies: List[Source[A]], +// executes: () => List[A] +// ) +private class InteractionWithTypes[S, A]: + inline def requires(inline expr: (S, A) => Boolean) = InteractionWithRequires( + expr + ) + +private class InteractionWithRequires[S, A](requires: (S, A) => Boolean): + inline def modifies(inline expr: Source[S]) = + InteractionWithRequiresAndModifies(requires, expr) + +// private class InteractionWithModifies[A](modifies: Source[A]): +// inline def executes(inline expr: A => A) = +// () => modifies.transform(expr) +// inline def requires(inline expr: () => Boolean) = +// InteractionWithRequiresAndModifies(expr, modifies) + +private class InteractionWithRequiresAndModifies[S, A]( + requires: (S, A) => Boolean, + modifies: Source[S] +): + inline def executes(inline expr: (S, A) => S) = + (arg: A) => + modifies.transform(currVal => + if requires(currVal, arg) then expr(currVal, arg) + else + println(s"Requirement $requires evaluated to false!") + currVal + ) + +object Interaction: + inline def apply[S, A] = InteractionWithTypes[S, A] + // inline def modifies[A](source: Source[A]) = InteractionWithModifies(source) + inline def requires[S, A](b: Boolean): Boolean = + ${ + makeFromRequires('b) + } + +def makeFromRequires(b: Expr[Boolean])(using Quotes) = + println(b.show) + Parser.parse(b.toString()) match + case Left(err) => println(err) + case Right(value) => println(value) + b diff --git a/src/main/scala/lore/DSL/DSLTest.scala b/src/main/scala/lore/DSL/DSLTest.scala new file mode 100644 index 0000000..c56bab4 --- /dev/null +++ b/src/main/scala/lore/DSL/DSLTest.scala @@ -0,0 +1,24 @@ +import lore.DSL._ + +import rescala.default + +object DSLTest: + @main + def main = + val a: Source[Int] = Source(0) + val b: Derived[Int] = Derived { a() + a() } + val add10 = + Interaction[Int, Int] + .requires((curr, _) => curr < 20) + .modifies(a) + .executes((curr, _) => curr + 10) + // .requires((curr, _) => curr < 20) + // .modifies(a) + // .requires(() => false) + // .executes((curr) => curr + 10) + add10(0) + println(s"a: ${a.now}, b: ${b.now}") + add10(0) + println(s"a: ${a.now}, b: ${b.now}") + add10(0) + println(s"a: ${a.now}, b: ${b.now}")