Skip to content

Commit e131cdb

Browse files
phischub-studios
andauthored
Rest of computation in state statements (#824)
- [x] Synchronize naming of `Alloc`, `Var`, `Get`, `Set`. - [x] Adjust numbers in VM tests --------- Co-authored-by: Jonathan Brachthäuser <[email protected]>
1 parent 295bc65 commit e131cdb

File tree

17 files changed

+183
-154
lines changed

17 files changed

+183
-154
lines changed

effekt/jvm/src/test/scala/effekt/core/VMTests.scala

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ class VMTests extends munit.FunSuite {
241241
dynamicDispatches = 5000,
242242
patternMatches = 0,
243243
branches = 31628,
244-
pushedFrames = 34010,
245-
poppedFrames = 34010,
244+
pushedFrames = 31479,
245+
poppedFrames = 31479,
246246
allocations = 0,
247247
closures = 100,
248248
variableReads = 7132,
@@ -273,8 +273,8 @@ class VMTests extends munit.FunSuite {
273273
dynamicDispatches = 0,
274274
patternMatches = 0,
275275
branches = 26,
276-
pushedFrames = 117,
277-
poppedFrames = 117,
276+
pushedFrames = 18,
277+
poppedFrames = 18,
278278
allocations = 0,
279279
closures = 0,
280280
variableReads = 70,
@@ -289,8 +289,8 @@ class VMTests extends munit.FunSuite {
289289
dynamicDispatches = 0,
290290
patternMatches = 455,
291291
branches = 56,
292-
pushedFrames = 80,
293-
poppedFrames = 80,
292+
pushedFrames = 17,
293+
poppedFrames = 17,
294294
allocations = 31,
295295
closures = 0,
296296
variableReads = 34,
@@ -321,8 +321,8 @@ class VMTests extends munit.FunSuite {
321321
dynamicDispatches = 0,
322322
patternMatches = 0,
323323
branches = 26736,
324-
pushedFrames = 51284,
325-
poppedFrames = 51284,
324+
pushedFrames = 5001,
325+
poppedFrames = 5001,
326326
allocations = 0,
327327
closures = 0,
328328
variableReads = 34546,
@@ -337,8 +337,8 @@ class VMTests extends munit.FunSuite {
337337
dynamicDispatches = 0,
338338
patternMatches = 16396,
339339
branches = 16287,
340-
pushedFrames = 65630,
341-
poppedFrames = 65630,
340+
pushedFrames = 24590,
341+
poppedFrames = 24590,
342342
allocations = 8206,
343343
closures = 0,
344344
variableReads = 41027,
@@ -353,8 +353,8 @@ class VMTests extends munit.FunSuite {
353353
dynamicDispatches = 0,
354354
patternMatches = 0,
355355
branches = 17326,
356-
pushedFrames = 54797,
357-
poppedFrames = 54797,
356+
pushedFrames = 8661,
357+
poppedFrames = 8661,
358358
allocations = 0,
359359
closures = 0,
360360
variableReads = 32437,
@@ -369,8 +369,8 @@ class VMTests extends munit.FunSuite {
369369
dynamicDispatches = 0,
370370
patternMatches = 0,
371371
branches = 5463,
372-
pushedFrames = 28674,
373-
poppedFrames = 28674,
372+
pushedFrames = 5463,
373+
poppedFrames = 5463,
374374
allocations = 5461,
375375
closures = 0,
376376
variableReads = 13654,
@@ -501,8 +501,8 @@ class VMTests extends munit.FunSuite {
501501
dynamicDispatches = 0,
502502
patternMatches = 0,
503503
branches = 6,
504-
pushedFrames = 12,
505-
poppedFrames = 12,
504+
pushedFrames = 1,
505+
poppedFrames = 1,
506506
allocations = 0,
507507
closures = 0,
508508
variableReads = 6,
@@ -517,8 +517,8 @@ class VMTests extends munit.FunSuite {
517517
dynamicDispatches = 0,
518518
patternMatches = 0,
519519
branches = 7,
520-
pushedFrames = 14,
521-
poppedFrames = 14,
520+
pushedFrames = 2,
521+
poppedFrames = 2,
522522
allocations = 0,
523523
closures = 0,
524524
variableReads = 7,
@@ -549,8 +549,8 @@ class VMTests extends munit.FunSuite {
549549
dynamicDispatches = 0,
550550
patternMatches = 0,
551551
branches = 210,
552-
pushedFrames = 378,
553-
poppedFrames = 377,
552+
pushedFrames = 69,
553+
poppedFrames = 68,
554554
allocations = 0,
555555
closures = 0,
556556
variableReads = 222,
@@ -597,8 +597,8 @@ class VMTests extends munit.FunSuite {
597597
dynamicDispatches = 0,
598598
patternMatches = 3490,
599599
branches = 3167,
600-
pushedFrames = 8207,
601-
poppedFrames = 9807,
600+
pushedFrames = 5357,
601+
poppedFrames = 6957,
602602
allocations = 2556,
603603
closures = 0,
604604
variableReads = 2051,
@@ -647,8 +647,8 @@ class VMTests extends munit.FunSuite {
647647
dynamicDispatches = 57,
648648
patternMatches = 31,
649649
branches = 40,
650-
pushedFrames = 33,
651-
poppedFrames = 30,
650+
pushedFrames = 23,
651+
poppedFrames = 20,
652652
allocations = 15,
653653
closures = 36,
654654
variableReads = 7,
@@ -663,8 +663,8 @@ class VMTests extends munit.FunSuite {
663663
dynamicDispatches = 7,
664664
patternMatches = 95,
665665
branches = 41,
666-
pushedFrames = 105,
667-
poppedFrames = 106,
666+
pushedFrames = 74,
667+
poppedFrames = 75,
668668
allocations = 73,
669669
closures = 7,
670670
variableReads = 29,
@@ -679,8 +679,8 @@ class VMTests extends munit.FunSuite {
679679
dynamicDispatches = 18,
680680
patternMatches = 298,
681681
branches = 405,
682-
pushedFrames = 703,
683-
poppedFrames = 703,
682+
pushedFrames = 520,
683+
poppedFrames = 520,
684684
allocations = 202,
685685
closures = 27,
686686
variableReads = 164,
@@ -695,8 +695,8 @@ class VMTests extends munit.FunSuite {
695695
dynamicDispatches = 783,
696696
patternMatches = 13502,
697697
branches = 14892,
698-
pushedFrames = 28210,
699-
poppedFrames = 28186,
698+
pushedFrames = 20836,
699+
poppedFrames = 20812,
700700
allocations = 7923,
701701
closures = 521,
702702
variableReads = 6742,
@@ -711,8 +711,8 @@ class VMTests extends munit.FunSuite {
711711
dynamicDispatches = 443,
712712
patternMatches = 7272,
713713
branches = 8110,
714-
pushedFrames = 16101,
715-
poppedFrames = 16088,
714+
pushedFrames = 11348,
715+
poppedFrames = 11335,
716716
allocations = 4317,
717717
closures = 358,
718718
variableReads = 4080,
@@ -727,8 +727,8 @@ class VMTests extends munit.FunSuite {
727727
dynamicDispatches = 3201452,
728728
patternMatches = 1474290,
729729
branches = 303298,
730-
pushedFrames = 7574476,
731-
poppedFrames = 6709181,
730+
pushedFrames = 3212277,
731+
poppedFrames = 2346982,
732732
allocations = 4626007,
733733
closures = 865541,
734734
variableReads = 2908620,
@@ -743,8 +743,8 @@ class VMTests extends munit.FunSuite {
743743
dynamicDispatches = 0,
744744
patternMatches = 795964,
745745
branches = 71995,
746-
pushedFrames = 223269,
747-
poppedFrames = 223269,
746+
pushedFrames = 127131,
747+
poppedFrames = 127131,
748748
allocations = 103221,
749749
closures = 0,
750750
variableReads = 77886,
@@ -761,8 +761,8 @@ class VMTests extends munit.FunSuite {
761761
dynamicDispatches = 0,
762762
patternMatches = 0,
763763
branches = 11,
764-
pushedFrames = 92,
765-
poppedFrames = 92,
764+
pushedFrames = 2,
765+
poppedFrames = 2,
766766
allocations = 0,
767767
closures = 0,
768768
variableReads = 61,
@@ -793,8 +793,8 @@ class VMTests extends munit.FunSuite {
793793
dynamicDispatches = 9009,
794794
patternMatches = 30052,
795795
branches = 3003,
796-
pushedFrames = 54105,
797-
poppedFrames = 54105,
796+
pushedFrames = 15027,
797+
poppedFrames = 15027,
798798
allocations = 24060,
799799
closures = 12030,
800800
variableReads = 24048,

effekt/shared/src/main/scala/effekt/core/PolymorphismBoxing.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,8 @@ object PolymorphismBoxing extends Phase[CoreTransformed, CoreTransformed] {
276276

277277
case Stmt.Invoke(callee, method, methodTpe, targs, vargs, bargs) => ???
278278

279-
case Stmt.Get(id, capt, tpe) => Stmt.Get(id, capt, transform(tpe))
280-
case Stmt.Put(id, capt, value) => Stmt.Put(id, capt, transform(value))
279+
case Stmt.Get(id, tpe, ref, capt, body) => Stmt.Get(id, transform(tpe), ref, capt, transform(body))
280+
case Stmt.Put(ref, capt, value, body) => Stmt.Put(ref, capt, transform(value), transform(body))
281281
case Stmt.If(cond, thn, els) =>
282282
Stmt.If(transform(cond), transform(thn), transform(els))
283283
case Stmt.Match(scrutinee, clauses, default) =>

effekt/shared/src/main/scala/effekt/core/PrettyPrinter.scala

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ object PrettyPrinter extends ParenPrettyPrinter {
165165

166166
def toDoc(s: Stmt): Doc = s match {
167167
// requires a block to be readable:
168-
case _ : (Stmt.Def | Stmt.Let | Stmt.Val | Stmt.Alloc | Stmt.Var) => block(toDocStmts(s))
168+
case _ : (Stmt.Def | Stmt.Let | Stmt.Val | Stmt.Alloc | Stmt.Var | Stmt.Get | Stmt.Put) => block(toDocStmts(s))
169169
case other => toDocStmts(s)
170170
}
171171

@@ -212,18 +212,20 @@ object PrettyPrinter extends ParenPrettyPrinter {
212212
"resume" <> parens(toDoc(k)) <+> block(toDocStmts(body))
213213

214214
case Alloc(id, init, region, body) =>
215-
"var" <+> toDoc(id) <+> "in" <+> toDoc(region) <+> "=" <+> toDoc(init) <+> ";" <> line <>
215+
"var" <+> toDoc(id) <+> "in" <+> toDoc(region) <+> "=" <+> toDoc(init) <> ";" <> line <>
216216
toDocStmts(body)
217217

218-
case Var(id, init, cap, body) =>
219-
"var" <+> toDoc(id) <+> "=" <+> toDoc(init) <+> ";" <> line <>
218+
case Var(ref, init, cap, body) =>
219+
"var" <+> toDoc(ref) <+> "=" <+> toDoc(init) <> ";" <> line <>
220220
toDocStmts(body)
221221

222-
case Get(id, capt, tpe) =>
223-
"!" <> toDoc(id)
222+
case Get(id, tpe, ref, capt, body) =>
223+
"let" <+> toDoc(id) <+> "=" <+> "!" <> toDoc(ref) <> ";" <> line <>
224+
toDocStmts(body)
224225

225-
case Put(id, capt, value) =>
226-
toDoc(id) <+> ":=" <+> toDoc(value)
226+
case Put(ref, capt, value, body) =>
227+
toDoc(ref) <+> ":=" <+> toDoc(value) <> ";" <> line <>
228+
toDocStmts(body)
227229

228230
case Region(body) =>
229231
"region" <+> toDoc(body)

effekt/shared/src/main/scala/effekt/core/Recursive.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,14 @@ class Recursive(
7171
case Stmt.Alloc(id, init, region, body) =>
7272
process(init)
7373
process(body)
74-
case Stmt.Var(id, init, capture, body) =>
74+
case Stmt.Var(ref, init, capture, body) =>
7575
process(init)
7676
process(body)
77-
case Stmt.Get(id, capt, tpe) => ()
78-
case Stmt.Put(id, tpe, value) => process(value)
77+
case Stmt.Get(ref, capt, tpe, id, body) =>
78+
process(body)
79+
case Stmt.Put(ref, tpe, value, body) =>
80+
process(value)
81+
process(body)
7982
case Stmt.Reset(body) => process(body)
8083
case Stmt.Shift(prompt, body) => process(prompt); process(body)
8184
case Stmt.Resume(k, body) => process(k); process(body)

effekt/shared/src/main/scala/effekt/core/Renamer.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,16 @@ class Renamer(names: Names = Names(Map.empty), prefix: String = "") extends core
6565
val resolvedReg = rewrite(reg)
6666
withBinding(id) { core.Alloc(rewrite(id), resolvedInit, resolvedReg, rewrite(body)) }
6767

68-
case core.Var(id, init, capt, body) =>
68+
case core.Var(ref, init, capt, body) =>
6969
val resolvedInit = rewrite(init)
7070
val resolvedCapt = rewrite(capt)
71-
withBinding(id) { core.Var(rewrite(id), resolvedInit, resolvedCapt, rewrite(body)) }
71+
withBinding(ref) { core.Var(rewrite(ref), resolvedInit, resolvedCapt, rewrite(body)) }
72+
73+
case core.Get(id, tpe, ref, capt, body) =>
74+
val resolvedRef = rewrite(ref)
75+
val resolvedCapt = rewrite(capt)
76+
withBinding(id) { core.Get(rewrite(id), rewrite(tpe), resolvedRef, resolvedCapt, rewrite(body)) }
77+
7278
}
7379

7480
override def block: PartialFunction[Block, Block] = {

effekt/shared/src/main/scala/effekt/core/Transformer.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,9 @@ object Transformer extends Phase[Typechecked, CoreTransformed] {
329329
case sym: RefBinder =>
330330
val stateType = Context.blockTypeOf(sym)
331331
val tpe = TState.extractType(stateType)
332-
Context.bind(Get(sym, transform(Context.captureOf(sym)), transform(tpe)))
332+
val stateId = Id("s")
333+
// emits `let s = !ref; return s`
334+
Context.bind(Get(stateId, transform(tpe), sym, transform(Context.captureOf(sym)), Return(core.ValueVar(stateId, transform(tpe)))))
333335
case sym: ValueSymbol => ValueVar(sym)
334336
case sym: BlockSymbol => transformBox(tree)
335337
}
@@ -472,7 +474,9 @@ object Transformer extends Phase[Typechecked, CoreTransformed] {
472474

473475
case a @ source.Assign(id, expr) =>
474476
val sym = a.definition
475-
Context.bind(Put(sym, transform(Context.captureOf(sym)), transformAsPure(expr)))
477+
// emits `ref := value; return ()`
478+
Context.bind(Put(sym, transform(Context.captureOf(sym)), transformAsPure(expr), Return(Literal((), core.Type.TUnit))))
479+
Literal((), core.Type.TUnit)
476480

477481
// methods are dynamically dispatched, so we have to assume they are `control`, hence no PureApp.
478482
case c @ source.MethodCall(receiver, id, targs, vargs, bargs) =>

effekt/shared/src/main/scala/effekt/core/Tree.scala

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,13 @@ enum Stmt extends Tree {
274274
// creates a fresh state handler to model local (backtrackable) state.
275275
// [[capture]] is a binding occurrence.
276276
// e.g. state(init) { [x]{x: Ref} => ... }
277-
case Var(id: Id, init: Pure, capture: Id, body: Stmt)
278-
case Get(id: Id, annotatedCapt: Captures, annotatedTpe: ValueType)
279-
case Put(id: Id, annotatedCapt: Captures, value: Pure)
277+
case Var(ref: Id, init: Pure, capture: Id, body: Stmt)
278+
279+
// e.g. let x: T = !ref @ r; body
280+
case Get(id: Id, annotatedTpe: ValueType, ref: Id, annotatedCapt: Captures, body: Stmt)
281+
282+
// e.g. ref @ r := value; body
283+
case Put(ref: Id, annotatedCapt: Captures, value: Pure, body: Stmt)
280284

281285
// binds a fresh prompt as [[id]] in [[body]] and delimits the scope of captured continuations
282286
// Reset({ [cap]{p: Prompt[answer] at cap} => stmt: answer}): answer
@@ -614,11 +618,11 @@ object Variables {
614618
case Stmt.Region(body) => free(body)
615619
// are mutable variables now block variables or not?
616620
case Stmt.Alloc(id, init, region, body) => free(init) ++ Variables.block(region, TRegion, Set(region)) ++ (free(body) -- Variables.block(id, TState(init.tpe), Set(region)))
617-
case Stmt.Var(id, init, capture, body) => free(init) ++ (free(body) -- Variables.block(id, TState(init.tpe), Set(capture)))
618-
case Stmt.Get(id, annotatedCapt, annotatedTpe) =>
619-
Variables.block(id, core.Type.TState(annotatedTpe), annotatedCapt)
620-
case Stmt.Put(id, annotatedCapt, value) =>
621-
Variables.block(id, core.Type.TState(value.tpe), annotatedCapt) ++ free(value)
621+
case Stmt.Var(ref, init, capture, body) => free(init) ++ (free(body) -- Variables.block(ref, TState(init.tpe), Set(capture)))
622+
case Stmt.Get(id, annotatedTpe, ref, annotatedCapt, body) =>
623+
Variables.block(ref, core.Type.TState(annotatedTpe), annotatedCapt) ++ (free(body) -- Variables.value(id, annotatedTpe))
624+
case Stmt.Put(ref, annotatedCapt, value, body) =>
625+
Variables.block(ref, core.Type.TState(value.tpe), annotatedCapt) ++ free(value) ++ free(body)
622626

623627
case Stmt.Reset(body) => free(body)
624628
case Stmt.Shift(prompt, body) => free(prompt) ++ free(body)
@@ -710,14 +714,14 @@ object substitutions {
710714
Alloc(id, substitute(init), substituteAsVar(region),
711715
substitute(body)(using subst shadowBlocks List(id)))
712716

713-
case Var(id, init, capture, body) =>
714-
Var(id, substitute(init), capture, substitute(body)(using subst shadowBlocks List(id)))
717+
case Var(ref, init, capture, body) =>
718+
Var(ref, substitute(init), capture, substitute(body)(using subst shadowBlocks List(ref)))
715719

716-
case Get(id, capt, tpe) =>
717-
Get(substituteAsVar(id), substitute(capt), substitute(tpe))
720+
case Get(id, tpe, ref, capt, body) =>
721+
Get(id, substitute(tpe), substituteAsVar(ref), substitute(capt), substitute(body)(using subst shadowBlocks List(id)))
718722

719-
case Put(id, capt, value) =>
720-
Put(substituteAsVar(id), substitute(capt), substitute(value))
723+
case Put(ref, capt, value, body) =>
724+
Put(substituteAsVar(ref), substitute(capt), substitute(value), substitute(body))
721725

722726
// We annotate the answer type here since it needs to be the union of body.tpe and all shifts
723727
case Reset(body) =>

0 commit comments

Comments
 (0)