Skip to content

Commit

Permalink
Drop Select from core and add Run to CPS (#765)
Browse files Browse the repository at this point in the history
  • Loading branch information
b-studios authored Jan 8, 2025
1 parent 4a71622 commit 3cbf9cf
Show file tree
Hide file tree
Showing 19 changed files with 53 additions and 158 deletions.
40 changes: 5 additions & 35 deletions effekt/jvm/src/test/scala/effekt/core/VMTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = counting.poppedFrames,
allocations = counting.allocations,
closures = counting.closures,
fieldLookups = counting.fieldLookups,
variableReads = counting.variableReads,
variableWrites = counting.variableWrites,
resets = counting.resets,
Expand All @@ -100,7 +99,6 @@ class VMTests extends munit.FunSuite {
poppedFrames: Int,
allocations: Int,
closures: Int,
fieldLookups: Int,
variableReads: Int,
variableWrites: Int,
resets: Int,
Expand Down Expand Up @@ -247,7 +245,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 34010,
allocations = 0,
closures = 100,
fieldLookups = 0,
variableReads = 7132,
variableWrites = 3157,
resets = 0,
Expand All @@ -264,7 +261,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 4961,
allocations = 34,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 0,
Expand All @@ -281,7 +277,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 117,
allocations = 0,
closures = 0,
fieldLookups = 0,
variableReads = 70,
variableWrites = 32,
resets = 0,
Expand All @@ -292,13 +287,12 @@ class VMTests extends munit.FunSuite {
examplesDir / "benchmarks" / "are_we_fast_yet" / "nbody.effekt" -> Some(Summary(
staticDispatches = 56,
dynamicDispatches = 0,
patternMatches = 0,
patternMatches = 455,
branches = 56,
pushedFrames = 80,
poppedFrames = 80,
allocations = 31,
closures = 0,
fieldLookups = 455,
variableReads = 34,
variableWrites = 30,
resets = 0,
Expand All @@ -315,7 +309,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 3060,
allocations = 0,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 113,
Expand All @@ -332,7 +325,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 51284,
allocations = 0,
closures = 0,
fieldLookups = 0,
variableReads = 34546,
variableWrites = 11738,
resets = 0,
Expand All @@ -349,7 +341,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 65630,
allocations = 8206,
closures = 0,
fieldLookups = 0,
variableReads = 41027,
variableWrites = 8205,
resets = 0,
Expand All @@ -366,7 +357,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 54797,
allocations = 0,
closures = 0,
fieldLookups = 0,
variableReads = 32437,
variableWrites = 13699,
resets = 0,
Expand All @@ -383,7 +373,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 28674,
allocations = 5461,
closures = 0,
fieldLookups = 0,
variableReads = 13654,
variableWrites = 9557,
resets = 0,
Expand All @@ -402,7 +391,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 6,
allocations = 16,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 0,
Expand All @@ -419,7 +407,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 1,
allocations = 0,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 0,
Expand All @@ -436,7 +423,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 15,
allocations = 0,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 0,
Expand All @@ -453,7 +439,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 1,
allocations = 0,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 0,
Expand All @@ -470,7 +455,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 7,
allocations = 6,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 0,
Expand All @@ -487,7 +471,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 7,
allocations = 6,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 0,
Expand All @@ -504,7 +487,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 12,
allocations = 6,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 0,
Expand All @@ -523,7 +505,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 12,
allocations = 0,
closures = 0,
fieldLookups = 0,
variableReads = 6,
variableWrites = 5,
resets = 0,
Expand All @@ -540,7 +521,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 14,
allocations = 0,
closures = 0,
fieldLookups = 0,
variableReads = 7,
variableWrites = 6,
resets = 0,
Expand All @@ -557,7 +537,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 1409,
allocations = 54,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 1,
Expand All @@ -574,7 +553,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 377,
allocations = 0,
closures = 0,
fieldLookups = 0,
variableReads = 222,
variableWrites = 88,
resets = 1,
Expand All @@ -591,7 +569,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 1008,
allocations = 1002,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 5,
Expand All @@ -608,7 +585,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 16001,
allocations = 0,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 1000,
Expand All @@ -625,7 +601,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 9807,
allocations = 2556,
closures = 0,
fieldLookups = 0,
variableReads = 2051,
variableWrites = 1430,
resets = 10,
Expand All @@ -642,7 +617,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 880,
allocations = 4,
closures = 0,
fieldLookups = 0,
variableReads = 0,
variableWrites = 0,
resets = 1,
Expand All @@ -655,13 +629,12 @@ class VMTests extends munit.FunSuite {
examplesDir / "casestudies" / "ad.effekt.md" -> Some(Summary(
staticDispatches = 19,
dynamicDispatches = 335,
patternMatches = 0,
patternMatches = 706,
branches = 285,
pushedFrames = 453,
poppedFrames = 453,
allocations = 174,
closures = 39,
fieldLookups = 706,
variableReads = 0,
variableWrites = 0,
resets = 8,
Expand All @@ -678,7 +651,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 30,
allocations = 15,
closures = 36,
fieldLookups = 0,
variableReads = 7,
variableWrites = 3,
resets = 9,
Expand All @@ -695,7 +667,6 @@ class VMTests extends munit.FunSuite {
poppedFrames = 106,
allocations = 73,
closures = 8,
fieldLookups = 0,
variableReads = 29,
variableWrites = 18,
resets = 1,
Expand All @@ -706,13 +677,12 @@ class VMTests extends munit.FunSuite {
examplesDir / "casestudies" / "inference.effekt.md" -> Some(Summary(
staticDispatches = 1457444,
dynamicDispatches = 3201452,
patternMatches = 1474376,
patternMatches = 1474290,
branches = 303298,
pushedFrames = 7574572,
poppedFrames = 6709277,
pushedFrames = 7574480,
poppedFrames = 6709185,
allocations = 4626007,
closures = 865541,
fieldLookups = 0,
variableReads = 2908620,
variableWrites = 1453663,
resets = 288559,
Expand Down
7 changes: 0 additions & 7 deletions effekt/shared/src/main/scala/effekt/core/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,6 @@ class CoreParsers(positions: Positions, names: Names) extends EffektLexers(posit
// Pure Expressions
// ----------------
lazy val pure: P[Pure] =
pureNonAccess ~ many((`.` ~> id) ~ (`:` ~> valueType)) ^^ {
case firstTarget ~ accesses => accesses.foldLeft(firstTarget){
case (target, field ~ tpe) => Pure.Select(target, field, tpe)
}
}

lazy val pureNonAccess: P[Pure] =
( literal
| id ~ (`:` ~> valueType) ^^ Pure.ValueVar.apply
| `box` ~> captures ~ block ^^ { case capt ~ block => Pure.Box(block, capt) }
Expand Down
41 changes: 3 additions & 38 deletions effekt/shared/src/main/scala/effekt/core/PolymorphismBoxing.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,6 @@ object PolymorphismBoxing extends Phase[CoreTransformed, CoreTransformed] {
def unbox(p: Pure) = Pure.PureApp(unboxFn, Nil, List(p))
}

/**
* Describes how to box/unbox values using records
*
* @param boxTpe The type BoxedT
* @param constructor The constructor to use for boxing
* @param field The field to access for unboxing
*/
case class RecordBoxer(boxTpe: ValueType.Data, constructor: Constructor, field: Field) extends Boxer {
def tpe = boxTpe
def box(p: Pure) = Pure.Make(boxTpe, constructor.id, List(p))
def unbox(p: Pure) = Pure.Select(p, field.id, field.tpe)
}

/**
* Partial function to describe which values to box and how.
* Is defined iff values of the given type should be boxed.
Expand Down Expand Up @@ -124,18 +111,10 @@ object PolymorphismBoxing extends Phase[CoreTransformed, CoreTransformed] {
}
Some(ExternFnBoxer(boxRet, box, unbox))
}
/** Try to find a `BoxedT` type */
def findRecordBoxer() = boundary {
findRecord("Boxed" ++ name) match {
case Some(Declaration.Data(tpe, List(), List(cns@Constructor(id, List(field))))) =>
Some(RecordBoxer(ValueType.Data(tpe, Nil), cns, field))
case _ => None
}
}
findExternFnBoxer() orElse findRecordBoxer() getOrElse {

findExternFnBoxer() getOrElse {
Context.abort(s"Type ${name}, which needs to be boxed, is used as a type argument but no " +
s"corresponding pure externs box${name} and unbox${name} were defined in the prelude, " +
s"and also no record type Boxed${name}.")
s"corresponding pure externs box${name} and unbox${name} were defined in the prelude.")
}
}
}
Expand Down Expand Up @@ -379,20 +358,6 @@ object PolymorphismBoxing extends Phase[CoreTransformed, CoreTransformed] {
val coercedArgs = (vargs zip paramTypes).map { case (arg, paramTpe) => coerce(transform(arg), paramTpe) }
Pure.Make(transform(data), tag, coercedArgs)

case Pure.Select(target, field, annotatedType) => {
val (symbol, targs) = target.tpe match {
case ValueType.Data(symbol, targs) => (symbol, targs)
case t => Context.abort(s"Select on value of type ${PrettyPrinter.format(t)} is not supported.")
}
PContext.getData(symbol) match {
case Declaration.Data(id, tparams, List(Constructor(cns, fields))) =>
val f = fields.find(_.id == field).getOrElse{
Context.abort(s"${id} has no field ${field}.")
}
coerce(Pure.Select(target, field, transform(annotatedType)), Type.substitute(f.tpe, (tparams zip targs).toMap, Map()))
case t => Context.abort(s"Select on data type ${t.id} is not supported.")
}
}
case Pure.Box(b, annotatedCapture) =>
Pure.Box(transform(b), annotatedCapture)
}
Expand Down
2 changes: 0 additions & 2 deletions effekt/shared/src/main/scala/effekt/core/PrettyPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ object PrettyPrinter extends ParenPrettyPrinter {
case Make(data, tag, vargs) => "make" <+> toDoc(data) <+> toDoc(tag) <> argsToDoc(Nil, vargs, Nil)
case DirectApp(b, targs, vargs, bargs) => toDoc(b) <> argsToDoc(targs, vargs, bargs)

case Select(b, field, tpe) => toDoc(b) <> "." <> toDoc(field)

case Box(b, capt) => parens("box" <+> toDoc(b))
}

Expand Down
1 change: 0 additions & 1 deletion effekt/shared/src/main/scala/effekt/core/Recursive.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ class Recursive(
case Pure.Literal(value, annotatedType) => ()
case Pure.PureApp(b, targs, vargs) => process(b); vargs.foreach(process)
case Pure.Make(data, tag, vargs) => vargs.foreach(process)
case Pure.Select(target, field, annotatedType) => process(target)
case Pure.Box(b, annotatedCapture) => process(b)
}

Expand Down
29 changes: 28 additions & 1 deletion effekt/shared/src/main/scala/effekt/core/Transformer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,35 @@ object Transformer extends Phase[Typechecked, CoreTransformed] {
case source.Literal(value, tpe) =>
Literal(value, transform(tpe))

// [[ sc.field ]] = val x = sc match { tag: { (_, _, x, _) => return x } }; ...
case s @ source.Select(receiver, selector) =>
Select(transformAsPure(receiver), s.definition, transform(Context.inferredTypeOf(s)))
val field: Field = s.definition

val constructor = field.constructor
val dataType: symbols.TypeConstructor = constructor.tpe
val universals: List[symbols.TypeParam] = dataType.tparams

// allTypeParams = universals ++ existentials
val allTypeParams: List[symbols.TypeParam] = constructor.tparams

assert(allTypeParams.length == universals.length, "Existentials on record selection not supported, yet.")

val scrutineeTypeArgs = Context.inferredTypeOf(receiver) match {
case effekt.symbols.ValueType.ValueTypeApp(constructor, args) => args
case _ => Context.panic("Should not happen: selection from non ValueTypeApp")
}

val substitution = Substitutions((universals zip scrutineeTypeArgs).toMap, Map.empty)

val selected = Id("x")
val tpe = transform(Context.inferredTypeOf(s))
val params = constructor.fields.map {
case f: Field =>
val tpe = transform(substitution.substitute(f.returnType))
core.ValueParam(if f == field then selected else Id("_"), tpe)
}
Context.bind(Stmt.Match(transformAsPure(receiver),
List((constructor, BlockLit(Nil, Nil, params, Nil, Stmt.Return(Pure.ValueVar(selected, tpe))))), None))

case source.Box(capt, block) =>
transformBox(block)
Expand Down
Loading

0 comments on commit 3cbf9cf

Please sign in to comment.