Commit 49390348 authored by Sebastian Erdweg's avatar Sebastian Erdweg
Browse files

WIP fork at joinComputations

parent 33f9d1a8
Pipeline #279739 failed with stage
in 47 seconds
......@@ -14,10 +14,10 @@ lazy val root = (project in file("."))
.settings(name := "sturdy")
.aggregate(
sturdy_core,
sturdy_scheme,
// sturdy_scheme,
sturdy_tip,
sturdy_wasm,
sturdy_tutorial
// sturdy_wasm,
// sturdy_tutorial
)
.settings(skip / publish := true)
......@@ -44,49 +44,49 @@ lazy val sturdy_tip = (project in file("sturdy-tip"))
)
)
lazy val sturdy_scheme = (project in file("sturdy-scheme"))
.dependsOn(sturdy_core % "compile->compile;test->test")
.settings(
name := "sturdy-scheme",
libraryDependencies ++= Seq(
"org.typelevel" %% "cats-parse" % "0.3.4",
// test
"org.scalatest" %% "scalatest" % "3.2.9" % "test"
)
)
//lazy val sturdy_scheme = (project in file("sturdy-scheme"))
// .dependsOn(sturdy_core % "compile->compile;test->test")
// .settings(
// name := "sturdy-scheme",
// libraryDependencies ++= Seq(
// "org.typelevel" %% "cats-parse" % "0.3.4",
// // test
// "org.scalatest" %% "scalatest" % "3.2.9" % "test"
// )
// )
val swamCommit = "39999a1751076c6dbfe2a92c874f17683730d14e"
val swam = uri(s"https://gitlab.rlp.net/plmz/external/swam.git#$swamCommit")
lazy val sturdy_wasm = (project in file("sturdy-wasm"))
.dependsOn(sturdy_core % "compile->compile;test->test")
.dependsOn(ProjectRef(swam, "swam_core") % "compile->compile;test->test")
.dependsOn(ProjectRef(swam, "swam_text") % "test->test")
.settings(
name := "sturdy-wasm",
libraryDependencies ++= Seq(
// test
"org.scalatest" %% "scalatest" % "3.2.9" % "test",
"org.json4s" %% "json4s-native" % "4.0.4" % "test",
("org.typelevel" %% "cats-parse" % "0.3.4").cross(CrossVersion.for3Use2_13) % "test",
// "org.xerial" % "sqlite-jdbc" % "3.36.0.3",
// ("org.typelevel" %% "cats-effect" % "3.3.9").cross(CrossVersion.for3Use2_13),
// "io.circe" %% "circe-core" % "0.14.1",
// "io.circe" %% "circe-generic" % "0.14.1",
// "io.circe" %% "circe-parser" % "0.14.1"
)
)
//lazy val sturdy_wasm = (project in file("sturdy-wasm"))
// .dependsOn(sturdy_core % "compile->compile;test->test")
// .dependsOn(ProjectRef(swam, "swam_core") % "compile->compile;test->test")
// .dependsOn(ProjectRef(swam, "swam_text") % "test->test")
// .settings(
// name := "sturdy-wasm",
// libraryDependencies ++= Seq(
// // test
// "org.scalatest" %% "scalatest" % "3.2.9" % "test",
// "org.json4s" %% "json4s-native" % "4.0.4" % "test",
// ("org.typelevel" %% "cats-parse" % "0.3.4").cross(CrossVersion.for3Use2_13) % "test",
//// "org.xerial" % "sqlite-jdbc" % "3.36.0.3",
//// ("org.typelevel" %% "cats-effect" % "3.3.9").cross(CrossVersion.for3Use2_13),
// // "io.circe" %% "circe-core" % "0.14.1",
// // "io.circe" %% "circe-generic" % "0.14.1",
// // "io.circe" %% "circe-parser" % "0.14.1"
// )
// )
lazy val sturdy_tutorial = (project in file("sturdy-tutorial"))
.dependsOn(sturdy_core % "compile->compile;test->test")
.settings(
name := "sturdy-tutorial",
libraryDependencies ++= Seq(
"org.typelevel" %% "cats-parse" % "0.3.4",
"org.typelevel" %% "cats-core" % "2.6.1",
"org.scalatest" %% "scalatest" % "3.2.9" % "test"
)
)
//lazy val sturdy_tutorial = (project in file("sturdy-tutorial"))
// .dependsOn(sturdy_core % "compile->compile;test->test")
// .settings(
// name := "sturdy-tutorial",
// libraryDependencies ++= Seq(
// "org.typelevel" %% "cats-parse" % "0.3.4",
// "org.typelevel" %% "cats-core" % "2.6.1",
// "org.scalatest" %% "scalatest" % "3.2.9" % "test"
// )
// )
//lazy val sturdy_wasm_benchmarks = (project in file("sturdy-wasm-benchmarks"))
// .dependsOn(sturdy_wasm % "compile->compile")
......
......@@ -7,3 +7,8 @@ trait Executor:
val e = this.newInstance
e.copyState(this)
e
trait Executable[+B] extends Function1[Executor, B]:
def executor: Executor
def run: B = apply(executor)
def runWith(exec: Executor): B = apply(exec)
package sturdy.data
import sturdy.Executable
import sturdy.effect.EffectStack
import sturdy.values.Join
......@@ -22,7 +23,7 @@ type WithJoin[A] = MayJoin.WithJoin[A]
given noJoin[A]: NoJoin[A] = MayJoin.NoJoin()
inline def joinComputations[A](f: => A)(g: => A)(using w: WithJoin[A]): A =
inline def joinComputations[A](f: Executable[A])(g: Executable[A])(using w: WithJoin[A]): A =
w.eff.joinComputations(f)(g)(using w.j)
inline def joinWithFailure[A](f: => A)(g: => Nothing)(using eff: EffectStack): A =
......
package sturdy.effect
import sturdy.{Executable, Executor}
import sturdy.values.Join
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
class EffectStack(_effects: => List[Effectful]) extends ObservableJoin:
private lazy val effects = _effects
private def baseJoiner[A]: ComputationJoiner[A] = new ComputationJoiner {
......@@ -22,12 +26,17 @@ class EffectStack(_effects: => List[Effectful]) extends ObservableJoin:
override def retainBoth(fRes: TrySturdy[A], gRes: TrySturdy[A]): Unit = joiners.foreach(_.retainBoth(fRes, gRes))
}
final def joinComputations[A](f: => A)(g: => A): Join[A] ?=> A = {
final def joinComputations[A](f: Executable[A])(g: Executable[A]): (Executor, Join[A]) ?=> A = {
val joiner = makeComputationJoiner[A]
val triedF = TrySturdy(f)
joiner.inbetween()
val triedG = TrySturdy(g)
val gExecutor = if (f.executor eq g.executor) f.executor.fork else g.executor
import concurrent.ExecutionContext.Implicits.global
val futureF = Future(f.run)
val futureG = Future(g.runWith(gExecutor))
val triedF = TrySturdy(Await.result(futureF, Duration.Inf))
val triedG = TrySturdy(Await.result(futureG, Duration.Inf))
(triedF.isBottom, triedG.isBottom) match
case (false, false) => joiner.retainBoth(triedF, triedG)
......@@ -38,6 +47,7 @@ class EffectStack(_effects: => List[Effectful]) extends ObservableJoin:
Join(triedF, triedG).get.getOrThrow
}
def joinWithFailure[A](f: => A)(g: => Nothing): A = {
val joiner = makeComputationJoiner[A]
......@@ -54,7 +64,7 @@ class EffectStack(_effects: => List[Effectful]) extends ObservableJoin:
Join(triedF, triedG).get.getOrThrow
}
final def mapJoin[A, B](as: Iterable[A], f: A => B): Join[B] ?=> B = as.size match
final def mapJoin[A, B](as: Iterable[A], f: A => B): (Executor, Join[B]) ?=> B = as.size match
case 0 => throw new IllegalArgumentException
case 1 => f(as.head)
case 2 =>
......@@ -69,7 +79,7 @@ class EffectStack(_effects: => List[Effectful]) extends ObservableJoin:
case _ =>
mapJoinIt(as.iterator, f)
private final def mapJoinIt[A, B](as: Iterator[A], f: A => B): Join[B] ?=> B =
private final def mapJoinIt[A, B](as: Iterator[A], f: A => B): (Executor, Join[B]) ?=> B =
val a = as.next()
if (as.isEmpty)
f(a)
......
......@@ -24,4 +24,6 @@ class ConcreteInterpreter extends GenericInterpreter[Int, NoJoin]:
override val jv: NoJoin[Int] = noJoin
override val fixpoint: Fixpoint[FixIn, FixOut[Int]] = new ConcreteFixpoint[FixIn, FixOut[Int]]
\ No newline at end of file
override val fixpoint: Fixpoint[FixIn, FixOut[Int]] = new ConcreteFixpoint[FixIn, FixOut[Int]]
override def newInstance: ConcreteInterpreter = new ConcreteInterpreter
\ No newline at end of file
......@@ -79,7 +79,8 @@ case object UninitializedVariable extends FailureKind
* With these interface at hand we can now implement the generic interpreter. This is only the first try without
* using a fixpoint computation. We will later refine the generic interpreter.
*/
trait GenericInterpreterFirstShot[V, J[_] <: MayJoin[_]]:
trait GenericInterpreterFirstShot[V, J[_] <: MayJoin[_]]
extends sturdy.Executor[GenericInterpreterFirstShot[V, J]]:
// value components - we require a NumericOps component and a Branching component
val numericOps: NumericOps[V]
val branching: Branching[V,Unit]
......@@ -90,7 +91,10 @@ trait GenericInterpreterFirstShot[V, J[_] <: MayJoin[_]]:
// joining of computations requires all effect components to participate in the join.
// We achieve this by using an effect stack containing all effect components of the language.
final val effectStack: EffectStack = new EffectStack(List(store, failure))
final val effectStack: EffectStack = new EffectStack {
override type E = GenericInterpreterFirstShot[V, J]
override lazy val effects: List[Effectful] = List(store, failure)
}
given EffectStack = effectStack
given Failure = failure
......@@ -159,7 +163,10 @@ object GenericInterpreter:
import GenericInterpreter.*
trait GenericInterpreter[V, J[_] <: MayJoin[_]]:
trait GenericInterpreter[V, J[_] <: MayJoin[_]]
extends sturdy.Executor[GenericInterpreter[V, J]]:
override def self: GenericInterpreter[V, J] = this
val fixpoint: fix.Fixpoint[FixIn,FixOut[V]]
type Fixed = FixIn => FixOut[V]
......@@ -174,7 +181,10 @@ trait GenericInterpreter[V, J[_] <: MayJoin[_]]:
// joining of computations requires all effect components to participate in the join.
// We achieve this by using an effect stack containing all effect components of the language.
final val effectStack: EffectStack = new EffectStack(List(store, failure))
final val effectStack: EffectStack = new EffectStack {
override type E = GenericInterpreter[V, J]
override lazy val effects: List[Effectful] = List(store, failure)
}
given EffectStack = effectStack
given Failure = failure
......
......@@ -42,6 +42,8 @@ class SignInterpreter extends GenericInterpreter[Sign, WithJoin]:
given Finite[String] with {}
}
override def newInstance: SignInterpreter = new SignInterpreter
// We define what is means for a sign interpreter to be sound with respect to a concrete interpreter
given Soundness[ConcreteInterpreter, SignInterpreter] with
def isSound(c: ConcreteInterpreter, a: SignInterpreter): IsSound = a.store.storeIsSound(c.store)
\ No newline at end of file
......@@ -43,6 +43,7 @@ class SignInterpreterTest extends AnyFlatSpec, Matchers:
case AFallible.Unfailing(v) => assertResult(expected)(v)
case AFallible.MaybeFailing(v,_) => assertResult(expected)(v)
case AFallible.Failing(fails) => assert(false, s"Expected $expected but execution failed: $fails")
case AFallible.Diverging(recur) => assert(false, s"Expected $expected but execution diverged: $recur")
}
def testSoundness(p: Path, arg: Int): Unit =
......
......@@ -222,7 +222,6 @@ trait GenericInterpreter[V, Addr, Bytes, Size, ExcV, FuncIx, FunV, J[_] <: MayJo
callFrame.setLocals(in._4)
}
private given Failure = failure
lazy val num = new GenericInterpreterNumerics[V, J](stack, wasmOps)
private val labelStack = new LabelStack
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment