Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions effekt/jvm/src/test/scala/effekt/ChezSchemeTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ abstract class ChezSchemeTests extends EffektTests {
examplesDir / "pos" / "object",
examplesDir / "pos" / "type_omission_op.effekt",
examplesDir / "pos" / "issue972.effekt",
examplesDir / "pos" / "issue1153.effekt",

// filesystem operations and bytearrays are not yet supported in our Chez backend
examplesDir / "benchmarks" / "input_output" / "word_count_ascii.effekt",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ object RemoveTailResumptions {
case Stmt.Match(scrutinee, clauses, default) => !freeInExpr(scrutinee) && clauses.forall {
case (_, BlockLit(tparams, cparams, vparams, bparams, body)) => tailResumptive(k, body)
} && default.forall { stmt => tailResumptive(k, stmt) }
case Stmt.Region(BlockLit(tparams, cparams, vparams, bparams, body)) => tailResumptive(k, body)
case Stmt.Region(BlockLit(tparams, cparams, vparams, bparams, body)) => false
case Stmt.Alloc(id, init, region, body) => tailResumptive(k, body) && !freeInExpr(init)
case Stmt.Var(ref, init, capture, body) => tailResumptive(k, body) && !freeInExpr(init)
// Conceptually, a mutable variable definition can be seen as a handler for get and put operations.
// Treating this as tail-resumptive leads to a failure of semantics preservation.
// See https://github.com/effekt-lang/effekt/issues/1153 for an example.
case Stmt.Var(ref, init, capture, body) => false
case Stmt.Get(ref, annotatedCapt, tpe, id, body) => tailResumptive(k, body)
case Stmt.Put(ref, annotatedCapt, value, body) => tailResumptive(k, body) && !freeInExpr(value)
case Stmt.Reset(BlockLit(tparams, cparams, vparams, bparams, body)) => false
Expand Down
2 changes: 2 additions & 0 deletions examples/pos/issue1153.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
3
3
49 changes: 49 additions & 0 deletions examples/pos/issue1153.effekt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
effect flip(): Bool

def all{prog: => Unit / {flip}} = {
try {
prog()
} with flip {
resume(true)
resume(false)
}
}

interface State[T] {
def get(): T
def set(x: T): Unit
}

interface allocate {
def fresh[T, R](init: T){k: {State[T]} => R}: R
}

def newRegion[T]{prog: {r: allocate} => T}: T = {
try {
prog{r}
} with r: allocate {
def fresh[T, R](init) = {
var x = init
def s = new State[T] {
def get() = x
def set(y) = {
x = y
}
}
resume{{k} => k{s}}
}
}
}

def main() = {
newRegion { {r} =>
all {
with def x = r.fresh(0)
if (do flip()) {
x.set(3)
} else {
}
println(x.get())
}
}
}