Skip to content

Commit

Permalink
rename () to recover (#262)
Browse files Browse the repository at this point in the history
Bumps minor for `()`->`recover` rename due to `()` triggering Nim compiler bugs for `foo[T](bar)` calls.
  • Loading branch information
disruptek authored Dec 30, 2021
1 parent fb9d448 commit 3ba79e7
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 29 deletions.
4 changes: 1 addition & 3 deletions cps.nim
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,6 @@ proc dealloc*[T: Continuation](c: sink T; E: typedesc[T]): E {.used, inline.} =
## its result may be assigned to another continuation reference.
nil

{.push experimental: "callOperator".}
template `()`(c: Continuation): untyped {.used.} =
template recover*(c: Continuation): untyped {.used.} =
## Returns the result, i.e. the return value, of a continuation.
discard
{.pop.}
2 changes: 1 addition & 1 deletion cps.nimble
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "0.4.5"
version = "0.5.0"
author = "disruptek"
description = "continuation-passing style"
license = "MIT"
Expand Down
25 changes: 13 additions & 12 deletions cps/environment.nim
Original file line number Diff line number Diff line change
Expand Up @@ -420,38 +420,39 @@ proc genException*(e: var Env): NimNode =
newLetIdentDef(ex, newRefType(bindName("Exception")), newNilLit())
result = newDotExpr(e.castToChild(e.first), ex)

proc createResult*(env: Env, exported = false): ProcDef =
proc createRecover*(env: Env, exported = false): ProcDef =
## define a procedure for retrieving the result of a continuation
##
## `exported` determines whether this procedure will be exported
let
field =
field = NimNode:
if env.rs.hasType:
env.get # the return value is env.result
else:
nnkDiscardStmt.newTree:
newEmptyNode() # the return value is void

# compose the (exported?) symbol
var name = nnkAccQuoted.newTree ident"()"
if exported:
name = NormNode postfix(name, "*")
let name = NimNode ident"recover"
var ename =
if exported:
postfix(name, "*")
else:
name

result = ProcDef:
genAst(name = name.NimNode, field = field.NimNode, c = env.first.NimNode,
cont = env.identity.NimNode, tipe = env.rs.typ.NimNode,
dismissed=Dismissed, finished=Finished, running=Running):
{.push experimental: "callOperator".}
proc name(c: cont): tipe {.used.} =
genAstOpt({}, name, ename, field, c = env.first.NimNode,
cont = env.identity.NimNode, tipe = env.rs.typ.NimNode,
dismissed=Dismissed, finished=Finished, running=Running):
proc ename(c: cont): tipe {.used.} =
case c.state
of dismissed:
raise Defect.newException:
"dismissed continuations have no result"
of finished:
field
of running:
`()`(trampoline c)
{.pop.}
name(trampoline c)

proc createWhelp*(env: Env; n: ProcDef, goto: NormNode): ProcDef =
## the whelp needs to create a continuation
Expand Down
8 changes: 4 additions & 4 deletions cps/transform.nim
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ proc shimAssign(env: var Env; store: NormNode, expr: NormNode, tail: NormNode):

# swap the call in the assignment statement(s)
let (child, etype) = setupChildContinuation(env, call)
assign = assign.resymCall(call, newCall child)
assign = assign.resymCall(call, newCall("recover".asName, child))

# compose the rewrite as an assignment, a lame effort to dealloc
# the child, and then any remaining statements we were passed
Expand Down Expand Up @@ -1198,17 +1198,17 @@ proc cpsTransformProc(T: NimNode, n: NimNode): NormNode =
for p in [whelp, booty]:
p.addPragma(bindName"cpsEnvironment", env.identity)

# the `()` operator recovers the result of a continuation
# the `recover` operator recovers the result of a continuation
#
# copy the exported-ness from the original proc so that it can be used
# from other modules
let dots = env.createResult(originalProcSym.isExported)
let recover = env.createRecover(exported = originalProcSym.isExported)

# "encouraging" a write of the current accumulating type
env = env.storeType(force = off)

# generated proc bodies, remaining proc, whelp, bootstrap
result = newStmtList(types, processMainContinuation, dots, whelp, booty)
result = newStmtList(types, processMainContinuation, recover, whelp, booty)

# this is something that happens a lot in cps-generated code, so hide it
# here to not spam the user with hints.
Expand Down
10 changes: 5 additions & 5 deletions tests/thooks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ suite "hooks":
stack 2: foo foo πŸ‘
boot 3: c nil πŸ‘
trace 4: foo continuation πŸ‘
coop 5: Cont nil genasts.nim
coop 5: Cont nil environment.nim
trace 6: While Loop continuation πŸ‘
trace 7: Post Call continuation πŸ‘
tail 8: Cont continuation πŸ‘
Expand All @@ -92,9 +92,9 @@ suite "hooks":
trace 14: Post Call continuation πŸ‘
pass 15: continuation.mom Cont(continuation) normalizedast.nim
coop 16: result nil normalizedast.nim
dealloc 17: cps environment 😎 genasts.nim
dealloc 17: cps environment 😎 environment.nim
trace 18: Post Child continuation normalizedast.nim
coop 19: Cont nil genasts.nim
coop 19: Cont nil environment.nim
trace 20: While Loop continuation πŸ‘
trace 21: Post Call continuation πŸ‘
tail 22: Cont continuation πŸ‘
Expand All @@ -106,9 +106,9 @@ suite "hooks":
trace 28: Post Call continuation πŸ‘
pass 29: continuation.mom Cont(continuation) normalizedast.nim
coop 30: result nil normalizedast.nim
dealloc 31: cps environment 😎 genasts.nim
dealloc 31: cps environment 😎 environment.nim
trace 32: Post Child continuation normalizedast.nim
coop 33: Cont nil genasts.nim
coop 33: Cont nil environment.nim
trace 34: While Loop continuation πŸ‘
trace 35: Post Call continuation πŸ‘
""".dedent(8).strip()
Expand Down
8 changes: 4 additions & 4 deletions tests/treturns.nim
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ suite "returns and results":

var c = whelp foo(5)
trampoline c
check "call operator works correctly":
c() == 25
check "recover operator works correctly":
recover(c) == 25

block:
## assignments to the special result symbol work
Expand Down Expand Up @@ -134,8 +134,8 @@ suite "returns and results":

var c = whelp foo()
trampoline c
check "call operator works correctly":
c() == 6
check "recover operator works correctly":
6 == recover c

block:
## discarding a continuation return value works
Expand Down

0 comments on commit 3ba79e7

Please sign in to comment.