Skip to content

Commit 53e395e

Browse files
committed
Allow the user to define ShouldResetNestedFunctions = true to reset nested functions
1 parent 6a51ad8 commit 53e395e

File tree

2 files changed

+72
-25
lines changed

2 files changed

+72
-25
lines changed

reset/src/main/scala/com/thoughtworks/dsl/reset.scala

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,27 @@ import scala.util.control.Exception.Catcher
5353
* r % 10 should not be r / 10
5454
* }}}
5555
*/
56-
object reset {
56+
trait reset:
57+
type ShouldResetNestedFunctions <: Boolean & Singleton
58+
59+
transparent inline def reify[Value](inline value: Value): Any = ${
60+
reset.Macros.reify[ShouldResetNestedFunctions, Value]('value)
61+
}
62+
63+
class *[Functor[_]]() {
64+
inline def apply[Value](inline value: Value): Functor[Value] = ${
65+
reset.Macros.reset[ShouldResetNestedFunctions, Value, Functor[Value]]('value)
66+
}
67+
}
68+
inline def *[Domain[_]]: *[Domain] = new *[Domain]
69+
70+
inline def apply[Value](inline value: Value): Value = ${
71+
reset.Macros.reset[ShouldResetNestedFunctions, Value, Value]('value)
72+
}
73+
74+
object reset extends reset.DefaultOptions {
75+
trait DefaultOptions extends reset:
76+
type ShouldResetNestedFunctions = false
5777

5878
private class Macros[Q <: Quotes](resetDescendant: Boolean)(using val qctx: Q) {
5979
import qctx.reflect.{_, given}
@@ -785,32 +805,47 @@ object reset {
785805
}
786806

787807
object Macros {
788-
def reify[V](body: quoted.Expr[_])(using qctx: Quotes, tv: quoted.Type[V]): quoted.Expr[_] = {
789-
Macros[qctx.type](resetDescendant = false).reify[V](body/*.underlyingArgument*/)
790-
}
791-
792-
def reset[From, To](body: quoted.Expr[From])(using qctx: Quotes, fromType: quoted.Type[From], toType: quoted.Type[To]): quoted.Expr[To] = {
793-
import qctx.reflect.{_, given}
794-
val result: quoted.Expr[To] = Macros[qctx.type](resetDescendant = false).reset(body/*.underlyingArgument*/)
795-
// report.warning(result.asTerm.show(using qctx.reflect.Printer.TreeStructure))
796-
// report.warning(result.asTerm.show)
797-
result
808+
def reify[ShouldResetNestedFunctions <: Boolean & Singleton, V](
809+
body: quoted.Expr[_]
810+
)(using
811+
qctx: Quotes,
812+
translateNestedFunctions: quoted.Type[ShouldResetNestedFunctions],
813+
tv: quoted.Type[V]
814+
): quoted.Expr[_] = {
815+
import quoted.quotes.reflect.*
816+
quoted.Type.valueOfConstant[ShouldResetNestedFunctions] match {
817+
case None =>
818+
report.error("ShouldResetNestedFunctions is not defined", body)
819+
'{ ??? }
820+
case Some(translateNestedFunction) =>
821+
Macros[qctx.type](resetDescendant =
822+
quoted.Type.valueOfConstant[ShouldResetNestedFunctions].get
823+
).reify[V](body /*.underlyingArgument*/ )
824+
}
798825
}
799-
}
800826

801-
transparent inline def reify[Value](inline value: Value): Any = ${
802-
Macros.reify[Value]('value)
803-
}
804-
805-
class *[Functor[_]]() {
806-
inline def apply[Value](inline value: Value): Functor[Value] = ${
807-
Macros.reset[Value, Functor[Value]]('value)
827+
def reset[ShouldResetNestedFunctions <: Boolean & Singleton, From, To](
828+
body: quoted.Expr[From]
829+
)(using
830+
qctx: Quotes,
831+
translateNestedFunctions: quoted.Type[ShouldResetNestedFunctions],
832+
fromType: quoted.Type[From],
833+
toType: quoted.Type[To]
834+
): quoted.Expr[To] = {
835+
import quoted.quotes.reflect.{_, given}
836+
quoted.Type.valueOfConstant[ShouldResetNestedFunctions] match {
837+
case None =>
838+
report.error("ShouldResetNestedFunctions is not defined", body)
839+
'{ ??? }
840+
case Some(translateNestedFunction) =>
841+
val result = Macros[qctx.type](resetDescendant =
842+
quoted.Type.valueOfConstant[ShouldResetNestedFunctions].get
843+
).reset[From, To](body /*.underlyingArgument*/ )
844+
// report.warning(result.asTerm.show(using qctx.reflect.Printer.TreeStructure))
845+
// report.warning(result.asTerm.show)
846+
result
847+
}
808848
}
809849
}
810-
inline def *[Domain[_]]: *[Domain] = new *[Domain]
811-
812-
inline def apply[Value](inline value: Value): Value = ${
813-
Macros.reset[Value, Value]('value)
814-
}
815850

816-
}
851+
}

reset/src/test/scala/com/thoughtworks/dsl/keywords/ReturnSpec.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ object ReturnSpec extends TestSuite {
4646
assert(result == 42)
4747
}
4848

49+
"reset nested function" - {
50+
new reset {
51+
type ShouldResetNestedFunctions = true
52+
}.apply {
53+
def continuation = { (!Return(42)): Int!!String }
54+
val result = continuation { s =>
55+
throw new java.lang.AssertionError(s)
56+
}
57+
assert(result == 42)
58+
}
59+
}
60+
4961
"return the right domain" - {
5062
def continuation: Int !! String = reset[Int !! String]{!Return("right value") }
5163

0 commit comments

Comments
 (0)